fixing up mobile layouts

This commit is contained in:
legop3
2025-11-22 19:10:50 -05:00
parent 3be9e17ecc
commit 930f411549
10 changed files with 62 additions and 53 deletions
+15 -9
View File
@@ -72,8 +72,10 @@ function DesktopLayout({ layout }) {
function MobilePortraitLayout() {
return (
<div className="flex flex-col gap-0.5">
<DriverVideoPanel />
<DriverVideoPanel layoutFormat='mobile'/>
<MobileControls />
<ChatPanel />
<UserListPanel />
<DrivePanel />
<TelemetryPanel />
<AuthPanel />
@@ -90,23 +92,27 @@ function MobileLandscapeLayout() {
<div className="flex flex-col gap-0.5">
<section className="grid min-h-screen grid-cols-[minmax(0,0.7fr)_minmax(0,2.1fr)_minmax(0,0.7fr)] gap-0.5">
<MobileLandscapeAuxColumn />
<DriverVideoPanel />
<div>
<DriverVideoPanel layoutFormat='mobile'/>
<TelemetryPanel />
</div>
<MobileLandscapeControlColumn />
</section>
<div className="flex flex-col gap-0.5 pb-0.5">
<RoomCameraPanel />
<HomeAssistantControls />
<DrivePanel />
<section className="grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-0.5">
<div className="flex flex-col gap-0.5">
<AuthPanel />
<AdminPanel />
{/* <AuthPanel /> */}
{/* <AdminPanel /> */}
<UserListPanel />
</div>
<div className="flex flex-col gap-0.5">
<LogPanel />
<TelemetryPanel />
{/* <LogPanel /> */}
<ChatPanel />
</div>
</section>
<RoomCameraPanel />
<HomeAssistantControls />
{/* <DrivePanel /> */}
</div>
</div>
);
+2 -2
View File
@@ -3,7 +3,7 @@ import { useTelemetryFrame } from '../context/TelemetryContext.jsx';
import { useVideoRequests } from '../hooks/useVideoRequests.js';
import VideoTile from './VideoTile.jsx';
export default function DriverVideoPanel() {
export default function DriverVideoPanel({layoutFormat = 'desktop'}) {
const { session } = useSession();
const roverId = session?.assignment?.roverId;
const sources = useVideoRequests(roverId ? [roverId] : []);
@@ -20,7 +20,7 @@ export default function DriverVideoPanel() {
return (
<section className="panel">
{roverId ? (
<VideoTile sessionInfo={info} label={roverLabel} telemetryFrame={frame} batteryConfig={batteryConfig} />
<VideoTile sessionInfo={info} label={roverLabel} telemetryFrame={frame} batteryConfig={batteryConfig} layoutFormat={layoutFormat}/>
) : (
<div className="panel-muted content-center text-center text-sm text-slate-400 aspect-video">
<p>You are not assigned to a rover.</p>
+18 -16
View File
@@ -7,13 +7,13 @@ const SOURCE = 'mobile-joystick';
const JOYSTICK_RADIUS = 80;
const JOYSTICK_SMOOTHING = 0.15;
const AUX_BUTTONS = [
{ id: 'main-forward', label: 'Main +', values: { main: 127 }, hold: true, color: 'bg-emerald-600' },
{ id: 'main-reverse', label: 'Main -', values: { main: -127 }, hold: true, color: 'bg-emerald-800' },
{ id: 'side-forward', label: 'Side +', values: { side: 127 }, hold: true, color: 'bg-cyan-600' },
{ id: 'side-reverse', label: 'Side -', values: { side: -70 }, hold: true, color: 'bg-cyan-800' },
{ id: 'main-forward', label: 'Main Brush +', values: { main: 127 }, hold: true, color: 'bg-emerald-600' },
{ id: 'main-reverse', label: 'Main Brush -', values: { main: -127 }, hold: true, color: 'bg-emerald-800' },
{ id: 'all-forward', label: 'All Motors +', values: { main: 127, side: 127, vacuum: 127 }, hold: true, color: 'bg-fuchsia-600' },
{ id: 'side-forward', label: 'Side Brush +', values: { side: 127 }, hold: true, color: 'bg-cyan-600' },
{ id: 'side-reverse', label: 'Side Brush -', values: { side: -70 }, hold: true, color: 'bg-cyan-800' },
{ id: 'vacuum-fast', label: 'Vacuum Max', values: { vacuum: 127 }, hold: true, color: 'bg-amber-500 text-amber-950' },
{ id: 'vacuum-slow', label: 'Vacuum Low', values: { vacuum: 50 }, hold: true, color: 'bg-amber-700' },
{ id: 'all-forward', label: 'All +', values: { main: 127, side: 127, vacuum: 127 }, hold: true, color: 'bg-fuchsia-600' },
{ id: 'stop-all', label: 'Stop', values: { main: 0, side: 0, vacuum: 0 }, hold: false, color: 'bg-slate-900' },
];
@@ -196,17 +196,8 @@ function MobileJoystickPanel({ layout }) {
return (
<div className="flex flex-col gap-0.5 text-slate-100">
<DriveModeToggle size="compact" />
<FloatingJoystick
disabled={disabled}
layout={layout}
radius={joystickRadius}
onMove={handleMove}
onStop={handleStop}
/>
<button type="button" onClick={stopAllMotion} disabled={disabled} className="button-danger w-full disabled:opacity-40">
Panic Stop
</button>
{cameraEnabled && (
<div className="bg-zinc-950 p-0.5 text-xs">
<div className="flex items-center justify-between text-[0.75rem] text-slate-400">
@@ -224,6 +215,17 @@ function MobileJoystickPanel({ layout }) {
/>
</div>
)}
<FloatingJoystick
disabled={disabled}
layout={layout}
radius={joystickRadius}
onMove={handleMove}
onStop={handleStop}
/>
<button type="button" onClick={stopAllMotion} disabled={disabled} className="button-danger w-full disabled:opacity-40">
Panic Stop
</button>
</div>
);
}
@@ -280,7 +282,7 @@ function AuxMotorPanel({ orientation }) {
onPointerLeave={() => handleRelease(button)}
onPointerCancel={() => handleRelease(button)}
onContextMenu={(event) => event.preventDefault()}
className={`px-0.5 py-0.5 text-left text-sm font-semibold text-white transition ${button.color} hover:brightness-110 disabled:opacity-30`}
className={`px-0.5 py-0.5 text-left text-sm font-semibold text-white transition ${button.color} hover:brightness-110 disabled:opacity-30 h-10`}
>
{button.label}
</button>
+9 -8
View File
@@ -4,7 +4,7 @@ import { WhepPlayer } from '../lib/whepPlayer.js';
const RESTART_DELAY_MS = 2000;
const UNMUTE_RETRY_MS = 3000;
export default function VideoTile({ sessionInfo, label, forceMute = false, telemetryFrame, batteryConfig }) {
export default function VideoTile({ sessionInfo, label, forceMute = false, telemetryFrame, batteryConfig, layoutFormat = 'desktop' }) {
const videoRef = useRef(null);
const restartTimer = useRef(null);
const unmuteTimer = useRef(null);
@@ -14,6 +14,7 @@ export default function VideoTile({ sessionInfo, label, forceMute = false, telem
const [muted, setMuted] = useState(true);
const sensors = telemetryFrame?.sensors;
const batteryCharge = sensors?.batteryChargeMah ?? null;
const desktopLayout = layoutFormat === 'desktop';
// console.log('[BatteryBarDebug]', {
// frameSensors: sensors,
// batteryCharge,
@@ -157,7 +158,7 @@ export default function VideoTile({ sessionInfo, label, forceMute = false, telem
controls={false}
className="h-full w-full object-contain"
/>
<HudOverlay frame={telemetryFrame} label={label} status={renderedStatus} />
<HudOverlay frame={telemetryFrame} label={label} status={renderedStatus} desktopLayout={desktopLayout}/>
<OvercurrentOverlay motors={overcurrentMotors} />
<LowBatteryOverlay charge={batteryCharge} config={batteryConfig} />
</div>
@@ -200,7 +201,7 @@ function BatteryBar({ charge, config }) {
);
}
function HudOverlay({ frame, label, status }) {
function HudOverlay({ frame, label, status, desktopLayout = true }) {
const sensors = frame?.sensors;
const bumps = sensors?.bumpsAndWheelDrops || {};
const [now, setNow] = useState(() => Date.now());
@@ -224,11 +225,11 @@ function HudOverlay({ frame, label, status }) {
{/* bump and wheel drops bar */}
<div className="absolute top-0.5 left-1/2 flex -translate-x-1/2 gap-1 bg-black/70 px-0.5 py-0.5 text-[0.6rem] font-medium text-slate-200">
<div className={`px-1 py-0.5 ${bumps.bumpLeft ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Left bump</div>
<div className={`px-1 py-0.5 ${bumps.wheelDropLeft ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Left wheel drop</div>
<div className={`px-1 py-0.5 ${bumps.wheelDropRight ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Right wheel drop</div>
<div className={`px-1 py-0.5 ${bumps.bumpRight ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Right bump</div>
<div className="absolute top-0.5 left-1/2 flex -translate-x-1/2 gap-1 bg-black/70 text-[0.6rem] font-medium text-slate-200">
<div className={`${desktopLayout ? 'px-1 py-0.5':'px-0.5 py-0 text-nowrap'} ${bumps.bumpLeft ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Left bump</div>
<div className={`${desktopLayout ? 'px-1 py-0.5':'px-0.5 py-0 text-nowrap'} ${bumps.wheelDropLeft ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Left wheel drop</div>
<div className={`${desktopLayout ? 'px-1 py-0.5':'px-0.5 py-0 text-nowrap'} ${bumps.wheelDropRight ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Right wheel drop</div>
<div className={`${desktopLayout ? 'px-1 py-0.5':'px-0.5 py-0 text-nowrap'} ${bumps.bumpRight ? 'bg-red-600 text-white animate-pulse' : 'text-slate-500'}`}>Right bump</div>
</div>
</div>
);