From d01bd9d28042396e3e6da1d6919d63dd41cee352 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 17 Apr 2026 16:22:31 +0000 Subject: [PATCH] fix(settings): stop clobbering WebDAV edits and save without a successful test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two coupled issues in workspace settings: 1. The credentials-loading effect re-ran whenever ws.webdav_url changed, so any config mutation (e.g. changing sync interval) would trigger a re-load of the stored username/password, overwriting whatever the user was typing into those fields. Gate with a one-shot credsLoaded flag. 2. Save would persist whatever was in the URL input even if the user had never tested it — a typo'd host silently pointed the workspace at a dead server. Now saveWebdav auto-runs the connection test and bails if it fails; any edit to the three inputs clears the "ok" status via markDirty() so the next Save is forced to re-verify. Also replaces the ASCII "Failed -- Retry" with an em dash. --- .../src/lib/screens/SettingsScreen.svelte | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/tauri/src/lib/screens/SettingsScreen.svelte b/apps/tauri/src/lib/screens/SettingsScreen.svelte index d63e617..9e9e581 100644 --- a/apps/tauri/src/lib/screens/SettingsScreen.svelte +++ b/apps/tauri/src/lib/screens/SettingsScreen.svelte @@ -15,14 +15,19 @@ let webdavUser = $state(""); let webdavPass = $state(""); let testStatus = $state<"idle" | "testing" | "ok" | "fail">("idle"); + let credsLoaded = $state(false); let renaming = $state(false); let renameValue = $state(""); let showKebab = $state(false); let confirmRename = $state(false); + // Load stored credentials exactly once for this workspace. Previously this + // ran on every `ws.webdav_url` change, which silently clobbered in-progress + // user edits whenever any other setting updated the config. $effect(() => { - if (!ws?.webdav_url) return; + if (credsLoaded || !ws?.webdav_url) return; + credsLoaded = true; webdavUrl = ws.webdav_url; try { const domain = new URL(ws.webdav_url).hostname; @@ -35,6 +40,12 @@ } catch {} }); + // Any edit invalidates a prior test so users can't Save a config they + // haven't validated since changing it. + function markDirty() { + if (testStatus !== "idle") testStatus = "idle"; + } + async function testConnection() { testStatus = "testing"; try { @@ -51,6 +62,12 @@ async function saveWebdav() { if (!webdavUrl.trim()) return; + // Require a successful test so a typo'd URL can't silently point the + // workspace at a dead server. + if (testStatus !== "ok") { + await testConnection(); + if (testStatus !== "ok") return; + } await invoke("set_webdav_config", { workspaceId, webdavUrl: webdavUrl.trim(), @@ -172,6 +189,7 @@ @@ -180,6 +198,7 @@ @@ -187,6 +206,7 @@ @@ -196,7 +216,7 @@ disabled={!webdavUrl.trim()} class="rounded-lg border border-border-light px-4 py-2 text-sm font-medium hover:bg-black/5 disabled:opacity-40 dark:border-border-dark dark:hover:bg-white/10" > - {testStatus === "testing" ? "Testing..." : testStatus === "ok" ? "Connected" : testStatus === "fail" ? "Failed -- Retry" : "Test Connection"} + {testStatus === "testing" ? "Testing…" : testStatus === "ok" ? "Connected" : testStatus === "fail" ? "Failed — Retry" : "Test Connection"}