// ============================================================ // CamTalk — 主应用组件(Web 端双栏布局) // ============================================================ import { useState } from "react"; import { useVisionSession } from "./hooks/useVisionSession"; import { VideoPreview } from "./components/VideoPreview"; import { ChatPanel } from "./components/ChatPanel"; import { ConfigPanel } from "./components/ConfigPanel"; import { ToastContainer } from "./components/Toast"; import "./App.css"; function App() { const [showConfig, setShowConfig] = useState(false); const { messages, currentReply, isProcessing, isAudioPlaying, isSpeaking, isVADReady, vadError, connectionStatus, videoRef, stream, config, updateConfig, stats, mode, isObserving, toggleMode, startSession, stopSession, interrupt, } = useVisionSession(); const isConnected = connectionStatus === "connected"; return (
{/* ---- 顶部导航栏 ---- */}

CamTalk

AI 视觉对话助手
{isConnected && (stats.queryCount > 0 || stats.totalTokens > 0) && ( {stats.queryCount} 次请求 · {stats.totalTokens} tokens )} {isConnected ? "已连接" : connectionStatus === "connecting" ? "连接中..." : "未连接"} {isConnected && ( )}
{showConfig && ( setShowConfig(false)} /> )} {/* ---- 主体:左侧视频 + 右侧聊天 ---- */}
{/* 左侧:视频预览 + 控制栏 */}
{config.detailLevel === "high" && (
HD
)} {isObserving && (
👁️ 观察中
)} {isSpeaking && (
🎤 正在聆听...
)} {isAudioPlaying && config.ttsEnabled && (
🔊 正在播放...
)} {isConnected && !isVADReady && !vadError && (
正在初始化语音检测...
)} {vadError && (
⚠️ {vadError}
)} {isProcessing && (
)} {!isConnected && !stream && (
📷 点击右侧按钮开始对话
)}
{/* 视频下方控制栏 */}
{!isConnected ? ( ) : (
{isProcessing && ( )}
)}
{/* 右侧:聊天面板 */}
对话 {isConnected && mode === "observation" && ( 观察模式 )}
{connectionStatus === "disconnected" && messages.length > 0 && (
连接已断开,正在重连...
)}
); } export default App;