Rework the CommonwealthOnline browser UI: restructure HTML into a nav + subpanel layout, add SVG/PNG/font assets and new sprites, and overhaul styles with a new font-face and refreshed color/spacing variables. Refactor components: tabs use a left nav list; filters extraction (renderRow) and reset focus handling; direct-connect renders into a dedicated container; server-list switched to compact row layout and adds a scroll indicator; server-details now uses a preview area and simplified preview/stats rendering. Update app logic: adjust focus zone handling (nextFocusZone), limit zones per tab, update connection status/count display, and avoid rendering details for direct-connect. Overall changes improve responsiveness, visual hierarchy, and focus/navigation behavior.
96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
(function () {
|
|
"use strict";
|
|
|
|
window.CO_ServerList = {
|
|
pingClass: function (ping) {
|
|
if (ping <= 50) return "co-ping-good";
|
|
if (ping <= 100) return "co-ping-mid";
|
|
return "co-ping-bad";
|
|
},
|
|
|
|
render: function (root, state) {
|
|
var wrap = root.querySelector(".co-server-list-wrap");
|
|
var list = root.querySelector(".co-server-list");
|
|
if (!wrap || !list) return;
|
|
|
|
wrap.className = "co-server-list-wrap" + (state.focusZone === "server-list" ? " focused" : "");
|
|
|
|
if (!state.servers.length) {
|
|
list.innerHTML = '<div class="co-empty">No servers found</div>';
|
|
CO_ServerList.updateScrollIndicator(wrap, list);
|
|
return;
|
|
}
|
|
|
|
list.innerHTML = state.servers.map(function (server, index) {
|
|
var selected = index === state.selectedServerIndex ? " selected" : "";
|
|
var fav = server.favorite ? " on" : "";
|
|
var pingCls = CO_ServerList.pingClass(server.ping);
|
|
return (
|
|
'<div class="co-server-row' + selected + '" data-index="' + index + '" data-id="' + escapeAttr(server.id) + '">' +
|
|
'<div class="co-server-row-left">' +
|
|
'<span class="co-fav' + fav + '">' + (server.favorite ? "\u2605" : "\u2606") + "</span>" +
|
|
'<span class="co-server-row-name">' + escapeHtml(server.name) + "</span>" +
|
|
"</div>" +
|
|
'<div class="co-server-row-right">' +
|
|
"<span>" + server.players + "/" + server.maxPlayers + "</span>" +
|
|
'<span class="co-ping ' + pingCls + '">' + server.ping + " ms</span>" +
|
|
"</div>" +
|
|
"</div>"
|
|
);
|
|
}).join("");
|
|
|
|
CO_ServerList.updateScrollIndicator(wrap, list);
|
|
},
|
|
|
|
updateScrollIndicator: function (wrap, list) {
|
|
var indicator = wrap && wrap.querySelector(".co-scroll-indicator");
|
|
if (!indicator || !list) return;
|
|
var hasOverflow = list.scrollHeight > list.clientHeight + 2;
|
|
indicator.classList.toggle("hidden", !hasOverflow);
|
|
},
|
|
|
|
bind: function (root, onSelect) {
|
|
var list = root.querySelector(".co-server-list");
|
|
if (!list) return;
|
|
|
|
list.addEventListener("click", function (e) {
|
|
var row = e.target.closest(".co-server-row");
|
|
if (!row) return;
|
|
onSelect(parseInt(row.getAttribute("data-index"), 10));
|
|
});
|
|
|
|
list.addEventListener("dblclick", function (e) {
|
|
var row = e.target.closest(".co-server-row");
|
|
if (!row) return;
|
|
onSelect(parseInt(row.getAttribute("data-index"), 10));
|
|
if (window.CO_App && window.CO_App.joinSelected) {
|
|
window.CO_App.joinSelected();
|
|
}
|
|
});
|
|
},
|
|
|
|
scrollToSelected: function (root, index) {
|
|
var list = root.querySelector(".co-server-list");
|
|
var row = list && list.querySelector('.co-server-row[data-index="' + index + '"]');
|
|
if (row) {
|
|
row.scrollIntoView({ block: "nearest" });
|
|
}
|
|
var wrap = root.querySelector(".co-server-list-wrap");
|
|
if (wrap && list) {
|
|
CO_ServerList.updateScrollIndicator(wrap, list);
|
|
}
|
|
}
|
|
};
|
|
|
|
function escapeHtml(value) {
|
|
return String(value)
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">");
|
|
}
|
|
|
|
function escapeAttr(value) {
|
|
return String(value).replace(/"/g, """);
|
|
}
|
|
})();
|