feat: 聊天框与视频功能解耦,输入文字即可开始对话

之前必须点击「开始对话」连接 WebSocket 后才能使用聊天框。
现在聊天输入框始终可用,输入文字自动连接 WebSocket 并发送消息;
左侧按钮改为「开始视频通话」,单独控制摄像头/麦克风。

- ChatPanel 移除 !isConnected early return,始终显示输入框
- useVisionSession 新增待发消息队列,sendTextMessage 支持自动连接
- startSession 改为仅负责视频(摄像头 + 麦克风 + VAD)
- 修复 statusRef 在 useWebSocketManager 之前声明导致的 TDZ 错误
- 更新 i18n 翻译(新增 controls.startVideo、video.placeholder)
This commit is contained in:
2026-06-14 15:07:39 +08:00
parent e95b1603c1
commit 15b1dd56fa
6 changed files with 73 additions and 31 deletions

View File

@@ -53,17 +53,6 @@ export function ChatPanel({ messages, currentReply, connectionStatus, onSendText
setInputText("");
};
// 未连接时的空状态
if (!isConnected) {
return (
<div className="chat-panel chat-panel--empty">
<span className="chat-panel--empty-icon">💬</span>
<p>{t("chat.empty.prompt")}</p>
<span className="chat-panel--empty-hint">{t("chat.empty.hint")}</span>
</div>
);
}
return (
<div className="chat-panel">
<div className="chat-panel__messages" ref={containerRef}>
@@ -71,8 +60,8 @@ export function ChatPanel({ messages, currentReply, connectionStatus, onSendText
{messages.length === 0 && !currentReply && (
<div className="chat-panel__welcome">
<span className="chat-panel__welcome-icon">💬</span>
<p>{t("chat.welcome.prompt")}</p>
<span className="chat-panel__welcome-hint">{t("chat.welcome.hint")}</span>
<p>{isConnected ? t("chat.welcome.prompt") : t("chat.empty.prompt")}</p>
<span className="chat-panel__welcome-hint">{isConnected ? t("chat.welcome.hint") : t("chat.empty.hint")}</span>
</div>
)}
@@ -106,7 +95,7 @@ export function ChatPanel({ messages, currentReply, connectionStatus, onSendText
<div ref={bottomRef} />
</div>
{/* 文本输入框 - 连接后始终显示 */}
{/* 文本输入框 - 始终显示 */}
{onSendText && (
<form className="chat-input" onSubmit={handleSubmit}>
<input
@@ -115,11 +104,12 @@ export function ChatPanel({ messages, currentReply, connectionStatus, onSendText
placeholder={t("chat.input.placeholder")}
value={inputText}
onChange={(e) => setInputText(e.target.value)}
disabled={connectionStatus === "connecting"}
/>
<button
type="submit"
className="chat-input__send"
disabled={!inputText.trim()}
disabled={!inputText.trim() || connectionStatus === "connecting"}
title={t("chat.send")}
>