rosary: server-side streak fetch, remove aggressive polling
All checks were successful
CI / update (push) Successful in 1m29s

- Fetch streak data in +page.server.ts for logged-in users via API
- Initialize store once with server data, sync only runs once
- Only poll for reconnection in PWA mode when offline with pending changes
- Extract FireEffect to separate component with burst animation
- Convert StreakAura/StreakCounter to Svelte 5 runes ($props, $state, $derived)
- Fix SSR flash by using server data for initial render
This commit is contained in:
2026-02-01 13:49:38 +01:00
parent 01fd067eda
commit 924ce386d5
6 changed files with 525 additions and 90 deletions

View File

@@ -4,6 +4,11 @@ import type { PageServerLoad } from './$types';
// TODO: allow prerendering/fetching of bible verses at compile time while keeping the rest dynamic.
// export const prerender = true; # breaks user logged-in state
interface StreakData {
length: number;
lastPrayed: string | null;
}
async function fetchBibleData(reference: string, fetch: typeof globalThis.fetch): Promise<{ text: string; verseData: VerseData | null }> {
try {
const response = await fetch(`/api/glaube/bibel/${encodeURIComponent(reference)}`);
@@ -33,7 +38,9 @@ async function fetchBibleData(reference: string, fetch: typeof globalThis.fetch)
}
}
export const load: PageServerLoad = async ({ fetch }) => {
export const load: PageServerLoad = async ({ fetch, locals }) => {
const session = await locals.auth();
// Fetch Bible texts for all mysteries at build time
const mysteryDescriptions: Record<string, MysteryDescription[]> = {
lichtreichen: [],
@@ -59,7 +66,21 @@ export const load: PageServerLoad = async ({ fetch }) => {
mysteryDescriptions[mysteryType] = descriptions;
}
// Fetch streak data for logged-in users via API route
let streakData: StreakData | null = null;
if (session?.user?.nickname) {
try {
const res = await fetch('/api/glaube/rosary-streak');
if (res.ok) {
streakData = await res.json();
}
} catch {
// Server unavailable, client will use localStorage
}
}
return {
mysteryDescriptions
mysteryDescriptions,
streakData
};
};

View File

@@ -1215,7 +1215,7 @@ l536 389l-209 -629zM1671 934l-370 267l150 436l-378 -271l-371 271q8 -34 15 -68q10
<!-- Toggle Controls & Streak Counter -->
<div class="controls-row">
<StreakCounter user={data.session?.user} />
<StreakCounter streakData={data.streakData} />
<div class="toggle-controls">
<!-- Luminous Mysteries Toggle -->
<Toggle