import { useEffect, useMemo, useState } from 'react';
import { useSession } from './context/SessionContext.jsx';
import { useTelemetryFrame } from './context/TelemetryContext.jsx';
import TelemetryPanel from './components/TelemetryPanel.jsx';
import VideoTile from './components/VideoTile.jsx';
import DrivePanel from './components/DrivePanel.jsx';
import AlertFeed from './components/AlertFeed.jsx';
import AdminPanel from './components/AdminPanel.jsx';
import MobileControls, { MobileJoystick, AuxMotorControls } from './components/MobileControls.jsx';
import { DriveControlProvider } from './context/DriveControlContext.jsx';
import { useVideoRequests } from './hooks/useVideoRequests.js';
function RoomCameraPanel() {
return (
Room camera
Feed placeholder. Wire upcoming room cam here.
);
}
function useLayoutMode() {
const [mode, setMode] = useState(() => {
if (typeof window === 'undefined') return 'desktop';
return window.innerWidth >= 1024
? 'desktop'
: window.innerWidth > window.innerHeight
? 'mobile-landscape'
: 'mobile-portrait';
});
useEffect(() => {
function updateMode() {
if (typeof window === 'undefined') return;
const { innerWidth, innerHeight } = window;
if (innerWidth >= 1024) {
setMode('desktop');
} else if (innerWidth > innerHeight) {
setMode('mobile-landscape');
} else {
setMode('mobile-portrait');
}
}
updateMode();
window.addEventListener('resize', updateMode);
return () => window.removeEventListener('resize', updateMode);
}, []);
return mode;
}
function LogPanel() {
const { logs } = useSession();
return (
Server logs
{logs.length}
{logs.length === 0 ? (
No logs yet.
) : (
logs
.slice()
.reverse()
.map((entry) => (
{entry.timestamp}{' '}
[{entry.level}]{' '}
{entry.label && [{entry.label}]}{' '}
{entry.message}
))
)}
);
}
function DriverVideoPanel() {
const { session } = useSession();
const roverId = session?.assignment?.roverId;
const sources = useVideoRequests(roverId ? [roverId] : []);
const info = roverId ? sources[roverId] : null;
const frame = useTelemetryFrame(roverId);
const batteryConfig = useMemo(() => {
if (!roverId || !session?.roster) return null;
const record = session.roster.find((item) => String(item.id) === String(roverId));
return record?.battery ?? null;
}, [session?.roster, roverId]);
return (
{roverId ? (
) : (
Assign a rover to view the video feed.
)}
);
}
function AuthPanel() {
const { login, setRole } = useSession();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
async function handleLogin(event) {
event.preventDefault();
setLoading(true);
try {
await login(username, password);
setUsername('');
setPassword('');
} catch (err) {
alert(err.message);
} finally {
setLoading(false);
}
}
return (
Admin login
);
}
function DesktopLayout() {
return (
);
}
function MobilePortraitLayout() {
return (
);
}
function MobileLandscapeLayout() {
return (
);
}
function App() {
const layout = useLayoutMode();
const renderedLayout = layout === 'desktop' ? : layout === 'mobile-landscape' ? : ;
return (
);
}
export default App;