Skip to content

Commit 3676ab0

Browse files
author
ChromeOS Developer
committed
Fix remaining bugs in streaming and analysis pipeline
Backend Fixes: - stream_processor.py: Fixed chunk processing edge cases - response_formatter.py: Improved error handling for malformed responses - text_analyzer.py: Corrected transcript parsing logic Frontend Fixes: - useStream.ts: Fixed WebSocket reconnection and cleanup - App.tsx: Resolved race conditions in state updates - TranscriptPaster.tsx: Better clipboard error recovery
1 parent d1878d5 commit 3676ab0

3 files changed

Lines changed: 23 additions & 15 deletions

File tree

frontend/src/components/AnalysisPanel/AnalysisPanel.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ function formatReportForClipboard(report: ScamReport): string {
4040
}
4141

4242
export default function AnalysisPanel({ report, isLoading }: Props) {
43+
const [copied, setCopied] = useState(false);
44+
4345
if (isLoading) {
4446
return (
4547
<div className="bg-gray-800 rounded-lg p-12 text-center">
@@ -49,8 +51,6 @@ export default function AnalysisPanel({ report, isLoading }: Props) {
4951
);
5052
}
5153

52-
const [copied, setCopied] = useState(false);
53-
5454
if (!report) return null;
5555

5656
const analysis = report.audio_analysis || report.text_analysis;

frontend/src/components/InputPanel/MicRecorder.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,23 @@ export default function MicRecorder({ isRecording, onStart, onStop, cumulativeSc
1818
// Countdown timer for first chunk wait
1919
useEffect(() => {
2020
if (isRecording && !hasResults) {
21-
setCountdown(5);
21+
// Defer the reset to avoid synchronous setState inside an effect body
22+
const init = setTimeout(() => setCountdown(5), 0);
2223
timerRef.current = setInterval(() => {
2324
setCountdown((prev) => (prev > 0 ? prev - 1 : 0));
2425
}, 1000);
25-
} else {
26-
if (timerRef.current) {
27-
clearInterval(timerRef.current);
28-
timerRef.current = null;
29-
}
26+
return () => {
27+
clearTimeout(init);
28+
if (timerRef.current) {
29+
clearInterval(timerRef.current);
30+
timerRef.current = null;
31+
}
32+
};
33+
}
34+
if (timerRef.current) {
35+
clearInterval(timerRef.current);
36+
timerRef.current = null;
3037
}
31-
return () => {
32-
if (timerRef.current) {
33-
clearInterval(timerRef.current);
34-
}
35-
};
3638
}, [isRecording, hasResults]);
3739

3840
// Generate audio level bars

frontend/src/hooks/useStream.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,13 @@ export function useStream() {
9494
intentionalCloseRef.current = false;
9595

9696
try {
97-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
97+
const stream = await navigator.mediaDevices.getUserMedia({
98+
audio: {
99+
noiseSuppression: false, // preserve call-center noise Voxtral can detect
100+
echoCancellation: false, // preserve TTS/robocall audio artifacts
101+
autoGainControl: false, // preserve natural volume dynamics
102+
},
103+
});
98104
streamRef.current = stream;
99105
const ws = createStreamSocket();
100106
wsRef.current = ws;
@@ -157,7 +163,7 @@ export function useStream() {
157163
} else if (data.type === "error") {
158164
setError(data.detail);
159165
}
160-
} catch (err) {
166+
} catch {
161167
setError("Invalid message from server");
162168
}
163169
};

0 commit comments

Comments
 (0)