- 将 vanilla TS 单文件 (app.ts 395行) 拆分为 React 组件化架构 - 引入 Zustand 管理全局状态 (连接/录音/预览/历史/toast) - 自定义 hooks 封装 WebSocket 连接和音频录制管线 - CSS 全面 Tailwind 化,style.css 从 234 行精简到 114 行 (仅保留 tokens + keyframes) - 新增依赖: react, react-dom, zustand, @vitejs/plugin-react - Go 后端 embed 路径 web/dist 不变,无需改动
36 lines
976 B
TypeScript
36 lines
976 B
TypeScript
import { useAppStore } from "../stores/app-store";
|
|
|
|
const statusConfig = {
|
|
connected: {
|
|
text: "\u5df2\u8fde\u63a5",
|
|
dotClass: "bg-success shadow-[0_0_6px_rgba(52,211,153,0.5)]",
|
|
borderClass: "border-success/15",
|
|
},
|
|
disconnected: {
|
|
text: "\u5df2\u65ad\u5f00",
|
|
dotClass: "bg-danger shadow-[0_0_6px_rgba(244,63,94,0.4)]",
|
|
borderClass: "border-edge",
|
|
},
|
|
connecting: {
|
|
text: "\u8fde\u63a5\u4e2d\u2026",
|
|
dotClass: "bg-accent animate-pulse-dot",
|
|
borderClass: "border-edge",
|
|
},
|
|
} as const;
|
|
|
|
export function StatusBadge() {
|
|
const status = useAppStore((s) => s.connectionStatus);
|
|
const { text, dotClass, borderClass } = statusConfig[status];
|
|
|
|
return (
|
|
<div
|
|
className={`flex items-center gap-[7px] rounded-full border bg-surface px-3 py-[5px] font-medium text-fg-dim text-xs transition-all ${borderClass}`}
|
|
>
|
|
<span
|
|
className={`size-[7px] shrink-0 rounded-full transition-all duration-300 ${dotClass}`}
|
|
/>
|
|
<span>{text}</span>
|
|
</div>
|
|
);
|
|
}
|