// Preference sync. Anonymous visitors keep using localStorage exactly as // before — this file is a no-op for them. When a user is signed in (Authentik // via OIDC), the server is the source of truth: their stored blob is injected // as window.PETE_PREFS and seeded into localStorage *synchronously* here, before // the feature scripts (settings.js, weather*.js) read it. Those scripts then // call PetePrefs.push() after every write to mirror the change back up. // // This script must run before the others — it's loaded first in layout.html, // and all the feature scripts are `defer`, so document order is guaranteed. (function () { // The localStorage keys we sync. The weather *cache* is deliberately excluded: // it's transient and per-device. var SYNCED = ["pete.disabledSources.v1", "pete.weather.loc.v1", "pete-weather-off", "pete.sfx.off"]; var user = window.PETE_USER || null; var serverPrefs = window.PETE_PREFS || null; function seed(prefs) { SYNCED.forEach(function (k) { if (!Object.prototype.hasOwnProperty.call(prefs, k)) return; var v = prefs[k]; try { if (v === null || v === undefined) localStorage.removeItem(k); else localStorage.setItem(k, String(v)); } catch (e) {} }); } function snapshot() { var out = {}; SYNCED.forEach(function (k) { try { var v = localStorage.getItem(k); if (v !== null) out[k] = v; } catch (e) {} }); return out; } var timer = null; function push() { if (!user) return; // anonymous: localStorage only if (timer) clearTimeout(timer); timer = setTimeout(function () { timer = null; try { fetch("/api/preferences", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(snapshot()), credentials: "same-origin", keepalive: true }).catch(function () {}); } catch (e) {} }, 600); } window.PetePrefs = { push: push, loggedIn: !!user, syncedKeys: SYNCED }; if (user) { if (serverPrefs && typeof serverPrefs === "object") { seed(serverPrefs); // cross-device: server wins on load } else { push(); // first sign-in: migrate this browser's prefs to the account } // Swap "saved in this browser" copy for the synced story. document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll("[data-storage-note]").forEach(function (el) { el.textContent = "Synced to your account ✓"; }); }); } })();