fix(frontend): 修复 speechSynthesis.cancel() 未守卫导致的页面崩溃

This commit is contained in:
2026-05-21 19:06:40 +08:00
parent 380cc24913
commit 8b7d4ec19a
2 changed files with 249 additions and 14 deletions
+24 -14
View File
@@ -131,13 +131,13 @@ export function useSpeechSynthesis(): UseSpeechSynthesisReturn {
// Chrome bug 规避:定期 resume 避免长时间不调用后暂停
useEffect(() => {
if (isSpeaking && !isPaused) {
resumeIntervalRef.current = setInterval(() => {
if (window.speechSynthesis.speaking && window.speechSynthesis.paused) {
window.speechSynthesis.resume();
}
}, 5000);
}
if (!isSupported || !isSpeaking || isPaused) return;
resumeIntervalRef.current = setInterval(() => {
if (window.speechSynthesis.speaking && window.speechSynthesis.paused) {
window.speechSynthesis.resume();
}
}, 5000);
return () => {
if (resumeIntervalRef.current) {
@@ -145,7 +145,7 @@ export function useSpeechSynthesis(): UseSpeechSynthesisReturn {
resumeIntervalRef.current = null;
}
};
}, [isSpeaking, isPaused]);
}, [isSupported, isSpeaking, isPaused]);
/** 朗读下一段 */
const speakNextChunk = useCallback(() => {
@@ -221,29 +221,37 @@ export function useSpeechSynthesis(): UseSpeechSynthesisReturn {
/** 停止朗读 */
const stop = useCallback(() => {
window.speechSynthesis.cancel();
if (!isSupported) {
console.warn('[useSpeechSynthesis] stop: speechSynthesis not supported');
return;
}
if (utteranceRef.current) {
window.speechSynthesis.cancel();
}
setIsSpeaking(false);
setIsPaused(false);
utteranceRef.current = null;
chunksRef.current = [];
chunkIndexRef.current = 0;
}, []);
}, [isSupported]);
/** 暂停 */
const pause = useCallback(() => {
if (!isSupported) return;
if (isSpeaking && !isPaused) {
window.speechSynthesis.pause();
setIsPaused(true);
}
}, [isSpeaking, isPaused]);
}, [isSupported, isSpeaking, isPaused]);
/** 恢复 */
const resume = useCallback(() => {
if (!isSupported) return;
if (isPaused) {
window.speechSynthesis.resume();
setIsPaused(false);
}
}, [isPaused]);
}, [isSupported, isPaused]);
/** 设置语音 */
const setVoice = useCallback((voice: SpeechSynthesisVoice) => {
@@ -253,12 +261,14 @@ export function useSpeechSynthesis(): UseSpeechSynthesisReturn {
// 组件卸载时停止
useEffect(() => {
return () => {
window.speechSynthesis.cancel();
if (isSupported && utteranceRef.current) {
window.speechSynthesis.cancel();
}
if (resumeIntervalRef.current) {
clearInterval(resumeIntervalRef.current);
}
};
}, []);
}, [isSupported]);
return {
isSpeaking,