import { SettingsProvider } from '../settings/index.js'; import { useSession } from '../context/SessionContext.jsx'; import { useSpectatorMode } from '../hooks/useSpectatorMode.js'; import { useTelemetryFrames } from '../context/TelemetryContext.jsx'; import { useVideoRequests } from '../hooks/useVideoRequests.js'; import VideoTile from '../components/VideoTile.jsx'; import RoomCameraPanel from '../components/RoomCameraPanel.jsx'; import UserListPanel from '../components/UserListPanel.jsx'; import ChatPanel from '../components/ChatPanel.jsx'; import LogPanel from '../components/LogPanel.jsx'; import RoverRoster from '../components/RoverRoster.jsx'; function formatDriverLabel({ roverId, session }) { const activeDriverId = session?.activeDrivers?.[roverId] || null; const user = (session?.users || []).find((entry) => entry.socketId === activeDriverId); const label = user?.nickname || (activeDriverId ? activeDriverId.slice(0, 6) : 'No driver'); const mode = session?.mode; const turnInfo = session?.turnQueues?.[roverId]; const driverText = mode === 'turns' && turnInfo?.current ? `${label} (turns)` : label; return driverText; } function RoverSpectatorCard({ rover, frame, videoInfo, audioInfo, session }) { const driverLabel = formatDriverLabel({ roverId: rover.id, session }); return (
); } function RoverRow({ roster, frames, videoSources, session }) { if (roster.length === 0) { return

No rovers registered.

; } return (
{roster.map((rover) => ( ))}
); } function SecondaryRow() { return (
); } function LogsRow({ className = '' }) { return (
); } export default function SpectatorApp() { const { session } = useSession(); useSpectatorMode(); const frames = useTelemetryFrames(); const roster = session?.roster ?? []; const entries = roster.flatMap((rover) => { const base = { type: 'rover', id: rover.id, key: rover.id }; if (rover.media?.audioPublishUrl) { return [base, { type: 'rover', id: `${rover.id}-audio`, key: `${rover.id}-audio` }]; } return [base]; }); const videoSources = useVideoRequests(entries); return (
); }