feat(ui): show meeting language badge + reprocess language picker (T8.7, M4.2)
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user