From 2a034ff9be5704ddd3472ca8cbe234fe814f2e03 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Tue, 16 Jun 2026 21:06:31 +0200 Subject: [PATCH] fix(ui): don't refetch the lobby on heartbeats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lobby refetched /user/games on every stream event, including the 10s keep-alive heartbeat, turning it into a 10s poll. That poll's REST view of a just-committed opponent move could flip a card (and now blink it) seconds before the matching your_turn event — and its toast — arrived over the slower live stream, so the new lobby-card blink appeared to lead the toast by 5-7s (variable with stream delivery; in sync when prompt). Gate the refetch to real events (kind !== 'heartbeat'): the card, its blink and the toast now ride the same event (opponent_moved + your_turn are published together), and the constant 10s full-lobby poll per client is gone. --- ui/src/screens/Lobby.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/src/screens/Lobby.svelte b/ui/src/screens/Lobby.svelte index d80af3e..89df2cf 100644 --- a/ui/src/screens/Lobby.svelte +++ b/ui/src/screens/Lobby.svelte @@ -55,7 +55,11 @@ void load(); }); $effect(() => { - if (app.lastEvent) void load(); + // Refetch on a real game event only — not the 10 s keep-alive heartbeat. Refetching on every + // heartbeat turned the lobby into a 10 s poll whose REST view of a just-committed opponent move + // could update (and blink) a card seconds before the matching your_turn event/toast arrived + // over the slower live stream; gating it keeps the card, its blink and the toast on one event. + if (app.lastEvent && app.lastEvent.kind !== 'heartbeat') void load(); }); const myId = $derived(app.session?.userId ?? '');