import { createSmoothRenderer } from "./shared.js"; const socket = io(); const display = document.getElementById("display"); const clientCountEl = document.getElementById("clientCount"); const tableBody = document.getElementById("clientsTable"); const colorPicker = document.getElementById("colorPicker"); const blackoutBtn = document.getElementById("blackout"); const wakeBtn = document.getElementById("wake"); const renderer = createSmoothRenderer({ setText: (t) => (display.textContent = t), }); socket.on("connect", () => { // Identify as admin to receive client list updates socket.emit("admin:join"); }); // Stopwatch state (also brings color & blackout) socket.on("state", (s) => { renderer.applyServerState(s); // Color reflection if (s.color) { display.style.color = s.color; if (colorPicker && colorPicker.value.toLowerCase() !== s.color.toLowerCase()) { colorPicker.value = s.color; } } // Blackout button label reflect state if (typeof s.blackout === "boolean" && blackoutBtn) { blackoutBtn.textContent = s.blackout ? "Show Clock" : "Blackout"; blackoutBtn.style.background = s.blackout ? "#550000" : "#111"; } }); // Render clients table socket.on("clients:list", ({ count, clients }) => { clientCountEl.textContent = count; if (!clients || clients.length === 0) { tableBody.innerHTML = `No clients connected yet.`; return; } const rows = clients.map((c) => { const since = new Date(c.connectedAt).toLocaleTimeString(); const lat = (c.latencyMs == null) ? "—" : `${c.latencyMs} ms`; const shortId = c.id.slice(0, 6); const ua = (c.ua || "").slice(0, 80); const url = (c.url || "").slice(0, 64); return ` ${shortId} ${c.ip} ${lat} ${url} ${ua} ${since} `; }); tableBody.innerHTML = rows.join(""); }); // Admin buttons document.getElementById("start").onclick = () => socket.emit("cmd:start"); document.getElementById("stop").onclick = () => socket.emit("cmd:stop"); document.getElementById("reset").onclick = () => socket.emit("cmd:reset"); // Color (debounced a bit) let colorDebounce; colorPicker?.addEventListener("input", (e) => { const hex = String(e.target.value || "").trim(); clearTimeout(colorDebounce); colorDebounce = setTimeout(() => { socket.emit("cmd:color", hex); }, 50); }); // Blackout toggle let blackoutEnabled = false; blackoutBtn?.addEventListener("click", () => { blackoutEnabled = !blackoutEnabled; socket.emit("cmd:blackout", blackoutEnabled); blackoutBtn.textContent = blackoutEnabled ? "Show Clock" : "Blackout"; blackoutBtn.style.background = blackoutEnabled ? "#550000" : "#111"; }); // 🚀 Wake button wakeBtn?.addEventListener("click", () => { socket.emit("cmd:wake"); // Visual feedback pulse wakeBtn.style.background = "#008800"; setTimeout(() => (wakeBtn.style.background = "#004400"), 300); });