fix(dictation): abort in-flight start on cleanup/unmount

cleanup() tore down resources but never set startAbortedRef, so a
composer unmounting while startRecording() awaited start_dictation /
listen / getUserMedia / addModule would resume the async start against a
torn-down instance — opening the mic/worklet and leaving the native
session and event listeners running after the component was gone. Set
the abort flag first in cleanup(); a fresh startRecording clears it
before its first await, so subsequent starts are unaffected.
This commit is contained in:
npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5
2026-07-11 16:19:22 +01:00
parent e8f288d322
commit 25339523ec
@@ -197,6 +197,15 @@ export function useLocalDictation({
}, []);
const cleanup = useCallback(() => {
// Abort any in-flight startRecording so it bails after its next await
// instead of resuming and opening the mic/worklet or leaving the native
// session/listeners running after teardown. `cleanup` is the unmount
// handler (and the catch-path teardown); without this, unmounting while
// startRecording awaits `start_dictation`/`listen`/`getUserMedia`/
// `addModule` would let the async start finish against a torn-down
// instance. A fresh startRecording clears this flag before its first
// await, so it never wrongly aborts a subsequent start.
startAbortedRef.current = true;
// Flush any remaining audio before teardown, then stop the native engine.
// Scope the stop to THIS hook instance's session. `cleanup` runs as every
// instance's unmount handler, so an unscoped stop here would let a