47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
(() => {
|
|
const list = document.querySelector(".status-list");
|
|
if (!list) return;
|
|
|
|
const esc = (value) => String(value ?? "").replace(/[&<>"']/g, (ch) => ({
|
|
"&": "&",
|
|
"<": "<",
|
|
">": ">",
|
|
"\"": """,
|
|
"'": "'",
|
|
}[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("");
|
|
};
|
|
|
|
fetch("/api/server-status", { cache: "no-store" })
|
|
.then((res) => res.ok ? res.json() : null)
|
|
.then((data) => data && render(data))
|
|
.catch(() => {});
|
|
})();
|