This commit is contained in:
legop3
2025-11-15 23:14:29 -05:00
parent f645390c92
commit aa6808a400
8 changed files with 30 additions and 32 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webui</title> <title>webui</title>
<script type="module" crossorigin src="/assets/index-Bd9-jciT.js"></script> <script type="module" crossorigin src="/assets/index-D4pzotAD.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BLqBO1Eu.css"> <link rel="stylesheet" crossorigin href="/assets/index-D4wUVUN4.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+7 -7
View File
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useState } from 'react';
import { useSession } from './context/SessionContext.jsx'; import { useSession } from './context/SessionContext.jsx';
import { useTelemetryFrame } from './context/TelemetryContext.jsx'; import { useTelemetryFrame } from './context/TelemetryContext.jsx';
import TelemetryPanel from './components/TelemetryPanel.jsx'; import TelemetryPanel from './components/TelemetryPanel.jsx';
@@ -84,16 +84,16 @@ function DriverVideoPanel() {
const sources = useVideoRequests(roverId ? [roverId] : []); const sources = useVideoRequests(roverId ? [roverId] : []);
const info = roverId ? sources[roverId] : null; const info = roverId ? sources[roverId] : null;
const frame = useTelemetryFrame(roverId); const frame = useTelemetryFrame(roverId);
const batteryConfig = useMemo(() => { const batteryRecord =
if (!roverId || !session?.roster) return null; roverId && session?.roster
const record = session.roster.find((item) => String(item.id) === String(roverId)); ? session.roster.find((item) => String(item.id) === String(roverId))
return record?.battery ?? null; : null;
}, [session?.roster, roverId]); const batteryConfig = batteryRecord?.battery ?? null;
return ( return (
<section className="rounded-sm bg-[#242a32] p-1"> <section className="rounded-sm bg-[#242a32] p-1">
{roverId ? ( {roverId ? (
<div className="min-h-[70vh]"> <div className="lg:min-h-[70vh]">
<VideoTile <VideoTile
sessionInfo={info} sessionInfo={info}
label={roverId} label={roverId}
+7 -3
View File
@@ -118,9 +118,13 @@ function AuxMotorControls() {
export default function MobileControlsStack() { export default function MobileControlsStack() {
return ( return (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1 sm:flex-row">
<MobileJoystick /> <div className="flex-1">
<AuxMotorControls /> <MobileJoystick />
</div>
<div className="flex-1">
<AuxMotorControls />
</div>
</div> </div>
); );
} }
+2 -8
View File
@@ -14,7 +14,6 @@ export default function VideoTile({ sessionInfo, label, forceMute = false, telem
const [muted, setMuted] = useState(true); const [muted, setMuted] = useState(true);
const sensors = telemetryFrame?.sensors; const sensors = telemetryFrame?.sensors;
const batteryCharge = sensors?.batteryChargeMah ?? null; const batteryCharge = sensors?.batteryChargeMah ?? null;
const batteryCapacity = sensors?.batteryCapacityMah ?? null;
// console.log('[BatteryBarDebug]', { // console.log('[BatteryBarDebug]', {
// frameSensors: sensors, // frameSensors: sensors,
// batteryCharge, // batteryCharge,
@@ -143,12 +142,12 @@ export default function VideoTile({ sessionInfo, label, forceMute = false, telem
<HudOverlay frame={telemetryFrame} /> <HudOverlay frame={telemetryFrame} />
<OvercurrentOverlay active={overcurrentActive} /> <OvercurrentOverlay active={overcurrentActive} />
</div> </div>
<BatteryBar charge={batteryCharge} capacity={batteryCapacity} config={batteryConfig} label={label} status={renderedStatus} /> <BatteryBar charge={batteryCharge} config={batteryConfig} label={label} status={renderedStatus} />
</div> </div>
); );
} }
function BatteryBar({ charge, capacity, config, label, status }) { function BatteryBar({ charge, config, label, status }) {
const full = config?.Full; const full = config?.Full;
const warn = config?.Warn; const warn = config?.Warn;
const urgent = config?.Urgent ?? null; const urgent = config?.Urgent ?? null;
@@ -173,17 +172,12 @@ function BatteryBar({ charge, capacity, config, label, status }) {
const depleted = normalized <= 0; const depleted = normalized <= 0;
const warnTriggered = urgent != null && charge <= urgent; const warnTriggered = urgent != null && charge <= urgent;
const barClass = depleted ? 'bg-red-500 animate-pulse' : warnTriggered ? 'bg-amber-400' : 'bg-emerald-500'; const barClass = depleted ? 'bg-red-500 animate-pulse' : warnTriggered ? 'bg-amber-400' : 'bg-emerald-500';
const capText = capacity ? `${charge}/${capacity}` : `${charge}`;
return ( return (
<div className="space-y-2 rounded-sm bg-[#1e1e1e] px-2 py-2 text-sm text-slate-200"> <div className="space-y-2 rounded-sm bg-[#1e1e1e] px-2 py-2 text-sm text-slate-200">
<div className="flex items-center justify-between text-xs text-slate-400"> <div className="flex items-center justify-between text-xs text-slate-400">
<span>{label}</span> <span>{label}</span>
<span>{status}</span> <span>{status}</span>
</div> </div>
{/* <div className="flex items-center justify-between text-sm">
<span>Battery</span>
<span>{capText} mAh</span>
</div> */}
<div className="relative h-4 w-full rounded-full bg-slate-800"> <div className="relative h-4 w-full rounded-full bg-slate-800">
<div className={`h-full rounded-full transition-[width] ${barClass}`} style={{ width: `${percentDisplay}%` }} /> <div className={`h-full rounded-full transition-[width] ${barClass}`} style={{ width: `${percentDisplay}%` }} />
<span className="absolute inset-0 flex items-center justify-center text-xs font-semibold text-black/80"> <span className="absolute inset-0 flex items-center justify-center text-xs font-semibold text-black/80">