Add active/inactive/game-time timers to fleet + server pages
Fleet cards and the per-server detail hero now show three live-ticking timers: Active (since players > 0), Inactive (since server emptied), and Game (since InitGame in games_sp.log, back-computed from the log's own MM:SS prefix so it stays accurate across restarts). Anchors are persisted on `servers` and fanned out via the SSE bus; a single 1s ticker feeds every card. Idle map cycles are filtered out so the game timer doesn't flicker.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Format an elapsed millisecond count as a compact human string:
|
||||
* < 60s -> "12s"
|
||||
* < 1h -> "5m 23s"
|
||||
* >= 1h -> "2h 05m"
|
||||
* Negatives clamp to 0s (clock skew tolerance).
|
||||
*/
|
||||
export function formatDuration(ms: number): string {
|
||||
if (!Number.isFinite(ms) || ms < 0) ms = 0;
|
||||
const totalSeconds = Math.floor(ms / 1000);
|
||||
if (totalSeconds < 60) return `${totalSeconds}s`;
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, '0')}s`;
|
||||
const hours = Math.floor(minutes / 60);
|
||||
const mins = minutes % 60;
|
||||
return `${hours}h ${String(mins).padStart(2, '0')}m`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: elapsed since an ISO timestamp, formatted. Returns null when
|
||||
* the anchor is null so callers can `{#if}` on it.
|
||||
*/
|
||||
export function elapsedSince(iso: string | null, now: number): string | null {
|
||||
if (!iso) return null;
|
||||
return formatDuration(now - new Date(iso).getTime());
|
||||
}
|
||||
Reference in New Issue
Block a user