fix: streak counter showing zero on second device due to stale localStorage
All checks were successful
CI / update (push) Successful in 1m30s

The RosaryStreakStore singleton survives client-side navigation but
the first mount. Also reorder onMount to merge server data before
assigning to streak, preventing a frame of stale localStorage values.
This commit is contained in:
2026-02-15 22:06:21 +01:00
parent 8c984f3064
commit a435a1142f
2 changed files with 6 additions and 9 deletions

View File

@@ -30,9 +30,12 @@ const labels = $derived({
}); });
// Initialize store on mount (client-side only) // Initialize store on mount (client-side only)
// Init with server data BEFORE assigning to streak, so displayLength
// never sees stale localStorage data from the singleton
onMount(() => { onMount(() => {
streak = getRosaryStreak(); const s = getRosaryStreak();
streak.initWithServerData(streakData, streakData !== null); s.initWithServerData(streakData, isLoggedIn);
streak = s;
}); });
async function pray() { async function pray() {

View File

@@ -79,7 +79,6 @@ class RosaryStreakStore {
#initialized = false; #initialized = false;
#syncing = $state(false); #syncing = $state(false);
#pendingSync = false; // Track if we have unsynced changes #pendingSync = false; // Track if we have unsynced changes
#hasSyncedOnce = false; // Track if initial sync has completed
#isOffline = $state(false); #isOffline = $state(false);
#reconnectInterval: ReturnType<typeof setInterval> | null = null; #reconnectInterval: ReturnType<typeof setInterval> | null = null;
@@ -164,14 +163,11 @@ class RosaryStreakStore {
return this.#syncing; return this.#syncing;
} }
// Initialize with server data (called once on page load) // Initialize with server data (called on each component mount)
initWithServerData(serverData: StreakData | null, isLoggedIn: boolean): void { initWithServerData(serverData: StreakData | null, isLoggedIn: boolean): void {
if (this.#hasSyncedOnce) return; // Only sync once
this.#isLoggedIn = isLoggedIn; this.#isLoggedIn = isLoggedIn;
if (!isLoggedIn || !serverData) { if (!isLoggedIn || !serverData) {
this.#hasSyncedOnce = true;
return; return;
} }
@@ -187,8 +183,6 @@ class RosaryStreakStore {
if (merged.length !== serverData.length || merged.lastPrayed !== serverData.lastPrayed) { if (merged.length !== serverData.length || merged.lastPrayed !== serverData.lastPrayed) {
this.#pushToServer(); this.#pushToServer();
} }
this.#hasSyncedOnce = true;
} }
async #pushToServer(): Promise<void> { async #pushToServer(): Promise<void> {