import { useStore } from '@nanostores/react' import { useEffect, useRef } from 'react' import { createPortal } from 'react-dom' import { useNavigate } from 'react-router' import { sessionTitle } from '@/lib/chat-runtime' import { cn } from '@/lib/utils' import { $switcherIndex, $switcherOpen, $switcherSessions, closeSwitcher } from '@/store/session-switcher' import { SessionStatusDot } from './chat/session-status-dot' import { HUD_ITEM, HUD_POSITION, HUD_SURFACE, HUD_TEXT } from './floating-hud' import { openSession } from './open-session' // Compact session-switcher HUD — keyboard-driven from `use-keybinds`, rows // clickable via mousedown (Ctrl+click on macOS). No Dialog: Tab stays global. export function SessionSwitcher() { const open = useStore($switcherOpen) const sessions = useStore($switcherSessions) const index = useStore($switcherIndex) const navigate = useNavigate() const activeRef = useRef(null) useEffect(() => { activeRef.current?.scrollIntoView({ block: 'nearest' }) }, [index, open]) if (!open || sessions.length === 0) { return null } const pick = (sessionId: string) => { closeSwitcher() openSession(sessionId, navigate) } return createPortal( <> {/* Transparent click-catcher: click-away closes, but no dim/blur. */}
{ e.preventDefault() closeSwitcher() }} />
{sessions.map((session, i) => { const selected = i === index return (
{ e.preventDefault() pick(session.id) }} ref={selected ? activeRef : undefined} > {sessionTitle(session)} {i < 9 && ( ⌃{i + 1} )}
) })}
, document.body ) }