import { useCallback } from "react"; import { useAppStore } from "../stores/app-store"; interface MicButtonProps { onStart: () => void; onStop: () => void; } export function MicButton({ onStart, onStop }: MicButtonProps) { const connected = useAppStore((s) => s.connectionStatus === "connected"); const micReady = useAppStore((s) => s.micReady); const recording = useAppStore((s) => s.recording); const pendingStart = useAppStore((s) => s.pendingStart); const stopping = useAppStore((s) => s.stopping); const weakNetwork = useAppStore((s) => s.weakNetwork); const isActive = recording || pendingStart || stopping; const disabled = !connected || !micReady || stopping; const handlePointerDown = useCallback( (e: React.PointerEvent) => { if (e.button !== 0) return; e.preventDefault(); e.currentTarget.setPointerCapture(e.pointerId); onStart(); }, [onStart], ); const handlePointerUp = useCallback( (e: React.PointerEvent) => { e.preventDefault(); e.currentTarget.releasePointerCapture(e.pointerId); onStop(); }, [onStop], ); // Read latest state to avoid stale closures const handlePointerLeave = useCallback(() => { const s = useAppStore.getState(); if (s.recording || s.pendingStart) onStop(); }, [onStop]); const handlePointerCancel = useCallback(() => { const s = useAppStore.getState(); if (s.recording || s.pendingStart) onStop(); }, [onStop]); const disabledClasses = "cursor-not-allowed border-edge bg-linear-to-br from-surface-hover to-surface text-fg-secondary opacity-30 shadow-[0_2px_12px_rgba(0,0,0,0.3),inset_0_1px_0_rgba(255,255,255,0.04)]"; const activeClasses = "animate-mic-breathe scale-[1.06] border-accent-hover bg-accent text-white shadow-[0_0_32px_rgba(99,102,241,0.35),0_0_80px_rgba(99,102,241,0.2)]"; const weakClasses = "border-amber-400 bg-linear-to-br from-amber-400/15 to-surface text-amber-200 shadow-[0_0_22px_rgba(251,191,36,0.28)]"; const idleClasses = "border-edge bg-linear-to-br from-surface-hover to-surface text-fg-secondary shadow-[0_2px_12px_rgba(0,0,0,0.3),inset_0_1px_0_rgba(255,255,255,0.04)]"; return (
{/* Wave rings */}

{!micReady ? "请先准备麦克风" : !connected ? "连接中断,等待重连" : stopping ? "收尾中…" : weakNetwork ? "网络波动,已启用缓冲" : "按住说话"}

); }