feat: dictation round 1 — primary-input routing, no interims, optimistic meter, wide button
Owner's first live mic test (2026-09-17) drove four changes: - ONE primary transcription input at all times: while a quiz/ask question waits, finals land in its field (text mode → 'Your answer', select modes → 'Your thinking') via a module-level claim registry (useDictationTarget in dictation.tsx); the composer is the fallback. Esc in a question field also stops dictation (threaded through DockOverlay → QuestionDock). - No interim results: live words were distracting and shifted the meter. Params now match the pi dictate extension exactly (no interim_results, endpointing=300, no utterance_end_ms); the meter's width stays fixed. - Optimistic meter: the click enters the meter view immediately (Stop pill + meter within one frame, verified at 150ms in the dev shell); token mint and mic acquisition run concurrently behind it. - Wide idle button: the stats-bar middle is one full-width affordance — a quiet bordered 'Dictate' button when idle (failure text replaces the label), Stop pill + fixed meter while live. Live-verified in the Electron dev shell: wide button renders on home (167px) and chat (358px), meter + Stop appear at 150ms after click, flat 2px bars in silence, clean return to 'Dictate' on stop.
This commit is contained in:
@@ -872,6 +872,7 @@ export function Chat({
|
||||
turns={turns}
|
||||
onReserve={setDockReserve}
|
||||
dictationSlot={<DictationBar dictation={dictation} />}
|
||||
dictationStop={dictation.stop}
|
||||
composer={
|
||||
<Composer
|
||||
// Stop applies only to a LOCAL stream: a server-side turn has no
|
||||
@@ -950,6 +951,7 @@ function DockOverlay({
|
||||
plan,
|
||||
onOpenPlan,
|
||||
dictationSlot,
|
||||
dictationStop,
|
||||
}: {
|
||||
pending: ReturnType<typeof findPendingToolCall>;
|
||||
/** Teach-phase pending question: arrives collapsed behind the reveal button (W5). */
|
||||
@@ -975,6 +977,9 @@ function DockOverlay({
|
||||
/** The dictation strip (STT wave): rendered in the stats bar's middle
|
||||
* slot — the mic button + live meter (components/dictation.tsx). */
|
||||
dictationSlot?: React.ReactNode;
|
||||
/** Esc in a pending question's field stops dictation (the strip is the
|
||||
* stats bar's; the stop belongs to the page-owned hook, threaded down). */
|
||||
dictationStop?: () => void;
|
||||
}) {
|
||||
const { isAtBottom, scrollToBottom, scrollRef } = useStickToBottomContext();
|
||||
// Teach-phase mount (session reload with a pending check): the dock starts
|
||||
@@ -1225,6 +1230,7 @@ function DockOverlay({
|
||||
phase={phase}
|
||||
onExpand={expandAndReveal}
|
||||
onSubmit={onSubmitAnswer}
|
||||
onEscape={dictationStop}
|
||||
/>
|
||||
) : (
|
||||
composer
|
||||
|
||||
Reference in New Issue
Block a user