91 lines
2.9 KiB
JavaScript
91 lines
2.9 KiB
JavaScript
(() => {
|
|
const qs = (s, r = document) => r.querySelector;
|
|
const qsa = (s, r = document) => Array.from(r.querySelectorAll(s));
|
|
|
|
async function apiAccount() {
|
|
const res = await fetch("/api/account", {
|
|
credentials: "same-origin",
|
|
headers: { "Accept": "application/json" },
|
|
});
|
|
|
|
const text = await res.text();
|
|
let data = {};
|
|
try {
|
|
data = text ? JSON.parse(text) : {};
|
|
} catch {
|
|
return { save_sync: { status: "unknown", message: "Save sync status unavailable." } };
|
|
}
|
|
|
|
if (!res.ok) {
|
|
return { save_sync: { status: "unknown", message: data.error || data.message || "Save sync status unavailable." } };
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function value(obj, paths, fallback = "") {
|
|
for (const path of paths) {
|
|
let cur = obj;
|
|
let ok = true;
|
|
for (const part of path.split(".")) {
|
|
if (!cur || !(part in cur)) {
|
|
ok = false;
|
|
break;
|
|
}
|
|
cur = cur[part];
|
|
}
|
|
if (ok && cur !== undefined && cur !== null && cur !== "") return cur;
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
function normalizeStatus(s) {
|
|
const v = String(s || "").toLowerCase();
|
|
if (["current", "synced", "ok", "ready"].includes(v)) return "Current";
|
|
if (["pending", "syncing"].includes(v)) return "Pending";
|
|
if (["missing", "unknown", "error"].includes(v)) return "Unknown";
|
|
return s || "Unknown";
|
|
}
|
|
|
|
function dot(status) {
|
|
return normalizeStatus(status) === "Current" ? '<span class="ready-dot"></span> ' : "";
|
|
}
|
|
|
|
function ensureMessage(card) {
|
|
let msg = document.getElementById("save-sync-message");
|
|
if (!msg) {
|
|
msg = document.createElement("p");
|
|
msg.id = "save-sync-message";
|
|
msg.className = "save-sync-message fine-print";
|
|
card.appendChild(msg);
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
function render(saveSync) {
|
|
const card = document.querySelector(".save-sync-card");
|
|
if (!card) return;
|
|
|
|
const rows = Array.from(card.querySelectorAll(".region-row"));
|
|
const us = value(saveSync, ["regions.us.status", "us.status", "us_status"], "Unknown");
|
|
const eu = value(saveSync, ["regions.eu.status", "eu.status", "eu_status"], "Unknown");
|
|
const last = value(saveSync, ["last_sync", "last_synced_at", "updated_at"], "Unknown");
|
|
|
|
if (rows[0]) rows[0].querySelector("strong").innerHTML = `${dot(us)}${normalizeStatus(us)}`;
|
|
if (rows[1]) rows[1].querySelector("strong").innerHTML = `${dot(eu)}${normalizeStatus(eu)}`;
|
|
if (rows[2]) rows[2].querySelector("strong").textContent = last;
|
|
|
|
const status = String(saveSync?.status || "").toLowerCase();
|
|
const fallback = status === "synced" || status === "current"
|
|
? ""
|
|
: "Save sync status unavailable.";
|
|
|
|
ensureMessage(card).textContent = saveSync?.message || fallback;
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", async () => {
|
|
const data = await apiAccount();
|
|
render(data.save_sync || {});
|
|
});
|
|
})();
|