Fix backend sync race causing reverted edits
This commit is contained in:
14
src/app.js
14
src/app.js
@@ -1767,6 +1767,9 @@ let reconnectTimer = null;
|
|||||||
let backendSyncTimer = null;
|
let backendSyncTimer = null;
|
||||||
let appVersionPollTimer = null;
|
let appVersionPollTimer = null;
|
||||||
let baselineAppVersion = "";
|
let baselineAppVersion = "";
|
||||||
|
let localStateVersion = 0;
|
||||||
|
let syncedStateVersion = 0;
|
||||||
|
let localStateDirty = false;
|
||||||
let selectedClassEditId = null;
|
let selectedClassEditId = null;
|
||||||
let selectedLeaderboardKey = null;
|
let selectedLeaderboardKey = null;
|
||||||
let selectedGridSessionId = null;
|
let selectedGridSessionId = null;
|
||||||
@@ -2134,6 +2137,8 @@ function saveState(options = {}) {
|
|||||||
const persistable = buildPersistableState();
|
const persistable = buildPersistableState();
|
||||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(persistable));
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(persistable));
|
||||||
if (!options.skipBackend) {
|
if (!options.skipBackend) {
|
||||||
|
localStateVersion += 1;
|
||||||
|
localStateDirty = true;
|
||||||
scheduleBackendSync();
|
scheduleBackendSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2675,6 +2680,7 @@ function scheduleBackendSync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function syncStateToBackend() {
|
async function syncStateToBackend() {
|
||||||
|
const syncVersion = localStateVersion;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${getBackendUrl()}/api/state`, {
|
const res = await fetch(`${getBackendUrl()}/api/state`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -2687,6 +2693,10 @@ async function syncStateToBackend() {
|
|||||||
backend.available = true;
|
backend.available = true;
|
||||||
backend.lastError = "";
|
backend.lastError = "";
|
||||||
backend.lastSyncAt = new Date().toISOString();
|
backend.lastSyncAt = new Date().toISOString();
|
||||||
|
syncedStateVersion = Math.max(syncedStateVersion, syncVersion);
|
||||||
|
if (syncVersion === localStateVersion) {
|
||||||
|
localStateDirty = false;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
backend.available = false;
|
backend.available = false;
|
||||||
backend.lastError = t("error.sync_failed", { msg: error instanceof Error ? error.message : String(error) });
|
backend.lastError = t("error.sync_failed", { msg: error instanceof Error ? error.message : String(error) });
|
||||||
@@ -2740,7 +2750,9 @@ async function checkAppVersion() {
|
|||||||
function startOverlaySync() {
|
function startOverlaySync() {
|
||||||
clearInterval(overlaySyncTimer);
|
clearInterval(overlaySyncTimer);
|
||||||
overlaySyncTimer = setInterval(async () => {
|
overlaySyncTimer = setInterval(async () => {
|
||||||
await hydrateFromBackend();
|
if (!localStateDirty) {
|
||||||
|
await hydrateFromBackend();
|
||||||
|
}
|
||||||
if (currentView === "overlay") {
|
if (currentView === "overlay") {
|
||||||
renderView();
|
renderView();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user