this better work

This commit is contained in:
legop3
2026-01-21 13:36:01 -05:00
parent eb85b85b8f
commit 213630cb68
7 changed files with 163 additions and 128 deletions
@@ -10,6 +10,7 @@ export default function DriverVideoPanel({layoutFormat = 'desktop'}) {
const { session } = useSession();
const {
state: { song, lastControlIntentAt },
overcurrentLimiter,
} = useControlSystem();
const [now, setNow] = useState(() => Date.now());
const [turnCueVisible, setTurnCueVisible] = useState(false);
@@ -122,6 +123,7 @@ export default function DriverVideoPanel({layoutFormat = 'desktop'}) {
telemetryFrame={frame}
batteryConfig={batteryConfig}
layoutFormat={layoutFormat}
overcurrentLimiter={overcurrentLimiter}
songNote={song?.note}
qualityNotice={!shouldShowVideo ? 'Preview feed (low FPS) until your turn.' : null}
showTurnCue={turnCueVisible}
+39 -6
View File
@@ -54,6 +54,7 @@ export default function VideoTile({
hudMapPosition = 'top-right',
hudLabelScale = 1,
fitParent = false,
overcurrentLimiter = null,
showTurnCue = false,
turnTimerText = null,
turnSeconds = null,
@@ -94,6 +95,29 @@ export default function VideoTile({
: Object.entries(wheelOvercurrents)
.filter(([, active]) => Boolean(active))
.map(([key]) => key);
const limiterCaps = overcurrentLimiter?.caps || null;
const limiterGroups = overcurrentLimiter?.overcurrent?.groups || null;
const limiterFill = useMemo(() => {
if (!limiterCaps) return null;
const driveCap = Number.isFinite(limiterCaps?.drive?.cap) ? limiterCaps.drive.cap : 1;
const auxCap = Number.isFinite(limiterCaps?.aux?.cap) ? limiterCaps.aux.cap : 1;
return Math.max(0, Math.min(1, 1 - Math.min(driveCap, auxCap)));
}, [limiterCaps]);
const limiterLabels = useMemo(() => {
if (!limiterCaps) return [];
const labels = [];
const driveCap = Number.isFinite(limiterCaps?.drive?.cap) ? limiterCaps.drive.cap : 1;
const auxCap = Number.isFinite(limiterCaps?.aux?.cap) ? limiterCaps.aux.cap : 1;
if (Boolean(limiterGroups?.drive) || driveCap < 0.999) labels.push('Drive wheels');
if (Boolean(limiterGroups?.aux) || auxCap < 0.999) labels.push('Aux motors');
return labels;
}, [limiterCaps, limiterGroups]);
const overlayActive = Boolean(overcurrentMotors.length || (limiterFill != null && limiterFill > 0.001));
const overlayLabels = overcurrentMotors.length
? overcurrentMotors.map((name) => OVERCURRENT_LABELS[name] || name)
: limiterLabels.length
? limiterLabels
: ['Overcurrent'];
const scheduleRestart = useCallback(() => {
clearTimeout(restartTimer.current);
@@ -420,7 +444,12 @@ export default function VideoTile({
labelScale={hudLabelScale}
/>
<HudChatInput compact={mobileHud} />
<OvercurrentOverlay motors={overcurrentMotors} compact={mobileHud} />
<OvercurrentOverlay
labels={overlayLabels}
fill={limiterFill ?? (overcurrentMotors.length ? 1 : 0)}
visible={overlayActive}
compact={mobileHud}
/>
<LowBatteryOverlay charge={batteryCharge} config={batteryConfig} compact={mobileHud} />
{showVerticalBattery && batteryVisual.available ? (
<BatteryBarVertical visual={batteryVisual} />
@@ -720,17 +749,21 @@ const OVERCURRENT_LABELS = {
sideBrush: 'Side brush',
};
function OvercurrentOverlay({ motors, compact = false }) {
if (!motors?.length) return null;
const labels = motors.map((name) => OVERCURRENT_LABELS[name] || name);
function OvercurrentOverlay({ labels, fill = 0, visible = false, compact = false }) {
if (!visible) return null;
const containerClass = compact ? 'p-2' : 'p-4';
const textClass = compact ? 'text-lg' : 'text-4xl';
const subTextClass = compact ? 'text-xs' : 'text-xl';
const safeFill = Math.max(0, Math.min(1, fill));
const fillWidth = `${Math.round(safeFill * 100)}%`;
return (
<div
className={`pointer-events-none absolute flex items-center justify-center bg-red-900/60 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 ${containerClass}`}
className={`pointer-events-none absolute flex items-center justify-center bg-red-900/60 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 ${containerClass} relative`}
>
<div className={`text-center font-semibold text-white animate-pulse ${textClass}`}>
<div className="absolute inset-0 overflow-hidden">
<div className="h-full bg-red-700/60" style={{ width: fillWidth }} />
</div>
<div className={`relative z-10 text-center font-semibold text-white animate-pulse ${textClass}`}>
<div>OVERCURRENT</div>
<div className={`mt-0 font-medium text-white ${subTextClass}`}>{labels.join(', ')}</div>
</div>