import { useState } from "react"; import { useAppStore } from "../store/useAppStore"; import { useCurrentMood, useCurrentPersona } from "../store/personaSelectors"; import { useModeStore } from "../store/useModeStore"; import { applyTheme, readTheme, type ThemeMode } from "../lib/theme"; import { personaAvatar } from "../lib/persona"; import { labelFor } from "../lib/enums"; import type { Mode, WsStatus } from "../lib/types"; import { UiModeSwitch } from "../design/UiModeSwitch"; import { Tag } from "./primitives"; import { Icon, type IconName } from "./Icon"; import { AwakenBadge } from "./status"; const MODE_LABEL: Record = { chat: "对话", code: "代码", home: "家居", work: "工作", docs: "知识库", voice: "语音", vision: "视觉", agents: "子代理", settings: "设置", }; const MODE_ICON: Record = { chat: "chat", code: "terminal", home: "home", work: "folder", docs: "docs", voice: "mic", vision: "vision", agents: "agent", settings: "settings", }; const wsMeta: Record = { idle: { label: "未连接", tone: "neutral" }, connecting: { label: "连接中", tone: "warn" }, connected: { label: "实时", tone: "ok" }, reconnecting: { label: "重连中", tone: "warn" }, disconnected: { label: "已断开", tone: "err" }, expired: { label: "登录过期", tone: "err" }, }; export function TopBar({ onMenu }: { onMenu: () => void }): React.ReactNode { const wsStatus = useAppStore((s) => s.wsStatus); // Both follow the *active session's* role (design/22 §4.6): switching sessions // switches the avatar/name, and the mood is the one the active role reported // (mood frames are role-scoped). const mood = useCurrentMood(); const currentPersona = useCurrentPersona(); const mode = useModeStore((s) => s.mode); const [theme, setTheme] = useState(readTheme); const toggleTheme = () => { const next: ThemeMode = theme === "dark" ? "light" : "dark"; applyTheme(next); setTheme(next); }; const meta = wsMeta[wsStatus]; return (
{currentPersona?.name
{currentPersona?.name ?? "昔涟"}
{MODE_LABEL[mode]}
{mood ? 心情 · {labelFor("mood", mood)} : null} {meta.label} {/* 双档 UI 档位(裁决 16.4.4):胶囊形态,尺寸对齐本栏其余 h-8 按钮。 窄屏(
); }