diff --git a/clients/desktop/src-tauri/src/sync/engine.rs b/clients/desktop/src-tauri/src/sync/engine.rs index aa089cb..716261a 100644 --- a/clients/desktop/src-tauri/src/sync/engine.rs +++ b/clients/desktop/src-tauri/src/sync/engine.rs @@ -98,17 +98,35 @@ impl SyncEngine { } else { // Check if real file exists (manually downloaded or offline-marked) if local_path.exists() { - // Real file exists - check if it's been modified let local_hash = compute_file_hash(&local_path); - if local_hash != entry.checksum.as_deref().unwrap_or("") { - // Local file changed - upload it - if !entry.locked.unwrap_or(false) { - match self.api.upload_file(&local_path, entry.id.into()).await { - Ok(_) => log.push(format!("Hochgeladen: {}", entry.name)), - Err(e) => log.push(format!("Upload-Fehler {}: {}", entry.name, e)), + let server_hash = entry.checksum.as_deref().unwrap_or(""); + if local_hash != server_hash { + if entry.locked.unwrap_or(false) { + log.push(format!("Zurueckgehalten (gesperrt): {}", entry.name)); + continue; + } + // Who is newer? + let local_modified = std::fs::metadata(&local_path) + .and_then(|m| m.modified()).ok(); + let server_modified = entry.updated_at.as_deref() + .and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok()) + .map(|dt| std::time::SystemTime::from(dt)); + + let server_is_newer = match (local_modified, server_modified) { + (Some(lt), Some(st)) => st > lt, + _ => false, + }; + + if server_is_newer { + match self.api.download_file(entry.id, &local_path).await { + Ok(_) => log.push(format!("Server->Lokal: {}", entry.name)), + Err(e) => log.push(format!("Download-Fehler {}: {}", entry.name, e)), } } else { - log.push(format!("Zurueckgehalten (gesperrt): {}", entry.name)); + match self.api.upload_file(&local_path, None).await { + Ok(_) => log.push(format!("Lokal->Server: {}", entry.name)), + Err(e) => log.push(format!("Upload-Fehler {}: {}", entry.name, e)), + } } } continue; @@ -198,16 +216,41 @@ impl SyncEngine { } else { // Existing file: check if changed (checksum compare) if let Some(se) = server_entries.iter().find(|e| e.name == name) { - if !se.locked.unwrap_or(false) { - let local_hash = compute_file_hash(&path); - if local_hash != se.checksum.as_deref().unwrap_or("") { + if se.locked.unwrap_or(false) { + log.push(format!("Zurueckgehalten (gesperrt): {}", name)); + continue; + } + + let local_hash = compute_file_hash(&path); + let server_hash = se.checksum.as_deref().unwrap_or(""); + + if local_hash != server_hash { + // Hashes differ - who is newer? + let local_modified = std::fs::metadata(&path) + .and_then(|m| m.modified()) + .ok(); + let server_modified = se.updated_at.as_deref() + .and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok()) + .map(|dt| std::time::SystemTime::from(dt)); + + let server_is_newer = match (local_modified, server_modified) { + (Some(local_t), Some(server_t)) => server_t > local_t, + _ => false, // if we can't compare, don't overwrite server + }; + + if server_is_newer { + // Server is newer -> download + match self.api.download_file(se.id, &path).await { + Ok(_) => log.push(format!("Server->Lokal: {}", name)), + Err(e) => log.push(format!("Download-Fehler {}: {}", name, e)), + } + } else { + // Local is newer -> upload match self.api.upload_file(&path, parent_id).await { - Ok(_) => log.push(format!("Aktualisiert: {}", name)), + Ok(_) => log.push(format!("Lokal->Server: {}", name)), Err(e) => log.push(format!("Upload-Fehler {}: {}", name, e)), } } - } else { - log.push(format!("Zurueckgehalten (gesperrt): {}", name)); } } } @@ -289,17 +332,40 @@ impl SyncEngine { } } } else { - let needs_upload = if let Some(se) = server_names.get(&name) { + if let Some(se) = server_names.get(&name) { if se.locked.unwrap_or(false) { log.push(format!("Zurueckgehalten (gesperrt): {}", name)); continue; } - compute_file_hash(&path) != se.checksum.as_deref().unwrap_or("") - } else { - true - }; + let local_hash = compute_file_hash(&path); + let server_hash = se.checksum.as_deref().unwrap_or(""); + if local_hash != server_hash { + // Who is newer? + let local_modified = std::fs::metadata(&path) + .and_then(|m| m.modified()).ok(); + let server_modified = se.updated_at.as_deref() + .and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok()) + .map(|dt| std::time::SystemTime::from(dt)); - if needs_upload { + let server_is_newer = match (local_modified, server_modified) { + (Some(lt), Some(st)) => st > lt, + _ => false, + }; + + if server_is_newer { + match self.api.download_file(se.id, &path).await { + Ok(_) => log.push(format!("Server->Lokal: {}", name)), + Err(e) => log.push(format!("Download-Fehler {}: {}", name, e)), + } + } else { + match self.api.upload_file(&path, parent_id).await { + Ok(_) => log.push(format!("Lokal->Server: {}", name)), + Err(e) => log.push(format!("Upload-Fehler {}: {}", name, e)), + } + } + } + } else { + // New file, not on server match self.api.upload_file(&path, parent_id).await { Ok(_) => log.push(format!("Hochgeladen: {}", name)), Err(e) => log.push(format!("Upload-Fehler {}: {}", name, e)),