Refresh Fleet with discovery, operation progress, and lobby watches
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
import type { BlueprintSummary, LaunchPreview } from '$lib/deployment-plan.js';
|
||||
import type { ZombieMapEntry, ZombieGame } from '$lib/map-aliases.js';
|
||||
|
||||
let { open = $bindable(false), initialBlueprintId = '', sourceDeploymentId = '', onblueprint }:
|
||||
{ open?: boolean; initialBlueprintId?: string; sourceDeploymentId?: string; onblueprint?: () => void } = $props();
|
||||
let { open = $bindable(false), initialBlueprintId = '', sourceDeploymentId = '', initialGame = 't5', initialMapSlug = '', onblueprint }:
|
||||
{ open?: boolean; initialBlueprintId?: string; sourceDeploymentId?: string; initialGame?: ZombieGame; initialMapSlug?: string; onblueprint?: () => void } = $props();
|
||||
let dialog: HTMLDialogElement | undefined = $state();
|
||||
let game = $state<ZombieGame>('t5');
|
||||
let mapSlug = $state('');
|
||||
@@ -40,6 +40,8 @@
|
||||
preview = null; plutoKey = ''; error = ''; loaded = false; busy = false;
|
||||
blueprintName = ''; description = ''; savedName = ''; saving = false;
|
||||
blueprintId = initialBlueprintId;
|
||||
game = initialGame;
|
||||
mapSlug = initialMapSlug;
|
||||
try {
|
||||
const [mapRes, blueprintRes] = await Promise.all([fetch('/api/maps'), fetch('/api/blueprints')]);
|
||||
if (!mapRes.ok || !blueprintRes.ok) throw new Error('Could not load maps and blueprints. Try again.');
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { telemetryByServer, uiNow } from '$ui/stores/servers.js';
|
||||
import { elapsedSince } from '$ui/duration.js';
|
||||
let { name }: { name: string } = $props();
|
||||
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
|
||||
&& (!since || Date.parse(report.receivedAt) >= Date.parse(since)));
|
||||
</script>
|
||||
|
||||
{#if report}
|
||||
{#if report && fresh}
|
||||
<div class="round" aria-live="polite">
|
||||
<strong>Round {report.round}</strong>
|
||||
<span title={report.receivedAt}>Last reported {elapsedSince(report.receivedAt, $uiNow)} ago · {report.players} players</span>
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
inactiveSince?: string | null;
|
||||
gameStartedAt?: string | null;
|
||||
gameEndedAt?: string | null;
|
||||
compactEmpty?: boolean;
|
||||
mapLabelOverride?: string;
|
||||
}
|
||||
let {
|
||||
name,
|
||||
@@ -46,7 +48,9 @@
|
||||
activeSince = null,
|
||||
inactiveSince = null,
|
||||
gameStartedAt = null,
|
||||
gameEndedAt = null
|
||||
gameEndedAt = null,
|
||||
compactEmpty = false,
|
||||
mapLabelOverride
|
||||
}: Props = $props();
|
||||
|
||||
function ago(iso: string | null): string {
|
||||
@@ -66,7 +70,7 @@
|
||||
);
|
||||
let showRoster = $derived(health === 'online' || health === 'stale');
|
||||
let title = $derived(serverTitle(name));
|
||||
let mapLabel = $derived(mapTitle(map));
|
||||
let mapLabel = $derived(mapLabelOverride ?? mapTitle(map));
|
||||
let gtLabel = $derived(gametypeLabel(gametype));
|
||||
|
||||
let activeElapsed = $derived(activeSince ? elapsedSince(activeSince, $uiNow) : null);
|
||||
@@ -106,7 +110,7 @@
|
||||
{:else}
|
||||
<div class="players" aria-live="polite">
|
||||
<Stat
|
||||
value={players ?? 0}
|
||||
value={players ?? '—'}
|
||||
size="md"
|
||||
tone={players !== null && players > 0 ? 'online' : 'primary'}
|
||||
tween
|
||||
@@ -123,9 +127,9 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if showRoster}<RoundTelemetry {name} />{/if}
|
||||
{#if health === 'online' && players !== null && players > 0 && gameInProgress}<RoundTelemetry {name} since={gameStartedAt} />{/if}
|
||||
|
||||
{#if showTiming}
|
||||
{#if showTiming && !(compactEmpty && players === 0)}
|
||||
<div class="timing">
|
||||
{#if activeElapsed}
|
||||
<div class="metric">
|
||||
@@ -159,7 +163,7 @@
|
||||
{/each}
|
||||
</ul>
|
||||
{:else}
|
||||
<div class="lobby-empty">Lobby is empty</div>
|
||||
<div class="lobby-empty">{health === 'stale' ? 'Waiting for a fresh report' : players === 0 ? 'Lobby is empty' : 'Player roster unavailable'}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { toasts, dismiss } from '$ui/toast.js';
|
||||
</script>
|
||||
|
||||
<div class="toaster" role="region" aria-label="Notifications">
|
||||
<div class="toaster" role="region" aria-label="Notifications" aria-live="polite">
|
||||
{#each $toasts as t (t.id)}
|
||||
<div
|
||||
class="toast v-{t.variant}"
|
||||
@@ -13,6 +13,7 @@
|
||||
>
|
||||
<span class="dot" aria-hidden="true"></span>
|
||||
<span class="msg">{t.message}</span>
|
||||
{#if t.href}<a href={t.href} onclick={() => dismiss(t.id)}>View</a>{/if}
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
|
||||
Reference in New Issue
Block a user