feat: File Lock beim Oeffnen + Entsperren per Rechtsklick

Beim Oeffnen einer .cloud-Datei:
- Download + Datei bleibt lokal (wie bisher)
- Lock wird auf dem Server gesetzt (andere sehen "gesperrt von X")
- Kein Auto-Unlock - Datei bleibt gesperrt bis manuell entsperrt

Rechtsklick im Datei-Browser auf Offline-Dateien:
- "Entsperren (Freigeben fuer andere)" - hebt den Lock auf
- "Nicht mehr offline" - .cloud zurueck + automatisch unlock

So bleiben Dateien gesperrt solange man daran arbeitet.
Wenn fertig: Rechtsklick -> Entsperren. Einfach und explizit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker
2026-04-12 03:03:01 +02:00
parent 0845659c84
commit 597dafc461
2 changed files with 46 additions and 2 deletions
+16 -2
View File
@@ -256,11 +256,17 @@ async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Resu
}
eprintln!("[OpenCloud] Downloaded {} bytes", std::fs::metadata(&real_path).map(|m| m.len()).unwrap_or(0));
// Remove .cloud placeholder - file stays as real file (like "offline markieren")
// Remove .cloud placeholder - file stays as real file
// Changes will be synced automatically by the file watcher
// User can manually "unmark offline" via right-click to get .cloud back
// User can "unmark offline" or "unlock" via right-click
std::fs::remove_file(&path).ok();
// Lock on server (prevents others from editing)
match api.lock_file(file_id, "Desktop Sync Client").await {
Ok(_) => eprintln!("[OpenCloud] Locked on server"),
Err(e) => eprintln!("[OpenCloud] Lock failed (file may be locked by someone else): {}", e),
}
// Open with default application for this file type
eprintln!("[OpenCloud] Opening with default app: {}", real_path.display());
open::that(&real_path)
@@ -269,6 +275,13 @@ async fn open_cloud_file(state: State<'_, AppState>, cloud_path: String) -> Resu
Ok(real_path.to_string_lossy().to_string())
}
#[tauri::command]
async fn unlock_file_cmd(state: State<'_, AppState>, file_id: i64) -> Result<String, String> {
let api = state.api.lock().unwrap().clone().ok_or("Nicht eingeloggt")?;
api.unlock_file(file_id).await?;
Ok("Datei entsperrt".to_string())
}
#[tauri::command]
async fn get_file_tree(state: State<'_, AppState>) -> Result<serde_json::Value, String> {
let api = state.api.lock().unwrap().clone().ok_or("Nicht eingeloggt")?;
@@ -726,6 +739,7 @@ pub fn run() {
open_cloud_file,
get_file_tree,
get_status,
unlock_file_cmd,
browse_sync_folder,
mark_offline,
unmark_offline,