Files
2026-06-14 01:07:03 -04:00

55 lines
1.7 KiB
JavaScript

(() => {
const list = document.querySelector(".status-list");
if (!list) return;
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (ch) => ({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&#39;",
}[ch]));
const players = (value) => {
const n = Number(value || 0);
return `${n.toLocaleString()} ${n === 1 ? "Player" : "Players"}`;
};
const render = (data) => {
const servers = Array.isArray(data?.servers) ? data.servers : [];
if (!servers.length) return;
list.classList.add("status-list--regions");
list.innerHTML = servers.map((server) => `
<div class="status-region" role="group" aria-label="${esc(server.label)} player counts">
<div class="status-row status-parent status-server" role="listitem">
<span>${esc(server.label)}</span><span>${players(server.players)}</span>
</div>
${(server.ships || []).map((ship) => `
<div class="status-row status-parent status-ship" role="listitem">
<span>${esc(ship.label)}</span><span></span>
</div>
${(ship.rows || []).map((row) => `
<div class="status-row status-child" role="listitem">
<span>${esc(row.label)}</span><span>${players(row.players)}</span>
</div>
`).join("")}
`).join("")}
</div>
`).join("");
};
const loadStatus = (url) => fetch(url, { cache: "no-store" })
.then((res) => {
if (!res.ok) {
throw new Error(`status ${res.status}`);
}
return res.json();
});
loadStatus(`/server-status.json?ts=${Date.now()}`)
.catch(() => loadStatus("/api/server-status"))
.then((data) => data && render(data))
.catch(() => {});
})();