+ {/* 头部:新建 + 收起 */}
+
+
+
+
-
- {sessions.length === 0 ? (
-
{t("sidebar.empty")}
- ) : (
- sessions.map((session) => (
-
onSelectSession(session.id)}
- >
- {editingId === session.id ? (
-
e.stopPropagation()}>
- setEditTitle(e.target.value)}
- onKeyDown={(e) => {
- if (e.key === "Enter") handleConfirmRename();
- if (e.key === "Escape") handleCancelRename();
- }}
- autoFocus
- />
-
-
-
- ) : (
- <>
-
-
{session.title}
-
- {session.messageCount > 0 && (
-
{session.messageCount}{t("sidebar.messages")}
+ {/* 搜索栏 */}
+
+ setSearchQuery(e.target.value)}
+ />
+
+
+ {/* 会话列表(按时间分组) */}
+
+ {sessions.length === 0 ? (
+
{t("sidebar.empty")}
+ ) : (
+ (["today", "yesterday", "earlier"] as TimeGroup[]).map((groupKey) => {
+ const items = grouped[groupKey];
+ if (items.length === 0) return null;
+ return (
+
+
{groupLabels[groupKey]}
+ {items.map((session) => (
+
handleSelect(session.id)}
+ >
+ {editingId === session.id ? (
+
e.stopPropagation()}>
+ setEditTitle(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter") handleConfirmRename();
+ if (e.key === "Escape") handleCancelRename();
+ }}
+ autoFocus
+ />
+
+
+
+ ) : (
+ <>
+ {/* 视频标记图标 */}
+ {session.messageCount > 5 && (
+
📹
+ )}
+
+
{session.title}
+
+ {session.messageCount > 0 && (
+ {session.messageCount}{t("sidebar.messages")}
+ )}
+ {formatRelativeTime(session.lastActiveAt)}
+
+
+
+
+
+
+ >
)}
-
{formatRelativeTime(session.lastActiveAt)}
-
-
-
-
-
- >
- )}
-
- ))
- )}
+ ))}
+
+ );
+ })
+ )}
+
-
+ >
);
}
diff --git a/frontend/src/hooks/useVisionSession.ts b/frontend/src/hooks/useVisionSession.ts
index 739afbf..497b996 100644
--- a/frontend/src/hooks/useVisionSession.ts
+++ b/frontend/src/hooks/useVisionSession.ts
@@ -482,5 +482,6 @@ export function useVisionSession() {
toggleCamera,
toggleMic,
sendTextMessage,
+ captureFrame,
};
}
diff --git a/frontend/src/lib/i18n/en-US.ts b/frontend/src/lib/i18n/en-US.ts
index eec5531..b24bcb4 100644
--- a/frontend/src/lib/i18n/en-US.ts
+++ b/frontend/src/lib/i18n/en-US.ts
@@ -89,6 +89,42 @@ export const enUS: TranslationMap = {
"sidebar.messages": " messages",
"sidebar.rename": "Rename",
"sidebar.delete": "Delete",
+ "sidebar.search": "Search conversations...",
+ "sidebar.today": "Today",
+ "sidebar.yesterday": "Yesterday",
+ "sidebar.earlier": "Earlier",
+ "sidebar.pinned": "Pinned",
+ "sidebar.video": "Video",
+ "sidebar.clearHistory": "Clear History",
+
+ // Scene cards (empty state)
+ "scene.describe": "Describe my surroundings",
+ "scene.describe.desc": "Let AI observe and describe the current scene",
+ "scene.text": "Recognize text in view",
+ "scene.text.desc": "Extract and translate text from the scene",
+ "scene.object": "Analyze this object",
+ "scene.object.desc": "Identify objects and provide information",
+ "scene.suggest": "Give me suggestions",
+ "scene.suggest.desc": "Practical suggestions based on the current scene",
+
+ // Video controls (enhanced)
+ "controls.recognize": "Analyze Scene",
+ "controls.device.camera": "Camera",
+ "controls.device.mic": "Microphone",
+ "controls.device.default": "Default",
+ "controls.mode.realtime": "Realtime",
+ "controls.mode.ondemand": "On-demand",
+ "controls.mode.chat": "Chat only",
+
+ // Status bar
+ "statusbar.ready": "Ready · Select devices to start",
+ "statusbar.calling": "In call",
+ "statusbar.duration": "Duration",
+ "statusbar.recognitions": "recognitions",
+ "statusbar.tokens": "Tokens",
+
+ // Input enhanced
+ "chat.input.voice": "Voice input",
// Device errors
"error.vadInit": "VAD initialization failed",
diff --git a/frontend/src/lib/i18n/ja-JP.ts b/frontend/src/lib/i18n/ja-JP.ts
index 947973b..37bc1e8 100644
--- a/frontend/src/lib/i18n/ja-JP.ts
+++ b/frontend/src/lib/i18n/ja-JP.ts
@@ -89,6 +89,42 @@ export const jaJP: TranslationMap = {
"sidebar.messages": "件のメッセージ",
"sidebar.rename": "名前を変更",
"sidebar.delete": "削除",
+ "sidebar.search": "会話を検索...",
+ "sidebar.today": "今日",
+ "sidebar.yesterday": "昨日",
+ "sidebar.earlier": "それ以前",
+ "sidebar.pinned": "ピン留め",
+ "sidebar.video": "ビデオ",
+ "sidebar.clearHistory": "履歴をクリア",
+
+ // Scene cards (empty state)
+ "scene.describe": "周囲のシーンを説明して",
+ "scene.describe.desc": "AIが現在のシーンを観察して説明します",
+ "scene.text": "画面のテキストを認識",
+ "scene.text.desc": "シーン内のテキストを抽出・翻訳します",
+ "scene.object": "この物を分析して",
+ "scene.object.desc": "物体を識別して関連情報を提供します",
+ "scene.suggest": "アドバイスをください",
+ "scene.suggest.desc": "現在のシーンに基づいた実用的な提案",
+
+ // Video controls (enhanced)
+ "controls.recognize": "シーンを分析",
+ "controls.device.camera": "カメラ",
+ "controls.device.mic": "マイク",
+ "controls.device.default": "デフォルト",
+ "controls.mode.realtime": "リアルタイム",
+ "controls.mode.ondemand": "オンデマンド",
+ "controls.mode.chat": "チャットのみ",
+
+ // Status bar
+ "statusbar.ready": "準備完了 · デバイスを選択して開始",
+ "statusbar.calling": "通話中",
+ "statusbar.duration": "通話時間",
+ "statusbar.recognitions": "回の認識",
+ "statusbar.tokens": "トークン",
+
+ // Input enhanced
+ "chat.input.voice": "音声入力",
// Device errors
"error.vadInit": "VAD初期化に失敗しました",
diff --git a/frontend/src/lib/i18n/zh-CN.ts b/frontend/src/lib/i18n/zh-CN.ts
index d085cde..1f49ae0 100644
--- a/frontend/src/lib/i18n/zh-CN.ts
+++ b/frontend/src/lib/i18n/zh-CN.ts
@@ -89,6 +89,42 @@ export const zhCN: TranslationMap = {
"sidebar.messages": "条消息",
"sidebar.rename": "重命名",
"sidebar.delete": "删除",
+ "sidebar.search": "搜索对话...",
+ "sidebar.today": "今天",
+ "sidebar.yesterday": "昨天",
+ "sidebar.earlier": "更早",
+ "sidebar.pinned": "置顶",
+ "sidebar.video": "视频",
+ "sidebar.clearHistory": "清除历史",
+
+ // Scene cards (empty state)
+ "scene.describe": "描述我面前的场景",
+ "scene.describe.desc": "让 AI 观察并描述当前画面",
+ "scene.text": "识别画面中的文字",
+ "scene.text.desc": "提取并翻译画面里的文字",
+ "scene.object": "帮我分析这个物品",
+ "scene.object.desc": "识别物体并给出相关信息",
+ "scene.suggest": "给我一些建议",
+ "scene.suggest.desc": "基于当前场景给出实用建议",
+
+ // Video controls (enhanced)
+ "controls.recognize": "识别画面",
+ "controls.device.camera": "摄像头",
+ "controls.device.mic": "麦克风",
+ "controls.device.default": "默认",
+ "controls.mode.realtime": "实时分析",
+ "controls.mode.ondemand": "按需识别",
+ "controls.mode.chat": "纯聊天",
+
+ // Status bar
+ "statusbar.ready": "就绪 · 选择设备后开始通话",
+ "statusbar.calling": "通话中",
+ "statusbar.duration": "通话时长",
+ "statusbar.recognitions": "次识别",
+ "statusbar.tokens": "Token",
+
+ // Input enhanced
+ "chat.input.voice": "语音输入",
// Device errors
"error.vadInit": "VAD 初始化失败",