From 3b182acc5ef1b588c705db0b64016263f9dca3fd Mon Sep 17 00:00:00 2001 From: klopez4212 Date: Mon, 6 Jul 2026 21:20:18 +0100 Subject: [PATCH] fix(dictation): capture session ID by value in listener closures Each listener now compares event.payload.session against the local `sessionId` const (captured by the closure) instead of reading from the mutable `nativeSessionRef.current`. This prevents stale listeners from a previous session from matching the new session's ID after the ref is updated. Also unregisters any lingering listeners at the start of a new session before registering fresh ones, ensuring no duplicate handlers exist. --- .../dictation/hooks/useLocalDictation.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/desktop/src/features/dictation/hooks/useLocalDictation.ts b/desktop/src/features/dictation/hooks/useLocalDictation.ts index 324c8ece0..0c3d37bb1 100644 --- a/desktop/src/features/dictation/hooks/useLocalDictation.ts +++ b/desktop/src/features/dictation/hooks/useLocalDictation.ts @@ -208,15 +208,26 @@ export function useLocalDictation({ return; } + // Unregister any lingering listeners from a previous session so they + // can't match the new session ID via the shared ref. + if (unlistenTranscriptRef.current) { + unlistenTranscriptRef.current(); + unlistenTranscriptRef.current = null; + } + if (unlistenStateRef.current) { + unlistenStateRef.current(); + unlistenStateRef.current = null; + } + // 2. Listen for transcript events from the native layer. - // Each event includes a `session` ID so we can definitively ignore stale - // transcripts from a previous session's forwarder. + // Each listener captures `sessionId` by value (closure) so it only + // matches events from this specific session — immune to ref mutation. const unlistenTranscript = await listen<{ text: string; session: number; }>(DICTATION_TRANSCRIPT_EVENT, (event) => { const { text, session } = event.payload; - if (session !== nativeSessionRef.current) return; + if (session !== sessionId) return; if (text) { onTranscriptTextRef.current(text); } @@ -234,7 +245,7 @@ export function useLocalDictation({ session: number; }>(DICTATION_STATE_EVENT, (event) => { const { state, session } = event.payload; - if (session !== nativeSessionRef.current) return; + if (session !== sessionId) return; if (state === "stopped") { setIsRecording(false); setIsTranscribing(false);