diff --git a/frontend/src/routes/play/+page.svelte b/frontend/src/routes/play/+page.svelte index b588201..71c4ea1 100644 --- a/frontend/src/routes/play/+page.svelte +++ b/frontend/src/routes/play/+page.svelte @@ -3,6 +3,8 @@ import { goto, afterNavigate } from '$app/navigation'; import { page } from '$app/stores'; import { getJSON } from '$lib/api.js'; + import { pushGameState } from '$lib/gamesync.js'; + import { auth } from '$lib/auth.svelte.js'; import WordGame from '$lib/components/WordGame.svelte'; import WordSearchGame from '$lib/components/WordSearchGame.svelte'; @@ -50,6 +52,29 @@ return Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0'); } + // The hub itself reconciles every game with the server (signed-in), so cards + // show cross-device status WITHOUT having to open each game first, and this + // device's local progress gets uploaded even for games it hasn't reopened. + async function syncOne(g, v, key) { + let local = null; + try { local = JSON.parse(localStorage.getItem(key) || 'null'); } catch { /* ignore */ } + const merged = await pushGameState(g, v, date, local || {}); + if (!merged) return; + if (g === 'wordsearch') merged.status = merged.ms ? 'done' : 'playing'; // card reads .status + try { localStorage.setItem(key, JSON.stringify(merged)); } catch { /* ignore */ } + } + async function syncAllGames() { + if (!auth.user || !date) return; + await Promise.allSettled([ + syncOne('word', '5', `goodnews:word:5:${date}`), + syncOne('word', '6', `goodnews:word:6:${date}`), + syncOne('wordsearch', 'small', `goodnews:wordsearch:small:${date}`), + syncOne('wordsearch', 'med', `goodnews:wordsearch:med:${date}`), + syncOne('wordsearch', 'large', `goodnews:wordsearch:large:${date}`), + ]); + refreshStatus(); + } + // Hub card one-liners function wordLabel() { const a = wordStatus['5'], b = wordStatus['6']; @@ -123,6 +148,7 @@ try { date = (await getJSON('/api/puzzle/word?variant=5')).date; } catch { /* offline */ } try { wsTheme = (await getJSON('/api/puzzle/wordsearch?variant=med')).theme; } catch { /* offline */ } refreshStatus(); + syncAllGames(); // signed-in: pull cross-device status into the cards + upload local progress }); // Refresh hub/selection statuses whenever we land on a screen (incl. Back). afterNavigate(() => refreshStatus());