fix(recorder): Resolve infinite loop stale closure & reset status text on discard
This commit is contained in:
@@ -187,9 +187,10 @@ const Recorder: React.FC<RecorderProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
// Refs for interval access to avoid dependency cycles
|
||||
// Refs for interval access to avoid dependency cycles and stale closures
|
||||
const lastSpeechTimeRef = useRef<number>(Date.now());
|
||||
const isStoppingRef = useRef(false);
|
||||
const autoStartEnabledRef = useRef(autoStartEnabled);
|
||||
|
||||
// Update refs when state changes
|
||||
useEffect(() => {
|
||||
@@ -200,6 +201,10 @@ const Recorder: React.FC<RecorderProps> = ({
|
||||
isStoppingRef.current = isStopping;
|
||||
}, [isStopping]);
|
||||
|
||||
useEffect(() => {
|
||||
autoStartEnabledRef.current = autoStartEnabled;
|
||||
}, [autoStartEnabled]);
|
||||
|
||||
// 1. Event Listeners Effect (Run ONCE when recording starts)
|
||||
useEffect(() => {
|
||||
let unlistenVAD: () => void;
|
||||
@@ -348,17 +353,14 @@ const Recorder: React.FC<RecorderProps> = ({
|
||||
|
||||
// NEW: Check if speech was actually detected during the session
|
||||
// If we recorded 20s of silence (Auto-Stop), we shouldn't transcribe.
|
||||
// If we recorded 20s of silence (Auto-Stop), we shouldn't transcribe.
|
||||
if (!hasSpeechDetected && recordingMode === 'voice') {
|
||||
// Note: For 'meeting' mode, system audio might have happened without VAD triggering?
|
||||
// But our updated backend VAD logic includes System Audio in 'is_speech' event.
|
||||
// So we can trust hasSpeechDetected for both modes now.
|
||||
|
||||
// IMPORTANT: Check applies to BOTH 'voice' and 'meeting' modes to prevent "Batch Null" errors on false triggers.
|
||||
if (!hasSpeechDetected) {
|
||||
console.log("No speech detected during recording. Skipping transcription.");
|
||||
addToast("Recording discarded (No speech/audio detected)", 'info');
|
||||
setStatus('Ready to record'); // Reset status text
|
||||
|
||||
// If auto-start is on, we just loop back.
|
||||
// skip the rest.
|
||||
// If auto-start is on, we just loop back (in finally block).
|
||||
// But we skip the expensive/failing API call.
|
||||
} else {
|
||||
|
||||
// Wait a moment for file flush (safety)
|
||||
@@ -489,11 +491,15 @@ const Recorder: React.FC<RecorderProps> = ({
|
||||
setIsStopping(false);
|
||||
|
||||
// AUTO-RESTART LOGIC
|
||||
if (autoStartEnabled) {
|
||||
// Use REF to get the latest state (fix for "starts again even if I uncheck")
|
||||
if (autoStartEnabledRef.current) {
|
||||
console.log("Auto-Start enabled: Restarting listener loop...");
|
||||
// Short delay to ensure backend cleanup
|
||||
setTimeout(() => {
|
||||
startRecording();
|
||||
// Double check ref before restarting
|
||||
if (autoStartEnabledRef.current) {
|
||||
startRecording();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user