From 2194dbdb4fca8d08425c99bcef62ee4e0398abfc Mon Sep 17 00:00:00 2001 From: larssand Date: Wed, 25 Mar 2026 22:20:50 +0100 Subject: [PATCH] Fix backend sync race causing reverted edits --- src/app.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index f2dfe00..3c845f1 100644 --- a/src/app.js +++ b/src/app.js @@ -1767,6 +1767,9 @@ let reconnectTimer = null; let backendSyncTimer = null; let appVersionPollTimer = null; let baselineAppVersion = ""; +let localStateVersion = 0; +let syncedStateVersion = 0; +let localStateDirty = false; let selectedClassEditId = null; let selectedLeaderboardKey = null; let selectedGridSessionId = null; @@ -2134,6 +2137,8 @@ function saveState(options = {}) { const persistable = buildPersistableState(); localStorage.setItem(STORAGE_KEY, JSON.stringify(persistable)); if (!options.skipBackend) { + localStateVersion += 1; + localStateDirty = true; scheduleBackendSync(); } } @@ -2675,6 +2680,7 @@ function scheduleBackendSync() { } async function syncStateToBackend() { + const syncVersion = localStateVersion; try { const res = await fetch(`${getBackendUrl()}/api/state`, { method: "POST", @@ -2687,6 +2693,10 @@ async function syncStateToBackend() { backend.available = true; backend.lastError = ""; backend.lastSyncAt = new Date().toISOString(); + syncedStateVersion = Math.max(syncedStateVersion, syncVersion); + if (syncVersion === localStateVersion) { + localStateDirty = false; + } } catch (error) { backend.available = false; backend.lastError = t("error.sync_failed", { msg: error instanceof Error ? error.message : String(error) }); @@ -2740,7 +2750,9 @@ async function checkAppVersion() { function startOverlaySync() { clearInterval(overlaySyncTimer); overlaySyncTimer = setInterval(async () => { - await hydrateFromBackend(); + if (!localStateDirty) { + await hydrateFromBackend(); + } if (currentView === "overlay") { renderView(); }