Pārlūkot izejas kodu

report: view state persists across bare reloads (localStorage layer under the URL params — server restart / new tab / binary update keep column visibility, medal filter, grouping; LS arrays normalized to strings on restore)

Alexander Korolev 1 mēnesi atpakaļ
vecāks
revīzija
f5144f1f03
1 mainītis faili ar 26 papildinājumiem un 13 dzēšanām
  1. 26 13
      src/report/page.html

+ 26 - 13
src/report/page.html

@@ -259,10 +259,16 @@ es.onmessage = ev => {
 };
 renderBell(); renderNotifs();
 const P = new URLSearchParams(location.search);
-const size0 = +(P.get("size") ?? 50);
+// Persistence: URL params (deep links) win; without them the last view is
+// restored from localStorage — bare reloads (server restart, new tab,
+// binary update) keep the column/settings state.
+const LS = (() => {
+  try { return JSON.parse(localStorage.getItem("report-view") || "{}"); } catch { return {}; }
+})();
+const pick = (k, dflt) => P.get(k) ?? (LS[k] ?? dflt);
+const size0 = +(pick("size", 50));
 // distinct TP values from the data, for the exact-TP filter
 const TPVALS = [...new Set(DATA.map(r => r.tp))].sort((a, b) => a - b);
-const tpParam = P.get("tp");
 for (const v of TPVALS) {
   const o = document.createElement("option");
   o.value = String(v);
@@ -270,17 +276,17 @@ for (const v of TPVALS) {
   document.getElementById("tp").appendChild(o);
 }
 const S = {
-  q: P.get("q") ?? "",
-  group: P.get("group") ?? "",
-  sort: P.get("sort") ?? "name",
-  dir: P.get("dir") ? +P.get("dir") : 1,
+  q: pick("q", ""),
+  group: pick("group", ""),
+  sort: pick("sort", "name"),
+  dir: pick("dir", 1) * 1 || 1,
   size: [25, 50, 100, 0].includes(size0) ? size0 : 50,
-  page: Math.max(0, +(P.get("page") ?? 0)),
-  hidden: new Set((P.get("hidden") ?? "title,image,port,parent").split(",").filter(Boolean)),
-  closed: new Set((P.get("closed") ?? "").split("|").map(decodeURIComponent).filter(Boolean)),
-  openRow: P.get("open") ?? null,
-  medal: P.get("medal") ?? "",
-  tp: tpParam != null && TPVALS.includes(+tpParam) ? tpParam : "",
+  page: Math.max(0, +(P.get("page") ?? 0)), // page stays URL-only (fresh view = top)
+  hidden: new Set(String(pick("hidden", "title,image,port,parent")).split(",").filter(Boolean)),
+  closed: new Set(String(pick("closed", "")).split("|").map(decodeURIComponent).filter(Boolean)),
+  openRow: pick("open", null),
+  medal: pick("medal", ""),
+  tp: TPVALS.includes(+(pick("tp", ""))) ? String(pick("tp", "")) : "",
 };
 document.getElementById("q").value = S.q;
 document.getElementById("group").value = S.group;
@@ -296,7 +302,7 @@ function syncUrl() {
   if (S.size !== 50) p.set("size", String(S.size));
   if (S.page) p.set("page", String(S.page));
   const hidden = [...S.hidden].sort();
-  if (hidden.join(",") !== ["title", "image", "port"].sort().join(",")) p.set("hidden", hidden.join(","));
+  if (hidden.join(",") !== ["title", "image", "port", "parent"].sort().join(",")) p.set("hidden", hidden.join(","));
   const closed = [...S.closed].map(encodeURIComponent);
   if (closed.length) p.set("closed", closed.join("|"));
   if (S.openRow) p.set("open", S.openRow);
@@ -304,6 +310,13 @@ function syncUrl() {
   if (S.tp) p.set("tp", S.tp);
   const qs = p.toString();
   history.replaceState(null, "", qs ? "?" + qs : location.pathname);
+  try {
+    localStorage.setItem("report-view", JSON.stringify({
+      q: S.q, group: S.group, sort: S.sort, dir: S.dir, size: S.size,
+      hidden: [...S.hidden], closed: [...S.closed], openRow: S.openRow,
+      medal: S.medal, tp: S.tp,
+    }));
+  } catch { /* private mode etc. — URL still carries the state */ }
 }
 
 const esc = s => String(s).replace(/[&<>"]/g, c => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c]));