From e925aa5438c775762af7da3e99a9ed35423ca74c Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sat, 2 May 2026 19:13:31 +0700 Subject: [PATCH] fix(app): keep dictation running when agent tab loses focus Previously, dictation was cancelled the moment the user switched away from the active agent tab, losing any in-progress recording. Drop the auto-stop-on-blur behavior so users can start dictating, switch tabs, and come back to finalize. --- packages/app/src/components/message-input.tsx | 1 - .../app/src/hooks/use-dictation.shared.ts | 1 - packages/app/src/hooks/use-dictation.ts | 41 ------------------- 3 files changed, 43 deletions(-) diff --git a/packages/app/src/components/message-input.tsx b/packages/app/src/components/message-input.tsx index 154bae910..fd775d04b 100644 --- a/packages/app/src/components/message-input.tsx +++ b/packages/app/src/components/message-input.tsx @@ -1328,7 +1328,6 @@ export const MessageInput = forwardRef( onError: handleDictationError, canStart: canStartDictation, canConfirm: canConfirmDictation, - autoStopWhenHidden: { isVisible: isPaneFocused }, enableDuration: true, }); diff --git a/packages/app/src/hooks/use-dictation.shared.ts b/packages/app/src/hooks/use-dictation.shared.ts index 14d3eaa32..af2a99582 100644 --- a/packages/app/src/hooks/use-dictation.shared.ts +++ b/packages/app/src/hooks/use-dictation.shared.ts @@ -8,7 +8,6 @@ export interface UseDictationOptions { onPermanentFailure?: (error: Error, context: { requestId: string }) => void; canStart?: () => boolean; canConfirm?: () => boolean; - autoStopWhenHidden?: { isVisible: boolean }; enableDuration?: boolean; } diff --git a/packages/app/src/hooks/use-dictation.ts b/packages/app/src/hooks/use-dictation.ts index b36f769c1..a7329610a 100644 --- a/packages/app/src/hooks/use-dictation.ts +++ b/packages/app/src/hooks/use-dictation.ts @@ -22,7 +22,6 @@ export function useDictation(options: UseDictationOptions): UseDictationResult { onPermanentFailure, canStart, canConfirm, - autoStopWhenHidden, enableDuration = false, } = options; @@ -425,46 +424,6 @@ export function useDictation(options: UseDictationOptions): UseDictationResult { clearStreamingState(); }, [clearStreamingState, stopDurationTracking]); - const cancelRef = useRef<(() => void) | null>(null); - useEffect(() => { - cancelRef.current = () => { - void cancelDictation(); - }; - }, [cancelDictation]); - - const visibilityRef = useRef( - typeof autoStopWhenHidden?.isVisible === "boolean" ? autoStopWhenHidden.isVisible : null, - ); - useEffect(() => { - const nextVisible = - typeof autoStopWhenHidden?.isVisible === "boolean" ? autoStopWhenHidden.isVisible : null; - const prevVisible = visibilityRef.current; - visibilityRef.current = nextVisible; - - if (prevVisible === true && nextVisible === false) { - attemptGuardRef.current.cancel(); - - if (isRecordingRef.current) { - cancelRef.current?.(); - return; - } - - if (isProcessingRef.current) { - stopDurationTracking(); - setDuration(0); - setIsProcessing(false); - isProcessingRef.current = false; - setError(null); - if (senderRef.current?.hasSegments()) { - setStatus("failed"); - } else { - setStatus("idle"); - clearStreamingState(); - } - } - } - }, [autoStopWhenHidden?.isVisible, clearStreamingState, stopDurationTracking]); - useEffect(() => { const attemptGuard = attemptGuardRef.current; const audioStop = audioStopRef;