import React, { useState, useEffect, useRef } from "react"; import StopIcon from "../icons/pause.svg"; import SpeechRecognition, { useSpeechRecognition, } from "react-speech-recognition"; interface InterviewOverlayProps { onClose: () => void; onTextUpdate: (text: string) => void; submitMessage: (text: string) => void; } export const InterviewOverlay: React.FC = ({ onClose, onTextUpdate, submitMessage, }) => { const [visible, setVisible] = useState(true); const [countdown, setCountdown] = useState(20); const countdownRef = useRef(countdown); const intervalIdRef = useRef(null); // 添加暂停状态 const [isPaused, setIsPaused] = useState(false); // 使用 react-speech-recognition 的钩子 const { transcript, listening, resetTranscript, browserSupportsSpeechRecognition, isMicrophoneAvailable, } = useSpeechRecognition(); // 保存当前文本的引用,用于在倒计时结束时提交 const transcriptRef = useRef(transcript); useEffect(() => { transcriptRef.current = transcript; onTextUpdate(transcript); // 当有新的语音识别结果时,重置倒计时 if (transcript) { setCountdown(20); countdownRef.current = 20; } }, [transcript, onTextUpdate]); // 检查浏览器是否支持语音识别 useEffect(() => { if (!browserSupportsSpeechRecognition) { console.error("您的浏览器不支持语音识别功能"); } else if (!isMicrophoneAvailable) { console.error("无法访问麦克风"); } }, [browserSupportsSpeechRecognition, isMicrophoneAvailable]); // 开始语音识别 useEffect(() => { if (visible && !isPaused) { // 配置语音识别 SpeechRecognition.startListening({ continuous: true, language: "zh-CN", }); // 设置倒计时 intervalIdRef.current = setInterval(() => { setCountdown((prev) => { const newCount = prev - 1; countdownRef.current = newCount; if (newCount <= 0) { stopRecognition(); } return newCount; }); }, 1000); } return () => { if (intervalIdRef.current) { clearInterval(intervalIdRef.current); } SpeechRecognition.stopListening(); }; }, [visible, isPaused]); const stopRecognition = () => { try { SpeechRecognition.stopListening(); // 提交最终结果 if (transcriptRef.current) { submitMessage(transcriptRef.current); } // 清理倒计时 if (intervalIdRef.current) { clearInterval(intervalIdRef.current); } // 关闭overlay setVisible(false); onClose(); } catch (error) { console.error("停止语音识别失败:", error); } }; // 添加暂停/恢复功能 const togglePause = () => { if (!isPaused) { // 暂停 SpeechRecognition.stopListening(); if (intervalIdRef.current) { clearInterval(intervalIdRef.current); } // 提交当前文本 if (transcriptRef.current) { submitMessage(transcriptRef.current); resetTranscript(); } } else { // 恢复 console.log("recover "); // 先确保停止当前可能存在的监听 SpeechRecognition.abortListening(); // 短暂延迟后重新启动监听 setTimeout(() => { SpeechRecognition.startListening({ continuous: true, language: "zh-CN", }); // 重置文本 resetTranscript(); }, 100); // 重新设置倒计时 intervalIdRef.current = setInterval(() => { setCountdown((prev) => { const newCount = prev - 1; countdownRef.current = newCount; if (newCount <= 0) { stopRecognition(); } return newCount; }); }, 1000); } setIsPaused(!isPaused); }; if (!visible) { return null; } return (

剩余{" "} {countdown} {" "} 秒,超时将自动发送

{/* 语音识别状态指示器 */}
{listening ? "正在监听..." : isPaused ? "已暂停" : "未监听"}
{/* 错误提示 */} {(!browserSupportsSpeechRecognition || !isMicrophoneAvailable) && (
{!browserSupportsSpeechRecognition ? "您的浏览器不支持语音识别功能,请使用Chrome浏览器" : "无法访问麦克风,请检查麦克风权限"}
)} {/* 识别文本显示区域 */} {transcript && (
{transcript}
)} {/* 按钮区域 */}
{/* 暂停/恢复按钮 */}
{/* 添加脉冲动画 */}
); };