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"}