mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-11-14 18:58:49 -05:00
56 lines
2.4 KiB
JavaScript
56 lines
2.4 KiB
JavaScript
// Server Display Utilities
|
|
// Purpose: Supplies small formatting helpers shared by the room display components.
|
|
// Scope: Keeps the display route focused on presentation while still using the same
|
|
// session, roster, and battery data shapes as the rest of the web UI.
|
|
import { buildBatteryVisual } from '../../lib/battery.js';
|
|
|
|
export function formatUserName(user) {
|
|
// The room display is read from a distance, so every user needs a short stable
|
|
// label even when they have not set a nickname. Socket ids are noisy, but the
|
|
// first six characters match existing UI behavior and are enough to distinguish
|
|
// temporary visitors in the room.
|
|
return String(user?.nickname || user?.socketId?.slice(0, 6) || 'unknown').trim();
|
|
}
|
|
|
|
export function findDriverForRover({ roverId, session }) {
|
|
const turn = session?.roster?.find((rover) => String(rover.id) === String(roverId))?.turn;
|
|
const driver = turn?.queue?.find((entry) => entry.socketId === turn.currentId);
|
|
return driver ? { socketId: driver.socketId, label: driver.name } : null;
|
|
}
|
|
|
|
export function getDisplayBatteryVisual({ rover, frame }) {
|
|
// Roster battery state is the normal fast path because the server already
|
|
// classifies warning/urgent thresholds. Telemetry charge is included as a
|
|
// fallback so the display still gets a useful percentage if the roster state
|
|
// arrives before the richer battery snapshot is populated.
|
|
return buildBatteryVisual({
|
|
batteryState: rover?.batteryState ?? null,
|
|
charge: frame?.sensors?.batteryChargeMah ?? null,
|
|
config: rover?.battery ?? null,
|
|
});
|
|
}
|
|
|
|
export function formatBatteryText(visual) {
|
|
if (!visual?.available) return '--';
|
|
if (visual.urgentActive) return `${visual.percentDisplay}% Low`;
|
|
if (visual.warnActive) return `${visual.percentDisplay}% Low`;
|
|
return `${visual.percentDisplay}%`;
|
|
}
|
|
|
|
export function buildRoverStateText(rover, visual) {
|
|
const states = [];
|
|
if (rover?.private?.enabled && rover?.private?.open) states.push('Private');
|
|
if (visual?.urgentActive || visual?.warnActive) states.push('Low');
|
|
// Only exceptional state belongs here. The normal driver/id/battery lines
|
|
// already consume the big readable space, and extra routine labels make this
|
|
// utility board harder to scan from across the room.
|
|
return states.join(' · ');
|
|
}
|
|
|
|
export function gridClassForRoverCount(count) {
|
|
if (count <= 1) return 'grid-cols-1';
|
|
if (count === 2) return 'grid-cols-2';
|
|
if (count === 4) return 'grid-cols-2';
|
|
return 'grid-cols-3';
|
|
}
|