Files
MultiRoombaRover/webui/src/display/ServerDisplayApp/utils.js
T

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';
}