refactor(web): 前端单页收敛修正——导航式侧边栏 + 去输入模式 chip,mode 由后端自切

按设计/01 §3 + 主人要求:行为模式切换由后端/agent 自切(热切换),前端不再提供
手动切换的行为模式按钮列表。
- 侧边栏改为导航式(连接状态 / 设置 / 管理面板 / 主题),不再列行为模式按钮;
  App.tsx 还原 <Sidebar/> 布局。
- ChatInput 去掉行为模式 chip 切换条(模式不由用户手选)。
- useChat.send/chatStream 不再传 mode;消息 mode 由后端在回复时决定,
  MessageBubble 仍按 message.mode 渲染。
- ChatShell onVoice 为占位(语音处理在 agent)。
This commit is contained in:
Aska committed 2026-09-06 14:04:46 +08:00
1 parent 4aab0f501a
commit 77f75b0d99
6 files changed
+105 -129

No files matched your search

+4 -6
View File
@@ -1,6 +1,5 @@
import { useEffect, useRef } from "react";
import { useAppStore } from "../store/useAppStore";
import { useModeStore } from "../store/useModeStore";
import { useSendChat } from "../lib/useChat";
import { MessageBubble } from "../components/chat";
import { ChatInput } from "../components/ChatInput";
@@ -9,15 +8,14 @@ import { Icon } from "../components/Icon";
/**
* The single shared page (design/07 §1). All behavior modes live in ONE message
* stream; each message carries its own `mode`, so its bubble renders per that
* mode — a session can mix chat / code / home / docs / work / vision shapes.
* The "input mode" chip above the composer sets the mode of the NEXT message.
* stream; each message carries its own `mode` (assigned by the agent at runtime,
* design/01 §3 hot-switch), so its bubble renders per that mode. There is no
* manual mode selector — the agent / backend drives the mode.
*/
export function ChatShell(): React.ReactNode {
const messages = useAppStore((s) => s.messages);
const { send, sending } = useSendChat();
const bottomRef = useRef<HTMLDivElement>(null);
const setMode = useModeStore((s) => s.setMode);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
@@ -39,7 +37,7 @@ export function ChatShell(): React.ReactNode {
<div ref={bottomRef} />
</div>
</div>
<ChatInput onSend={(t, mode) => void send(t, mode)} sending={sending} onVoice={() => setMode("voice")} />
<ChatInput onSend={(t) => void send(t)} sending={sending} onVoice={() => { /* voice handled by agent */ }} />
</div>
);
}