fix(settings): wrap nav tabs so the close button isn't cut off; add About page

The fixed-width settings panel overflowed horizontally because the tab nav
didn't wrap, pushing the X close button off the edge and adding a horizontal
scrollbar. nav now flex-wraps. Adds an About section: version, build commit,
and a link to the source repo (opened via open_url).
This commit is contained in:
iamdoubz committed 2026-07-06 07:46:19 -05:00
1 parent a51d7a777b
commit 31b3cfd5a7
1 file changed
+55 -3
+55 -3
View File
@@ -24,6 +24,7 @@
RefreshCw,
ChevronRight,
RotateCcw,
Info,
} from "@lucide/svelte";
import {
OLLAMA_OPTIONS,
@@ -36,9 +37,13 @@
let { onClose }: { onClose: () => void } = $props();
let section = $state<
"recording" | "hardware" | "storage" | "calendar" | "sync" | "ai" | "privacy"
"recording" | "hardware" | "storage" | "calendar" | "sync" | "ai" | "privacy" | "about"
>("recording");
// ---- About (version + build commit + source) ----
const SOURCE_URL = "https://git.dou.bet/iamdoubz/WhispAssist";
let appInfo = $state<{ version: string; commit: string } | null>(null);
// ---- AI summary provider (T5.2, FR-LLM-1) ----
let llmProvider = $state(settings.settings.llm_provider);
let llmEndpoint = $state(settings.settings.llm_endpoint);
@@ -291,6 +296,10 @@
onMount(() => {
settings.load();
calendar.load();
api
.appInfo()
.then((i) => (appInfo = i))
.catch(() => (appInfo = null));
const un = events.onNpuDownload((p) => {
if (p.stage === "model")
npuMsg = p.total ? `Model ${Math.round((100 * (p.received ?? 0)) / p.total)}%` : "Model…";
@@ -408,6 +417,9 @@
<button class:active={section === "privacy"} onclick={() => (section = "privacy")}>
<ShieldCheck size={14} aria-hidden="true" /> Privacy
</button>
<button class:active={section === "about"} onclick={() => (section = "about")}>
<Info size={14} aria-hidden="true" /> About
</button>
</nav>
<button class="close" onclick={onClose} aria-label="Close" title="Close (Esc)">
<X size={18} aria-hidden="true" />
@@ -1017,7 +1029,7 @@
</div>
{/if}
</section>
{:else}
{:else if section === "privacy"}
<section>
<h3>Privacy</h3>
<p class="muted">
@@ -1122,6 +1134,22 @@
{#if vaultMsg}<p class="muted">{vaultMsg}</p>{/if}
{/if}
</section>
{:else if section === "about"}
<section>
<h3>About</h3>
<p class="about-name">
WhispAssist <span class="about-ver">v{appInfo?.version ?? "…"}</span>
</p>
<p class="muted">A fully local, open-source, Windows-native meeting assistant.</p>
<div class="row">
Build commit<code>{appInfo?.commit ?? "…"}</code>
</div>
<p>
<button class="link source" onclick={() => api.openUrl(SOURCE_URL)}>
{SOURCE_URL} ↗
</button>
</p>
</section>
{/if}
</div>
</div>
@@ -1151,13 +1179,19 @@
top: 0;
background: var(--bg-elevated);
display: flex;
align-items: center;
align-items: flex-start;
gap: 1rem;
padding: 0.9rem 0;
border-bottom: 1px solid var(--border);
}
/* nav takes the middle and wraps its tabs onto a second row instead of
overflowing the fixed-width panel — that overflow was pushing the close
button off the panel edge and adding a horizontal scrollbar. */
nav {
display: flex;
flex: 1 1 auto;
min-width: 0;
flex-wrap: wrap;
gap: 0.25rem;
}
nav button,
@@ -1187,6 +1221,7 @@
.close {
display: grid;
place-items: center;
flex: 0 0 auto;
margin-left: auto;
width: 30px;
height: 30px;
@@ -1417,6 +1452,23 @@
.link.danger {
color: var(--danger);
}
.about-name {
font-size: 1.05rem;
font-weight: 600;
margin: 0.5rem 0 0.25rem;
}
.about-ver {
color: var(--muted);
font-weight: 500;
}
/* The source link reads as a link (accent + underline), unlike the muted
.link buttons used for secondary actions elsewhere. */
.link.source {
color: var(--accent);
text-decoration: underline;
padding: 0;
font: inherit;
}
.test {
display: inline-flex;
align-items: center;