feat(i18n): convert App shell chrome to t() (Batch A)
This commit is contained in:
1 parent
e5fdb2baea
commit
aac88bfbc5
1 file changed
+49
-48
+49
-48
@@ -18,6 +18,7 @@
|
||||
import ThemeToggle from "./lib/components/ThemeToggle.svelte";
|
||||
import Splitter from "./lib/components/Splitter.svelte";
|
||||
import { layout, clamp } from "./lib/stores/layout.svelte";
|
||||
import { t } from "./lib/i18n/index.svelte";
|
||||
import {
|
||||
Circle,
|
||||
Square,
|
||||
@@ -62,7 +63,7 @@
|
||||
vaultLocked = false;
|
||||
meetings.load(); // refresh now that encrypted content is readable
|
||||
} catch {
|
||||
vaultErr = "Incorrect password";
|
||||
vaultErr = t("app.vault_incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@
|
||||
checkVault();
|
||||
api
|
||||
.listNoteTemplates()
|
||||
.then((t) => (noteTemplates = t))
|
||||
.then((tpls) => (noteTemplates = tpls))
|
||||
.catch(() => (noteTemplates = []));
|
||||
|
||||
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
@@ -160,7 +161,7 @@
|
||||
}
|
||||
|
||||
async function cancelRecording() {
|
||||
if (!confirm("Discard this recording? Its audio and transcript will be deleted.")) return;
|
||||
if (!confirm(t("app.discard_confirm"))) return;
|
||||
await recording.cancel();
|
||||
meetings.deselect();
|
||||
}
|
||||
@@ -186,9 +187,9 @@
|
||||
$effect(() => {
|
||||
const current = recording.state;
|
||||
if (current !== previousRecordingState) {
|
||||
if (current === "recording") recordingAnnouncement = "Recording started";
|
||||
else if (current === "paused") recordingAnnouncement = "Recording paused";
|
||||
else if (previousRecordingState !== "idle") recordingAnnouncement = "Recording stopped";
|
||||
if (current === "recording") recordingAnnouncement = t("app.announce_started");
|
||||
else if (current === "paused") recordingAnnouncement = t("app.announce_paused");
|
||||
else if (previousRecordingState !== "idle") recordingAnnouncement = t("app.announce_stopped");
|
||||
previousRecordingState = current;
|
||||
}
|
||||
});
|
||||
@@ -232,58 +233,54 @@
|
||||
<div class="sr-only" role="status" aria-live="polite">{recordingAnnouncement}</div>
|
||||
<header class="bar">
|
||||
<strong>WhispAssist</strong>
|
||||
<span class="muted">local · private</span>
|
||||
<span class="muted">{t("app.tagline")}</span>
|
||||
<div class="spacer"></div>
|
||||
{#if recording.state === "idle"}
|
||||
<select
|
||||
class="theme-select"
|
||||
bind:value={selectedTemplateId}
|
||||
aria-label="Note template"
|
||||
title="Note template"
|
||||
aria-label={t("app.note_template")}
|
||||
title={t("app.note_template")}
|
||||
>
|
||||
<option value="">No template</option>
|
||||
{#each noteTemplates as t (t.id)}
|
||||
<option value={t.id}>{t.name}</option>
|
||||
<option value="">{t("app.no_template")}</option>
|
||||
{#each noteTemplates as tpl (tpl.id)}
|
||||
<option value={tpl.id}>{tpl.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<button
|
||||
class="import-btn"
|
||||
onclick={() => (showImport = true)}
|
||||
title="Add a meeting from a file or URL"
|
||||
title={t("app.add_meeting_title")}
|
||||
>
|
||||
<FilePlus size={13} aria-hidden="true" />
|
||||
Add meeting
|
||||
{t("app.add_meeting")}
|
||||
</button>
|
||||
<button
|
||||
class="record-btn"
|
||||
onclick={startRecording}
|
||||
title="Start recording (Ctrl+Shift+R)"
|
||||
title={t("app.record_title")}
|
||||
aria-keyshortcuts="Control+Shift+R"
|
||||
>
|
||||
<Circle size={11} fill="currentColor" aria-hidden="true" />
|
||||
Record
|
||||
{t("app.record")}
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
class="stop-btn"
|
||||
onclick={() => recording.stop()}
|
||||
title="Stop recording (Ctrl+Shift+R)"
|
||||
title={t("app.stop_title")}
|
||||
aria-keyshortcuts="Control+Shift+R"
|
||||
>
|
||||
<Square size={11} fill="currentColor" aria-hidden="true" />
|
||||
Stop
|
||||
{t("app.stop")}
|
||||
</button>
|
||||
<button
|
||||
class="cancel-btn"
|
||||
onclick={cancelRecording}
|
||||
title="Discard this recording and delete it"
|
||||
>
|
||||
<button class="cancel-btn" onclick={cancelRecording} title={t("app.cancel_title")}>
|
||||
<Trash2 size={12} aria-hidden="true" />
|
||||
Cancel
|
||||
{t("app.cancel")}
|
||||
</button>
|
||||
<span class="rec">
|
||||
<span class="rec-dot" aria-hidden="true"></span>
|
||||
Recording…
|
||||
{t("app.recording")}
|
||||
</span>
|
||||
<LevelMeter
|
||||
rms={recording.levelRms}
|
||||
@@ -293,16 +290,16 @@
|
||||
showMic={settings.settings.microphone_enabled}
|
||||
/>
|
||||
{#if settings.hardware}
|
||||
<span class="backend" title="Active transcription backend">{settings.hardware.active}</span>
|
||||
<span class="backend" title={t("app.backend_title")}>{settings.hardware.active}</span>
|
||||
{/if}
|
||||
<label class="retention" title="Save audio as .wav for this meeting">
|
||||
<label class="retention" title={t("app.retention_title")}>
|
||||
<input type="checkbox" checked={recording.retention} onchange={onToggleRetention} />
|
||||
<span>{recording.retention ? "saving" : "not saved"}</span>
|
||||
<span>{recording.retention ? t("app.saving") : t("app.not_saved")}</span>
|
||||
</label>
|
||||
{#if recording.deviceNotice}
|
||||
<span class="device-notice" role="status" title={recording.deviceNotice}>
|
||||
<AlertTriangle size={14} aria-hidden="true" />
|
||||
reconnecting audio device…
|
||||
{t("app.reconnecting")}
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -312,8 +309,8 @@
|
||||
/>
|
||||
<button
|
||||
class="icon"
|
||||
aria-label="Settings"
|
||||
title="Settings (Ctrl+,)"
|
||||
aria-label={t("app.settings")}
|
||||
title={t("app.settings_title")}
|
||||
aria-keyshortcuts="Control+,"
|
||||
onclick={() => (showSettings = !showSettings)}
|
||||
>
|
||||
@@ -326,7 +323,7 @@
|
||||
class="consent-overlay"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Recording consent"
|
||||
aria-label={t("app.consent_dialog")}
|
||||
tabindex="-1"
|
||||
use:trapFocus
|
||||
>
|
||||
@@ -347,23 +344,27 @@
|
||||
class="vault-overlay"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Unlock encryption vault"
|
||||
aria-label={t("app.vault_dialog")}
|
||||
tabindex="-1"
|
||||
use:trapFocus
|
||||
>
|
||||
<div class="vault-card">
|
||||
<h2>Unlock encryption vault</h2>
|
||||
<p class="muted">Your meetings are encrypted at rest. Enter your password to read them.</p>
|
||||
<h2>{t("app.vault_title")}</h2>
|
||||
<p class="muted">{t("app.vault_desc")}</p>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Vault password"
|
||||
placeholder={t("app.vault_password")}
|
||||
bind:value={vaultPw}
|
||||
onkeydown={(e) => e.key === "Enter" && submitUnlock()}
|
||||
/>
|
||||
{#if vaultErr}<p class="vault-err">{vaultErr}</p>{/if}
|
||||
<div class="vault-actions">
|
||||
<button class="primary" onclick={submitUnlock} disabled={!vaultPw}>Unlock</button>
|
||||
<button class="link" onclick={() => (vaultLocked = false)}>Continue locked</button>
|
||||
<button class="primary" onclick={submitUnlock} disabled={!vaultPw}
|
||||
>{t("app.unlock")}</button
|
||||
>
|
||||
<button class="link" onclick={() => (vaultLocked = false)}
|
||||
>{t("app.continue_locked")}</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -385,8 +386,8 @@
|
||||
layout.leftCollapsed = false;
|
||||
layout.persist();
|
||||
}}
|
||||
title="Show meetings list"
|
||||
aria-label="Show meetings list"
|
||||
title={t("app.show_meetings")}
|
||||
aria-label={t("app.show_meetings")}
|
||||
>
|
||||
<PanelLeftOpen size={16} aria-hidden="true" />
|
||||
</button>
|
||||
@@ -397,8 +398,8 @@
|
||||
layout.leftCollapsed = true;
|
||||
layout.persist();
|
||||
}}
|
||||
title="Hide meetings list"
|
||||
aria-label="Hide meetings list"
|
||||
title={t("app.hide_meetings")}
|
||||
aria-label={t("app.hide_meetings")}
|
||||
>
|
||||
<PanelLeftClose size={14} aria-hidden="true" />
|
||||
</button>
|
||||
@@ -407,7 +408,7 @@
|
||||
</aside>
|
||||
{#if !layout.leftCollapsed}
|
||||
<Splitter
|
||||
label="Resize meetings list"
|
||||
label={t("app.resize_meetings")}
|
||||
onResize={(d) => (layout.leftWidth = clamp(layout.leftWidth + d, 200, 480))}
|
||||
onResizeEnd={() => layout.persist()}
|
||||
/>
|
||||
@@ -417,7 +418,7 @@
|
||||
<section class="center"><TranscriptNotes /></section>
|
||||
{#if !layout.rightCollapsed}
|
||||
<Splitter
|
||||
label="Resize summary panel"
|
||||
label={t("app.resize_summary")}
|
||||
onResize={(d) => (layout.rightWidth = clamp(layout.rightWidth - d, 240, 560))}
|
||||
onResizeEnd={() => layout.persist()}
|
||||
/>
|
||||
@@ -432,8 +433,8 @@
|
||||
layout.rightCollapsed = false;
|
||||
layout.persist();
|
||||
}}
|
||||
title="Show summary panel"
|
||||
aria-label="Show summary panel"
|
||||
title={t("app.show_summary")}
|
||||
aria-label={t("app.show_summary")}
|
||||
>
|
||||
<PanelRightOpen size={16} aria-hidden="true" />
|
||||
</button>
|
||||
@@ -444,8 +445,8 @@
|
||||
layout.rightCollapsed = true;
|
||||
layout.persist();
|
||||
}}
|
||||
title="Hide summary panel"
|
||||
aria-label="Hide summary panel"
|
||||
title={t("app.hide_summary")}
|
||||
aria-label={t("app.hide_summary")}
|
||||
>
|
||||
<PanelRightClose size={14} aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user