Scope live chat to the current match and save match history
This commit is contained in:
@@ -7,11 +7,13 @@
|
||||
import { timeFormat } from '$ui/stores/time-zone.js';
|
||||
import Button from './primitives/Button.svelte';
|
||||
|
||||
let { server }: { server: string } = $props();
|
||||
let entries = $state<ContextualChatEntry[]>([]);
|
||||
let { server, history }: { server?: string; history?: ContextualChatEntry[] } = $props();
|
||||
let liveEntries = $state<ContextualChatEntry[]>([]);
|
||||
const entries = $derived(history ?? liveEntries);
|
||||
let timeline = $derived(groupChatTimeline(entries));
|
||||
let hasMessages = $derived(entries.some(entry => entry.type === 'message'));
|
||||
let loaded = $state(false);
|
||||
let liveLoaded = $state(false);
|
||||
const loaded = $derived(history !== undefined || liveLoaded);
|
||||
let loading = $state(false);
|
||||
let manualRefreshing = $state(false);
|
||||
let error = $state('');
|
||||
@@ -22,6 +24,7 @@
|
||||
let controller: AbortController | null = null;
|
||||
|
||||
async function refresh(manual = false) {
|
||||
if (!server) return;
|
||||
if (loading) {
|
||||
if (manual) manualRefreshing = true;
|
||||
return;
|
||||
@@ -36,9 +39,9 @@
|
||||
if (!response.ok || !data?.ok) throw new Error('Could not refresh chat. Try again shortly.');
|
||||
if (request.signal.aborted) return;
|
||||
if (paused && !manual) return;
|
||||
entries = data.entries ?? [];
|
||||
liveEntries = data.entries ?? [];
|
||||
missing = !!data.missing;
|
||||
loaded = true;
|
||||
liveLoaded = true;
|
||||
error = '';
|
||||
await tick();
|
||||
if (follow && body) body.scrollTop = body.scrollHeight;
|
||||
@@ -56,6 +59,7 @@
|
||||
if (body) body.scrollTop = body.scrollHeight;
|
||||
}
|
||||
onMount(() => {
|
||||
if (!server) return;
|
||||
const stop = pollVisible(() => paused ? Promise.resolve() : refresh(), 5000);
|
||||
return () => { stop(); controller?.abort(); };
|
||||
});
|
||||
@@ -89,18 +93,20 @@
|
||||
|
||||
<section aria-label="Player chat">
|
||||
<div class="chat-head">
|
||||
<div class="chat-title"><h2>Chat</h2><span class="update-cadence">{paused ? 'Paused' : 'Live · 5s'}</span></div>
|
||||
<div class="actions">
|
||||
{#if hasMessages}<Button size="sm" variant="ghost" onclick={() => paused = !paused}>{paused ? 'Resume' : 'Pause'}</Button>{/if}
|
||||
{#if !follow}<Button size="sm" variant="ghost" onclick={latest}>Latest messages</Button>{/if}
|
||||
<Button size="sm" onclick={() => refresh(true)} loading={manualRefreshing} ariaLabel={manualRefreshing ? 'Refreshing chat' : 'Refresh chat'}>Refresh</Button>
|
||||
</div>
|
||||
<div class="chat-title"><h2>Chat</h2><span class="update-cadence">{server ? paused ? 'Paused' : 'Live · 5s' : 'Match history'}</span></div>
|
||||
{#if server}
|
||||
<div class="actions">
|
||||
{#if hasMessages}<Button size="sm" variant="ghost" onclick={() => paused = !paused}>{paused ? 'Resume' : 'Pause'}</Button>{/if}
|
||||
{#if !follow}<Button size="sm" variant="ghost" onclick={latest}>Latest messages</Button>{/if}
|
||||
<Button size="sm" onclick={() => refresh(true)} loading={manualRefreshing} ariaLabel={manualRefreshing ? 'Refreshing chat' : 'Refresh chat'}>Refresh</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if error}<p class="ui-error" role="alert">{error} {loaded ? 'Showing the last loaded messages.' : ''}</p>{/if}
|
||||
{#if !loaded && !error}
|
||||
<p class="empty" role="status">Loading chat…</p>
|
||||
{:else if loaded && !hasMessages}
|
||||
<p class="empty">{missing ? 'Waiting for the game log. Player messages will appear here.' : 'No player messages in the recent game log.'}</p>
|
||||
<p class="empty">{history !== undefined ? 'No chat messages were saved for this match.' : missing ? 'Waiting for the game log. Player messages will appear here.' : 'No player messages in this match yet.'}</p>
|
||||
{:else if hasMessages}
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex (The scrollable chat region must support keyboard scrolling.) -->
|
||||
<div class="messages" bind:this={body} onscroll={onScroll} tabindex="0" role="region" aria-label="Chat messages">
|
||||
|
||||
Reference in New Issue
Block a user