Files
Commonwealth-Online-Public/ui/views/CommonwealthOnline/browser/components/tabs.js
T
andrew 9ceb6601ae Add LAN discovery and Local servers UI
Adds LAN server discovery and a Local tab in the multiplayer UI so clients can find relays on the same LAN. Introduces a new F4T::LanDiscovery module (plugin/include/F4TLanDiscovery.h, plugin/src/F4TLanDiscovery.cpp) that probes LAN hosts via UDP discover (port 7778) and TCP welcome fallback (port 7777). Server-side support includes a UDP responder (server/lan_discovery.py) and integration in server_core.py to start/stop discovery.

Plugin changes (F4TServerBrowserBridge/Data) add background scanning, dispatch results to the game thread, new local-server storage and events (scanLocalServers, localServersUpdated, localScanStarted/localScanFinished), and small join/recent handling updates. UI changes (ui/.../app.js and components) add localServers state, scanning UX, Recent persistence (localStorage), and join logic for local/direct entries. Docs updated (docs/protocol.md, docs/dev-log.md, server/README.md) and build script links iphlpapi. Also removes two unused exported sprite PNGs.
2026-06-22 15:53:17 +12:00

46 lines
1.3 KiB
JavaScript

(function () {
"use strict";
var TAB_ORDER = ["direct-connect", "server-browser", "local", "favorites", "recent"];
window.CO_Tabs = {
TAB_ORDER: TAB_ORDER,
render: function (root, state) {
var navEl = root.querySelector(".co-nav-list");
if (!navEl) return;
var labels = {
"direct-connect": "Direct Connect",
"server-browser": "Browse",
local: "Local",
favorites: "Favorites",
recent: "Recent"
};
navEl.innerHTML = TAB_ORDER.map(function (tabId, index) {
var active = state.activeTab === tabId ? " active" : "";
var focused = state.focusZone === "tabs" && state.selectedTabIndex === index ? " focused" : "";
return (
'<button type="button" class="co-nav-item' + active + focused + '" data-tab="' + tabId + '" data-index="' + index + '">' +
labels[tabId] +
"</button>"
);
}).join("");
navEl.className = "co-nav-list" + (state.focusZone === "tabs" ? " focused" : "");
},
bind: function (root, onTabClick) {
var navEl = root.querySelector(".co-nav-list");
if (!navEl) return;
navEl.addEventListener("click", function (e) {
var btn = e.target.closest(".co-nav-item");
if (!btn) return;
onTabClick(btn.getAttribute("data-tab"));
});
}
};
})();