Implement voice visualization feature in AssistantPage with microphone control

Added a new VoiceVisualizer component to the AssistantPage, enabling real-time audio visualization during voice testing. Integrated microphone control with state management for recording status and error handling. Updated UI elements to reflect recording state and provide user feedback on microphone access issues, enhancing the overall user experience for voice interactions.
This commit is contained in:
Xin Wang
2026-06-08 07:51:45 +08:00
parent 82ca52d438
commit 9aea5d2f7d
2 changed files with 309 additions and 10 deletions

View File

@@ -24,6 +24,7 @@ import {
HelpCircle,
Waypoints,
AudioLines,
Square,
} from "lucide-react";
import { Button } from "@/components/ui/button";
@@ -49,6 +50,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { VoiceVisualizer } from "@/components/ui/voice-visualizer";
import {
Card,
CardContent,
@@ -962,26 +964,53 @@ function DebugTextPanel() {
}
function DebugVoicePanel() {
const [recording, setRecording] = useState(false);
const [micError, setMicError] = useState(false);
return (
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-6 p-6 text-center">
<button
type="button"
className="flex h-24 w-24 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-transform hover:scale-105"
aria-label="开始语音测试"
>
<Mic size={32} />
</button>
<VoiceVisualizer
active={recording}
size={200}
onError={() => {
setMicError(true);
setRecording(false);
}}
/>
<div>
<div className="text-sm font-medium text-foreground"></div>
<div className="text-sm font-medium text-foreground">
{recording ? "正在聆听…" : "点击开始语音测试"}
</div>
<p className="mt-1.5 text-sm leading-6 text-muted-foreground">
{micError
? "无法访问麦克风,请检查浏览器权限后重试。"
: "点击下方按钮开始录音,实时识别结果将显示在下方。"}
</p>
</div>
<Button
onClick={() => {
setMicError(false);
setRecording((value) => !value);
}}
variant={recording ? "outline" : "default"}
className={[
"gap-2",
recording
? "border-hairline-strong text-muted-foreground hover:text-foreground"
: "",
].join(" ")}
>
{recording ? <Square size={16} /> : <Mic size={16} />}
{recording ? "结束录音" : "开始语音测试"}
</Button>
<div className="w-full rounded-xl border border-hairline bg-canvas-soft p-4 text-left">
<div className="caption-label mb-2 text-muted-soft"></div>
<p className="text-sm leading-6 text-muted-soft"></p>
<p className="text-sm leading-6 text-muted-soft">
{recording ? "聆听中,请开始说话…" : "等待语音输入…"}
</p>
</div>
</div>
);