fix: streak counter showing zero on second device due to stale localStorage
All checks were successful
CI / update (push) Successful in 1m30s
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:
@@ -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() {
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
Reference in New Issue
Block a user