fix: honor Komodo health and prefer fresh telemetry across fleet status
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import type { GameTelemetry } from '$lib/telemetry.js';
|
||||
import { freshTelemetry } from '$lib/server-observation.js';
|
||||
import { uiNow } from '$ui/stores/servers.js';
|
||||
import { elapsedSince } from '$ui/duration.js';
|
||||
import { mapTitle } from '$ui/server-labels.js';
|
||||
@@ -9,8 +10,9 @@
|
||||
import Badge from './primitives/Badge.svelte';
|
||||
import EmptyState from './primitives/EmptyState.svelte';
|
||||
|
||||
let { report, mapLabel, game }: { report: GameTelemetry | undefined; mapLabel?: string; game: string } = $props();
|
||||
const timingNow = $derived(report && (report.event === 'game_end' || $uiNow - Date.parse(report.receivedAt) > 120_000)
|
||||
let { report, mapLabel, game, current = true, after = null }: { report: GameTelemetry | undefined; mapLabel?: string; game: string; current?: boolean; after?: string | null } = $props();
|
||||
const fresh = $derived(current && freshTelemetry(report, $uiNow, after));
|
||||
const timingNow = $derived(report && (report.event === 'game_end' || !fresh)
|
||||
? Date.parse(report.receivedAt) : $uiNow);
|
||||
const columns = [
|
||||
{ key: 'score', label: 'Score' },
|
||||
@@ -38,11 +40,11 @@
|
||||
</script>
|
||||
|
||||
{#if !report}
|
||||
<EmptyState title="Waiting for game data" description="The scoreboard will appear when this server reports a game start, round change, or game end." />
|
||||
<EmptyState title="Waiting for game data" description="The scoreboard will appear when this server reports a game start, round change, heartbeat, or game end." />
|
||||
{:else}
|
||||
<header class="scoreboard-header">
|
||||
<div class="match">
|
||||
<span class="eyebrow">{report.event === 'game_end' ? 'Final scoreboard' : 'Latest scoreboard'}</span>
|
||||
<span class="eyebrow">{report.event === 'game_end' ? 'Final scoreboard' : fresh ? 'Live scoreboard' : 'Last reported scoreboard'}</span>
|
||||
<div class="match-title">
|
||||
<h2 title={report.map}>{mapLabel ?? mapTitle(report.map)}</h2>
|
||||
{#if report.event !== 'game_start'}<Badge variant="accent" size="md">Round {report.round}</Badge>{/if}
|
||||
@@ -51,7 +53,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-meta">
|
||||
<span>{players.length} {players.length === 1 ? 'player' : 'players'}</span>
|
||||
<span>{players.length} {players.length === 1 ? 'player' : 'players'} in this report</span>
|
||||
{#if !fresh}<Badge variant="warning">Historical report</Badge>{/if}
|
||||
<time datetime={report.receivedAt} title={$timeFormat.dateTime(report.receivedAt)}>
|
||||
Updated {elapsedSince(report.receivedAt, $uiNow)} ago
|
||||
</time>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import { telemetryByServer, uiNow } from '$ui/stores/servers.js';
|
||||
import { freshStatusTimestamp } from '$lib/server-freshness.js';
|
||||
import { elapsedSince } from '$ui/duration.js';
|
||||
let { name, since = null }: { name: string; since?: string | null } = $props();
|
||||
let report = $derived($telemetryByServer.get(name));
|
||||
let fresh = $derived(report && $uiNow - Date.parse(report.receivedAt) >= 0
|
||||
&& $uiNow - Date.parse(report.receivedAt) <= 120_000
|
||||
import type { GameTelemetry } from '$lib/telemetry.js';
|
||||
let { name, since = null, report: observation }: { name: string; since?: string | null; report?: GameTelemetry } = $props();
|
||||
let report = $derived(observation ?? $telemetryByServer.get(name));
|
||||
let fresh = $derived(report && freshStatusTimestamp(report.receivedAt, $uiNow)
|
||||
&& (!since || Date.parse(report.receivedAt) >= Date.parse(since)));
|
||||
</script>
|
||||
|
||||
{#if report && (report.event === 'round_change' || report.event === 'heartbeat') && fresh}
|
||||
<div class="round" aria-live="polite">
|
||||
<strong>Round {report.round}</strong>
|
||||
<span title={$timeFormat.dateTime(report.receivedAt)}>Last reported {elapsedSince(report.receivedAt, $uiNow)} ago · {report.players.length} players</span>
|
||||
<span title={$timeFormat.dateTime(report.receivedAt)}>Last reported {elapsedSince(report.receivedAt, $uiNow)} ago</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
betaId: number;
|
||||
}
|
||||
interface Props {
|
||||
telemetry?: import('$lib/telemetry.js').GameTelemetry;
|
||||
name: string;
|
||||
players?: number | null;
|
||||
map?: string | null;
|
||||
@@ -35,6 +36,7 @@
|
||||
mapLabelOverride?: string;
|
||||
}
|
||||
let {
|
||||
telemetry,
|
||||
name,
|
||||
players = null,
|
||||
map = null,
|
||||
@@ -66,7 +68,7 @@
|
||||
let topRoster = $derived(
|
||||
(roster ?? [])
|
||||
.slice()
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.sort((a, b) => (b.score ?? 0) - (a.score ?? 0))
|
||||
.slice(0, 4)
|
||||
);
|
||||
let showRoster = $derived(health === 'online' || health === 'stale');
|
||||
@@ -134,7 +136,7 @@
|
||||
{#if topRoster.length}<div class="roster-heading">Last reported players</div>{/if}
|
||||
{/if}
|
||||
|
||||
{#if health === 'online' && players !== null && players > 0 && gameInProgress}<RoundTelemetry {name} since={gameStartedAt} />{/if}
|
||||
{#if health === 'online' && players !== null && players > 0 && gameInProgress}<RoundTelemetry {name} report={telemetry} since={gameStartedAt} />{/if}
|
||||
|
||||
{#if showTiming && !(compactEmpty && players === 0)}
|
||||
<div class="timing">
|
||||
@@ -169,8 +171,8 @@
|
||||
{#each topRoster as p (p.guid ?? p.name)}
|
||||
<li>
|
||||
<span class="pname">{p.name || '—'}</span>
|
||||
<span class="pscore">{p.score}</span>
|
||||
<span class="pping">{p.ping}ms</span>
|
||||
<span class="pscore">{p.score ?? '—'}</span>
|
||||
<span class="pping">{p.ping === null ? '—' : `${p.ping}ms`}</span>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user