feat(ui): show meeting language badge + reprocess language picker (T8.7, M4.2)

This commit is contained in:
iamdoubz
2026-07-07 13:12:51 -05:00
parent 7bff39271c
commit 353d582e96
+41 -2
View File
@@ -29,6 +29,14 @@
return speakers.find((s) => s.label === label)?.display_name ?? label;
}
// T8.7/FR-TRX-4: the meeting view shows the language actually used, not
// just the raw ISO code — falls back to the code itself if it's not in
// the (curated) catalog, and to "auto-detecting…" before any is known.
function languageLabel(code: string | null): string {
if (!code) return "auto-detecting…";
return settings.languages.find((l) => l.code === code)?.label ?? code;
}
let notesText = $state("");
// Notes is a single pane: raw markdown ("Editor") or the rendered result
// ("Preview"), toggled by one button whose label flips to the other mode.
@@ -130,13 +138,16 @@
}
let reprocessModel = $state("");
// T8.7/FR-TRX-4: "" reuses the meeting's current language (backend default
// when `language` is omitted) rather than resetting it to auto.
let reprocessLanguage = $state("");
let reprocessing = $state(false);
async function reprocess() {
const m = meetings.selected;
if (!m || !reprocessModel) return;
reprocessing = true;
try {
await meetings.reprocess(m.id, reprocessModel);
await meetings.reprocess(m.id, reprocessModel, reprocessLanguage || undefined);
} finally {
reprocessing = false;
}
@@ -154,8 +165,13 @@
/>
<div class="split">
<div class="pane transcript">
<h4><MessageSquareText size={14} aria-hidden="true" /> Transcript</h4>
<h4>
<MessageSquareText size={14} aria-hidden="true" /> Transcript
<span class="badge lang" title="Transcription language">{languageLabel(m.language)}</span
>
</h4>
{#if m.recorded && settings.models.some((mo) => mo.installed)}
{@const reprocessModelInfo = settings.models.find((mo) => mo.id === reprocessModel)}
<div class="reprocess">
<select bind:value={reprocessModel}>
<option value="">Re-transcribe with…</option>
@@ -163,6 +179,15 @@
<option value={mo.id}>{mo.label}</option>
{/each}
</select>
{#if reprocessModelInfo?.multilingual}
<select bind:value={reprocessLanguage} aria-label="Reprocess language">
<option value="">Keep current language</option>
<option value="auto">Auto-detect</option>
{#each settings.languages as l (l.code)}
<option value={l.code}>{l.label}</option>
{/each}
</select>
{/if}
<button disabled={!reprocessModel || reprocessing} onclick={reprocess}>
<RefreshCw size={13} aria-hidden="true" class={reprocessing ? "spin" : ""} />
{reprocessing ? "Re-transcribing…" : "Go"}
@@ -328,6 +353,20 @@
letter-spacing: 0.04em;
color: var(--muted);
}
/* Transcription language (T8.7, FR-TRX-4) — a quiet pill, not a status
color, since "which language" isn't a good/bad state to flag. */
.badge.lang {
margin-left: auto;
font-size: 0.7rem;
font-weight: 500;
text-transform: none;
letter-spacing: normal;
color: var(--muted);
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 0.1rem 0.45rem;
}
.reprocess {
display: flex;
gap: 0.4rem;