import { Maximize2, X, Minus, Moon, Crosshair } from 'lucide-react'; import { useShallow } from 'zustand/react/shallow'; import { bridge } from '../../lib/bridge'; import { useSettings } from '../../state/settings'; import { useChat } from '../../state/chat'; import { useVoice } from '../../state/voice'; import { CoreStage } from '../hud/CoreStage'; import { ChatPanel } from '../chat/ChatPanel'; const STATE_LABEL: Record = { idle: 'veille', listening: 'écoute', thinking: 'réflexion', speaking: 'parle', alert: 'alerte', error: 'erreur', success: 'terminé' }; /** Compact mode: a glanceable strip (state, unread, last sentence) above the mini chat. */ export function CompactWidget() { const assistantName = useSettings((s) => s.settings.assistantName); const compactOpacity = useSettings((s) => s.settings.ui.compactOpacity); const { hud, hudOverride, unread, missionMode, quiet, last } = useChat( useShallow((s) => { const lastAssistant = [...s.messages].reverse().find((m) => m.role === 'assistant' && m.content.trim()); return { hud: s.hud, hudOverride: s.hudOverride, unread: s.unread, missionMode: s.missionMode, quiet: s.quiet, last: lastAssistant?.content ?? '' }; }) ); const wake = useVoice((s) => s.wake); const api = bridge(); const state = hudOverride ?? hud; const label = state === 'idle' && wake === 'spotting' ? 'à l’écoute du mot-clé' : STATE_LABEL[state] ?? state; const sentence = last.replace(/```[\s\S]*?```/g, ' ').replace(/[#*_>`|]/g, '').replace(/\s+/g, ' ').trim().slice(0, 140); return (
{assistantName} {api && ( <> )}
useChat.getState().markRead()} title={sentence}> {label} {sentence || 'Aucun message pour l’instant.'} {missionMode && } {quiet && } {unread > 0 && {unread}}
); }