From 763e673738a5089aa6ac78c0e6901f6248299d84 Mon Sep 17 00:00:00 2001 From: Yuri Karamian Date: Mon, 3 Aug 2026 01:12:50 +0200 Subject: [PATCH] Show vault location in Info panel --- src/lib/components/InfoPanel.svelte | 125 +++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/src/lib/components/InfoPanel.svelte b/src/lib/components/InfoPanel.svelte index ff6d26a..0703063 100644 --- a/src/lib/components/InfoPanel.svelte +++ b/src/lib/components/InfoPanel.svelte @@ -90,11 +90,16 @@ let orphans = $state(null); let scanning = $state(false); let trashing = $state(false); + let locationCopyState = $state<'idle' | 'copied' | 'error'>('idle'); + let locationCopyTimer: ReturnType | null = null; const orphanTotal = $derived((orphans ?? []).reduce((a, o) => a + o.size, 0)); getVersion().then(v => appVersion = v).catch(() => appVersion = '0.0.0'); function close() { + if (locationCopyTimer) clearTimeout(locationCopyTimer); + locationCopyTimer = null; + locationCopyState = 'idle'; $showInfo = false; activeTab = isMobile ? 'about' : 'shortcuts'; } @@ -103,6 +108,25 @@ openUrl(url).catch(console.error); } + async function copyVaultLocation() { + const location = $appConfig?.active_vault; + if (!location) return; + + if (locationCopyTimer) clearTimeout(locationCopyTimer); + try { + if (!navigator.clipboard?.writeText) throw new Error('Clipboard API unavailable'); + await navigator.clipboard.writeText(location); + locationCopyState = 'copied'; + } catch (e) { + console.error('Failed to copy vault location:', e); + locationCopyState = 'error'; + } + locationCopyTimer = setTimeout(() => { + locationCopyState = 'idle'; + locationCopyTimer = null; + }, 1600); + } + function formatSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; @@ -144,7 +168,7 @@
e.stopPropagation()}>

Info

- +
+ {$appConfig.active_vault} +
+ {/if} + {#if stats}
@@ -416,6 +468,71 @@ margin-top: 4px; } + .vault-location { + width: 100%; + margin-top: 18px; + padding: 11px 14px 12px; + border: 1px solid var(--border-light); + border-radius: 10px; + background: var(--bg-secondary); + text-align: left; + } + + .vault-location-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + } + + .vault-location-label { + color: var(--text-tertiary); + font-size: 11px; + font-weight: 600; + letter-spacing: 0.02em; + } + + .vault-location-path { + display: block; + margin-top: 7px; + color: var(--text-primary); + font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace; + font-size: 11px; + line-height: 1.45; + overflow-wrap: anywhere; + } + + .copy-location-btn { + display: inline-flex; + align-items: center; + gap: 5px; + margin: -4px -6px -4px 0; + padding: 4px 6px; + border: none; + border-radius: 6px; + background: transparent; + color: var(--accent); + font-size: 11px; + font-weight: 600; + cursor: pointer; + } + + .copy-location-btn:hover { + background: var(--accent-light); + } + + .copy-location-btn.copied { + color: var(--success); + } + + .copy-location-btn.error { + color: var(--danger); + } + + .vault-location + .info-stats { + margin-top: 12px; + } + .info-stats { width: 100%; margin-top: 20px; @@ -667,5 +784,11 @@ .info-header { padding-top: calc(env(safe-area-inset-top, 12px) + 12px); } + + .copy-location-btn { + min-height: 44px; + margin-block: -10px; + padding-inline: 10px; + } }