From 86545ca4055776bb2ab4d383dd2f3452857cbed3 Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Sun, 12 Apr 2026 01:50:09 +0200 Subject: [PATCH] feat: Minimiert starten + kein Fenster-Popup bei .cloud Oeffnung - .cloud Doppelklick oeffnet Datei im Hintergrund ohne das Client- Fenster aufzupoppen (war nervig) - Neue Einstellung "Minimiert starten (direkt im System-Tray)" als Checkbox im Einstellungen-Bereich - Wird in config.json gespeichert, bleibt bei Updates erhalten - Bei aktiviertem Haken: Client startet unsichtbar im Tray, Sync laeuft im Hintergrund, Fenster nur per Tray-Doppelklick Co-Authored-By: Claude Opus 4.6 (1M context) --- clients/desktop/src-tauri/src/lib.rs | 29 ++++++++++++++++---- clients/desktop/src-tauri/src/sync/config.rs | 2 ++ clients/desktop/src/App.vue | 17 ++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/clients/desktop/src-tauri/src/lib.rs b/clients/desktop/src-tauri/src/lib.rs index 9c89628..0e04108 100644 --- a/clients/desktop/src-tauri/src/lib.rs +++ b/clients/desktop/src-tauri/src/lib.rs @@ -104,6 +104,19 @@ async fn auto_login(state: State<'_, AppState>) -> Result Result { + let mut config = AppConfig::load(); + config.start_minimized = minimized; + config.save()?; + Ok(format!("Minimiert starten: {}", minimized)) +} + +#[tauri::command] +fn get_start_minimized() -> bool { + AppConfig::load().start_minimized +} + // --- Sync Paths --- #[tauri::command] @@ -741,11 +754,7 @@ pub fn run() { let path = path.trim().to_string(); if !path.is_empty() { let _ = app_req.emit("open-cloud-file", path); - // Show the window - if let Some(w) = app_req.get_webview_window("main") { - let _ = w.show(); - let _ = w.set_focus(); - } + // Don't show window - user opens it via tray when needed } } std::fs::remove_file(&request_file).ok(); @@ -753,6 +762,14 @@ pub fn run() { } }); + // Start minimized if configured + let config = AppConfig::load(); + if config.start_minimized { + if let Some(w) = app.get_webview_window("main") { + let _ = w.hide(); + } + } + // Handle .cloud file opened via file association (double-click) let args: Vec = std::env::args().collect(); if args.len() > 1 { @@ -803,6 +820,8 @@ pub fn run() { load_saved_config, auto_login, login, + set_start_minimized, + get_start_minimized, add_sync_path, remove_sync_path, get_sync_paths, diff --git a/clients/desktop/src-tauri/src/sync/config.rs b/clients/desktop/src-tauri/src/sync/config.rs index 95e38ec..200dead 100644 --- a/clients/desktop/src-tauri/src/sync/config.rs +++ b/clients/desktop/src-tauri/src/sync/config.rs @@ -11,6 +11,8 @@ pub struct AppConfig { pub sync_paths: Vec, #[serde(default)] pub auto_start: bool, + #[serde(default)] + pub start_minimized: bool, } impl AppConfig { diff --git a/clients/desktop/src/App.vue b/clients/desktop/src/App.vue index 1027edb..c560fe5 100644 --- a/clients/desktop/src/App.vue +++ b/clients/desktop/src/App.vue @@ -19,6 +19,11 @@ const userInfo = ref(null); const fileTree = ref([]); const fileChanges = ref([]); const autoSyncActive = ref(false); +const startMinimized = ref(false); + +async function saveStartMinimized() { + await invoke("set_start_minimized", { minimized: startMinimized.value }); +} // New sync path form const showAddPath = ref(false); @@ -114,6 +119,7 @@ async function handleLogin() { userInfo.value = result; screen.value = "main"; syncStatus.value = `Verbunden als ${result.username}`; + startMinimized.value = await invoke("get_start_minimized"); await loadFileTree(); await loadSyncPaths(); } catch (err) { @@ -236,6 +242,7 @@ onMounted(async () => { screen.value = "main"; syncStatus.value = `Verbunden als ${result.username}`; syncPaths.value = (await invoke("get_sync_paths")); + startMinimized.value = await invoke("get_start_minimized"); await loadFileTree(); // Auto-start sync if paths configured if (syncPaths.value.length > 0) { @@ -461,6 +468,15 @@ onUnmounted(() => { unlistenStatus?.(); unlistenLog?.(); unlistenError?.(); unli

Sync-Protokoll

{{ m }}
+ + +
+

Einstellungen

+ +
@@ -531,6 +547,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;f .lf-badge.cloud{background:#e3f2fd;color:#1565c0} .lf-badge.offline{background:#e8f5e9;color:#2e7d32} .lf-size{font-size:.75rem;color:#999;flex-shrink:0} +.checkbox-row{display:flex;align-items:center;gap:.5rem;font-size:.85rem;cursor:pointer} .context-menu{position:fixed;background:#fff;border:1px solid #ddd;border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);z-index:9999;min-width:200px;padding:.25rem 0} .cm-item{padding:.5rem .75rem;cursor:pointer;font-size:.85rem} .cm-item:hover{background:#f0f0f0}