Improve application responsiveness and background processing
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
<script lang="ts">
|
||||
let { data }: { data: import('./$types').PageData } = $props();
|
||||
const snapshot = $derived($fleet.receivedAt ? $fleet : data.fleetSnapshot);
|
||||
const visibleFleet = $derived($fleet.receivedAt ? $fleetServers : data.fleetSnapshot.servers);
|
||||
import RuntimeVersion from '$ui/components/RuntimeVersion.svelte';
|
||||
import MatchHistory from '$ui/components/MatchHistory.svelte';
|
||||
import RoundTelemetry from '$ui/components/RoundTelemetry.svelte';
|
||||
import TelemetryDiagnostics from '$ui/components/TelemetryDiagnostics.svelte';
|
||||
import { pollVisible } from '$ui/poll.js';
|
||||
import { fetchCampaigns } from '$ui/campaigns.js';
|
||||
import { fleet, fleetServers, fleetError, fleetIntegrations, refreshFleet } from '$ui/stores/fleet.js';
|
||||
import { freshServer, fleetIdentity } from '$lib/fleet-overview.js';
|
||||
import { serverTitle } from '$ui/server-labels.js';
|
||||
@@ -105,9 +109,9 @@
|
||||
}
|
||||
|
||||
let name = $derived($page.params.name ?? '');
|
||||
let server = $derived(($fleetServers.find(s => s.name === name) as Server | undefined) ?? null);
|
||||
let server = $derived((visibleFleet.find(s => s.name === name) as Server | undefined) ?? null);
|
||||
const native = $derived(!!server?.native_instance_id);
|
||||
let integrations = $derived($fleetIntegrations);
|
||||
let integrations = $derived($fleetIntegrations ?? data.fleetSnapshot.integrations);
|
||||
let history = $state<DeploymentRow[]>([]);
|
||||
let inventory = $state<InventoryEntry[]>([]);
|
||||
let komodoProbe = $state<KomodoProbeResult | null>(null);
|
||||
@@ -127,27 +131,39 @@
|
||||
let tabLoading = $state(false);
|
||||
let tabError = $state('');
|
||||
let historyLimit = $state(25);
|
||||
let historyTotal = $state(0);
|
||||
let inventoryLimit = $state(25);
|
||||
const operations = $derived($fleet.operations.filter(op => op.server === name));
|
||||
const operations = $derived(snapshot.operations.filter(op => op.server === name));
|
||||
|
||||
async function loadTab(currentName: string, tab: string) {
|
||||
let tabSequence = 0;
|
||||
async function loadTab(currentName: string, tab: string, signal?: AbortSignal) {
|
||||
if (tab !== 'history' && tab !== 'inventory') return;
|
||||
const sequence = ++tabSequence;
|
||||
try {
|
||||
const response = await fetch(tab === 'history' ? '/api/campaigns?server=' + encodeURIComponent(currentName) : '/api/servers/' + encodeURIComponent(currentName) + '/scripts');
|
||||
if (!response.ok) throw new Error('Could not refresh ' + tab + '.');
|
||||
const body = await response.json();
|
||||
if (name !== currentName || activeTab !== tab) return;
|
||||
if (tab === 'history') history = body.deployments; else inventory = body.scripts;
|
||||
if (tab === 'history') {
|
||||
const body = await fetchCampaigns<DeploymentRow>({ server: currentName }, historyLimit, signal);
|
||||
if (sequence !== tabSequence || name !== currentName || activeTab !== tab || signal?.aborted) return;
|
||||
history = body.deployments; historyTotal = body.total;
|
||||
} else {
|
||||
const response = await fetch('/api/servers/' + encodeURIComponent(currentName) + '/scripts', { signal });
|
||||
if (!response.ok) throw new Error('Could not refresh inventory.');
|
||||
const body = await response.json();
|
||||
if (sequence !== tabSequence || name !== currentName || activeTab !== tab || signal?.aborted) return;
|
||||
inventory = body.scripts;
|
||||
}
|
||||
tabError = '';
|
||||
} catch (error) { if (name === currentName && activeTab === tab) tabError = (error as Error).message; }
|
||||
finally { if (name === currentName && activeTab === tab) tabLoading = false; }
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (sequence === tabSequence && name === currentName && activeTab === tab && !signal?.aborted) tabError = (error as Error).message;
|
||||
return false;
|
||||
} finally { if (sequence === tabSequence && name === currentName && activeTab === tab && !signal?.aborted) tabLoading = false; }
|
||||
}
|
||||
$effect(() => {
|
||||
const currentName = name;
|
||||
const tab = activeTab;
|
||||
tabError = ''; history = []; inventory = []; historyLimit = 25; inventoryLimit = 25;
|
||||
tabLoading = tab === 'history' || tab === 'inventory';
|
||||
return pollVisible(() => loadTab(currentName, tab), 10000);
|
||||
return pollVisible(signal => loadTab(currentName, tab, signal), 10000);
|
||||
});
|
||||
$effect(() => { name; komodoProbe = null; rconProbe = null; netDiagnosis = null; });
|
||||
const fresh = $derived(server ? freshServer(server, $uiNow) : false);
|
||||
@@ -312,7 +328,7 @@
|
||||
|
||||
</Card>
|
||||
|
||||
{#if $fleetError}<div class="ui-error" role="alert">{$fleetError}<Button size="sm" onclick={refreshFleet}>Retry</Button></div>{/if}
|
||||
{#if $fleetError}<div class="ui-error" role="alert">{$fleetError}<Button size="sm" onclick={() => refreshFleet(true)}>Retry</Button></div>{/if}
|
||||
{#if hasDiagnosticIssue}
|
||||
<section class="connection-issue" aria-label="Server connection issue">
|
||||
<div><strong>{effectiveHealth === 'stale' ? 'Server report is outdated' : 'Server is not responding'}</strong><p>Player count is unknown. {effectiveSeen ? `Last successful report ${ago(effectiveSeen, $uiNow)}.` : 'No successful report has been received.'} {native && !server.host?.connected ? 'The host agent is offline; the game may still be running.' : !native && integrations && !integrations.rcon ? 'RCON is not configured.' : ''}</p></div>
|
||||
@@ -588,13 +604,13 @@
|
||||
</div>
|
||||
{/if}
|
||||
</Card>
|
||||
<ListFooter total={history.length} bind:limit={historyLimit} label="campaigns" />
|
||||
<ListFooter total={historyTotal} bind:limit={historyLimit} onchange={() => loadTab(name, 'history')} label="campaigns" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else if $fleetError}
|
||||
<div class="ui-error" role="alert">{$fleetError}<Button onclick={refreshFleet}>Retry</Button></div>
|
||||
{:else if $fleet.receivedAt}
|
||||
<div class="ui-error" role="alert">{$fleetError}<Button onclick={() => refreshFleet(true)}>Retry</Button></div>
|
||||
{:else if $fleet.receivedAt || data.fleetSnapshot}
|
||||
<EmptyState title="Server not found" description="This server may have been removed from the fleet." />
|
||||
{:else}
|
||||
<div class="loading">Loading…</div>
|
||||
|
||||
Reference in New Issue
Block a user