import type { Command, RGB, Telemetry } from '@/shared/contracts/robot.ts'; import type { AccessState, CommandAck } from '@/client/radio/session-state.ts'; import { ActionLabel } from '@/client/ui/action-label.tsx'; import { Icon } from '@/client/ui/icons.tsx'; import { BranchPanel } from '@/client/exhibit/branch-panel.tsx'; import type { ExplanationTrigger } from '@/client/exhibit/diagram/diagram-model.ts'; import { LedControls } from './led-controls.tsx'; import { TelemetryReadout } from './telemetry-readout.tsx'; type Props = ExplanationTrigger & { telemetry?: Telemetry; trackCount: number; paused: boolean; led?: RGB; auth: AccessState; connected: boolean; held: boolean; occupied: boolean; busy: boolean; ack: CommandAck; live: boolean; onToggleControl: () => void; onSend: (command: Command) => void; }; export function ControlsPanel({ telemetry, trackCount, paused, led, auth, connected, held, occupied, busy, ack, live, onToggleControl, onSend, ...explanation }: Props) { const pending = ack.state === 'pending'; const canSend = held && !pending; const canToggle = connected && !busy && !occupied; const send = (command: Command) => { if (canSend) onSend(command); }; return (
{auth === 'checking' ? 'Checking access…' : auth === 'required' ? 'Unlock access to use the controls.' : !connected ? 'Start listening to use the controls.' : held ? 'You have control' : occupied ? 'Another listener has control' : 'Controls available'}

LED and playback changes affect everyone.

send({ led: rgb })} />
PLAYBACK

{ack.state === 'confirmed' ? '✓ ' : ack.state === 'pending' ? '↖ ' : ''} {ack.text}

); }