feat(i18n): display-language selector in Settings + t() on nav and transcription-language strings

This commit is contained in:
iamdoubz
2026-07-12 09:35:22 -05:00
parent a7af623753
commit 030b06329a
+43 -17
View File
@@ -6,6 +6,7 @@
import { settings } from "../stores/settings.svelte";
import { calendar } from "../stores/calendar.svelte";
import { meetings } from "../stores/meetings.svelte";
import { t, i18n, LOCALES } from "../i18n/index.svelte";
import ConsentNotice from "../components/ConsentNotice.svelte";
import HostedAiBanner from "../components/HostedAiBanner.svelte";
import { open } from "@tauri-apps/plugin-dialog";
@@ -49,7 +50,16 @@
let { onClose }: { onClose: () => void } = $props();
let section = $state<
"recording" | "hardware" | "storage" | "calendar" | "sync" | "ai" | "mcp" | "privacy" | "about"
| "recording"
| "hardware"
| "storage"
| "calendar"
| "sync"
| "ai"
| "mcp"
| "privacy"
| "language"
| "about"
>("recording");
// The currently active whisper model (T8.7, FR-TRX-4) — gates the
@@ -650,31 +660,34 @@
<strong>Settings</strong>
<nav>
<button class:active={section === "recording"} onclick={() => (section = "recording")}>
<Mic size={14} aria-hidden="true" /> Recording
<Mic size={14} aria-hidden="true" /> {t("nav.recording")}
</button>
<button class:active={section === "hardware"} onclick={() => (section = "hardware")}>
<Cpu size={14} aria-hidden="true" /> Hardware
<Cpu size={14} aria-hidden="true" /> {t("nav.hardware")}
</button>
<button class:active={section === "storage"} onclick={() => (section = "storage")}>
<HardDrive size={14} aria-hidden="true" /> Storage
<HardDrive size={14} aria-hidden="true" /> {t("nav.storage")}
</button>
<button class:active={section === "calendar"} onclick={() => (section = "calendar")}>
<CalendarDays size={14} aria-hidden="true" /> Calendar
<CalendarDays size={14} aria-hidden="true" /> {t("nav.calendar")}
</button>
<button class:active={section === "sync"} onclick={() => (section = "sync")}>
<UploadCloud size={14} aria-hidden="true" /> Sync
<UploadCloud size={14} aria-hidden="true" /> {t("nav.sync")}
</button>
<button class:active={section === "ai"} onclick={() => (section = "ai")}>
<Sparkles size={14} aria-hidden="true" /> AI
<Sparkles size={14} aria-hidden="true" /> {t("nav.ai")}
</button>
<button class:active={section === "mcp"} onclick={() => (section = "mcp")}>
<Bot size={14} aria-hidden="true" /> MCP server
<Bot size={14} aria-hidden="true" /> {t("nav.mcp")}
</button>
<button class:active={section === "privacy"} onclick={() => (section = "privacy")}>
<ShieldCheck size={14} aria-hidden="true" /> Privacy
<ShieldCheck size={14} aria-hidden="true" /> {t("nav.privacy")}
</button>
<button class:active={section === "language"} onclick={() => (section = "language")}>
<Globe size={14} aria-hidden="true" /> {t("nav.language")}
</button>
<button class:active={section === "about"} onclick={() => (section = "about")}>
<Info size={14} aria-hidden="true" /> About
<Info size={14} aria-hidden="true" /> {t("nav.about")}
</button>
</nav>
<button class="close" onclick={onClose} aria-label="Close" title="Close (Esc)">
@@ -1002,10 +1015,10 @@
{/each}
</ul>
<h4>Transcription Language</h4>
<h4>{t("settings.transcription.title")}</h4>
{#if activeModel?.multilingual}
<label
>Language
>{t("settings.transcription.label")}
<select
value={settings.settings.whisper_language ?? ""}
onchange={(e) => {
@@ -1013,16 +1026,13 @@
settings.setWhisperLanguage(v || null);
}}
>
<option value="">Auto-detect</option>
<option value="">{t("settings.transcription.auto")}</option>
{#each settings.languages as l (l.code)}
<option value={l.code}>{l.label}</option>
{/each}
</select>
</label>
<p class="muted">
Applies to the next recording. The language actually used is shown on each meeting
afterward.
</p>
<p class="muted">{t("settings.transcription.applies_hint")}</p>
{:else}
<label
>Language
@@ -1890,6 +1900,22 @@
{#if vaultMsg}<p class="muted">{vaultMsg}</p>{/if}
{/if}
</section>
{:else if section === "language"}
<section>
<h3>{t("settings.language.title")}</h3>
<label
>{t("settings.language.display")}
<select
value={i18n.locale}
onchange={(e) => i18n.setLocale((e.target as HTMLSelectElement).value)}
>
{#each LOCALES as l (l.code)}
<option value={l.code}>{l.label}</option>
{/each}
</select>
</label>
<p class="muted">{t("settings.language.display_hint")}</p>
</section>
{:else if section === "about"}
<section>
<h3>About</h3>