Files
ttstd-infinite-canvas/web/src/pages/test-voice-recording.tsx

108 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from "react";
import { Button, Card, message } from "antd";
import { Mic, Send } from "lucide-react";
import { VoiceRecordingButton } from "@/components/conversation/voice-recording-button";
import { canvasThemes } from "@/lib/canvas-theme";
import { useThemeStore } from "@/stores/use-theme-store";
/**
* 语音录制功能测试页面
* 验证输入行内联波形录制和 STT 转写闭环
*/
export default function TestVoiceRecording() {
const theme = canvasThemes[useThemeStore((state) => state.theme)];
const [prompt, setPrompt] = useState("");
const [sending, setSending] = useState(false);
const handleTranscribed = (text: string) => {
// 转写结果填入输入框,供用户确认或直接发送
setPrompt((current) => (current.trim() ? `${current} ${text}` : text));
message.success("语音已转写为文字");
};
const handleSubmit = async () => {
if (!prompt.trim()) return;
setSending(true);
try {
// 原型阶段:发送到对话入口由调用方接入;此处仅输出
console.log("发送文本:", prompt);
message.success("发送成功(原型阶段,仅控制台输出)");
setPrompt("");
} finally {
setSending(false);
}
};
return (
<div className="min-h-screen p-8" style={{ background: theme.spatial.surface }}>
<div className="mx-auto max-w-2xl">
<Card
title={
<div className="flex items-center gap-2">
<Mic className="size-5" style={{ color: theme.accent.primary }} />
<span>实时对话功能测试(MVP)</span>
</div>
}
style={{ background: theme.spatial.elevated, borderColor: theme.toolbar.border }}
>
<div className="space-y-4">
{/* 文本输入 */}
<div>
<label className="mb-2 block text-sm font-medium" style={{ color: theme.node.text }}>
文本输入(语音转写结果会自动填入)
</label>
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="输入消息,或点击实时对话按钮用语音输入..."
className="w-full rounded-lg border px-3 py-2 text-sm outline-none transition focus:border-current"
style={{
background: theme.node.fill,
borderColor: theme.toolbar.border,
color: theme.node.text,
minHeight: 80,
}}
/>
</div>
{/* 音频预览 */}
{/* 控制栏:实时对话按钮(点击后在输入行展开波形录制条) */}
<div className="flex items-center justify-between gap-2">
<div className="flex flex-1 items-center gap-2">
<VoiceRecordingButton onTranscribed={handleTranscribed} />
</div>
<Button
type="primary"
icon={<Send className="size-4" />}
disabled={!prompt.trim()}
loading={sending}
onClick={handleSubmit}
style={{ background: theme.accent.primary, borderColor: theme.accent.primary, color: theme.accent.onPrimary }}
>
发送
</Button>
</div>
{/* 说明 */}
<div className="rounded-lg border p-3 text-xs" style={{ background: theme.toolbar.panel, borderColor: theme.toolbar.border, color: theme.node.muted }}>
<div className="font-semibold" style={{ color: theme.node.text }}>
使用说明:
</div>
<ul className="mt-1 list-inside list-disc space-y-1">
<li>点击麦克风按钮,输入行内展开波形录制条并自动开始录音</li>
<li>波形动画实时显示音量变化</li>
<li>点击停止按钮完成录制,自动上传并转写</li>
<li>转写结果自动填入输入框,可编辑后发送</li>
<li>转写失败时在录制条内提示,可点击麦克风重试</li>
</ul>
</div>
</div>
</Card>
</div>
</div>
);
}