diff --git a/public/buzzer.js b/public/buzzer.js index 2f4dd6d..45bf3f7 100644 --- a/public/buzzer.js +++ b/public/buzzer.js @@ -31,11 +31,8 @@ const buzzer_key = { name: "space bar", } -let socket, - conn, - clients = [], - me, - session_key +let conn, + clients = [] function hide(e) { e = isString(e) ? q(`#${e}`) : e @@ -218,6 +215,7 @@ function set_name(name) { } function setup_ws() { + let me, session_key const sid = session_id() const credentials = { id: storage["my_uid"], key: storage["my_key"] } conn = new Connection() diff --git a/public/matrix.css b/public/matrix.css index a0c5339..ac6cdfa 100644 --- a/public/matrix.css +++ b/public/matrix.css @@ -37,4 +37,4 @@ body { } .card.hidden { visibility: hidden; -} \ No newline at end of file +} diff --git a/public/monitor.css b/public/monitor.css index 2be28d9..78a3cc4 100644 --- a/public/monitor.css +++ b/public/monitor.css @@ -38,6 +38,10 @@ iframe { right: 0.2em; text-align: right; font-size: 36px; + transition: font-size 0.2s cubic-bezier(0.45, 1.07, 0.27, 1.55); +} +.points.big { + font-size: 80px; } .points.bg { -webkit-text-stroke: 10px var(--main-bg-color); diff --git a/public/monitor.html b/public/monitor.html index aeac6f4..24c3bf1 100644 --- a/public/monitor.html +++ b/public/monitor.html @@ -11,13 +11,13 @@ diff --git a/public/monitor.js b/public/monitor.js index ef58d13..5465cb2 100644 --- a/public/monitor.js +++ b/public/monitor.js @@ -5,7 +5,6 @@ const location = document.location const performance = window.performance import { - clear, Connection, ms_ns, node, @@ -15,9 +14,7 @@ import { session_url, } from "./shared.js" -let conn, - clients = {}, - me +let conn function setup_url() { const sid = session_id() || "" @@ -60,20 +57,38 @@ function test_prettynum() { test_prettynum() const player_list = q("#players") -function redraw_clients(me, clients) { +function _redraw_clients(me, clients) { if (!me) { return } - clear(player_list) + + // Remove all gone players. + const client_ids = clients.map((c) => "" + c.id) + for (const el of player_list.querySelectorAll(".player")) { + if (!client_ids.includes(el.dataset.cid)) { + el.remove() + } + } + const player_tpl = q("template#player").content.firstElementChild - for (const c of Object.values(clients)) { + for (const c of clients) { if (c.id === me.id) { continue } - const player_el = node(player_tpl.cloneNode(true), { - data: { cid: c.id }, - appendTo: player_list, - }) + let player_el = q(`.player[data-cid='${c.id}']`) + if (!player_el) { + player_el = node(player_tpl.cloneNode(true), { + data: { cid: c.id }, + appendTo: player_list, + }) + } else if (q(".points", player_el).textContent !== prettynum(c.points)) { + q(".points.fg", player_el).classList.add("big") + q(".points.bg", player_el).classList.add("big") + setTimeout(() => { + q(".points.fg", player_el).classList.remove("big") + q(".points.bg", player_el).classList.remove("big") + }, 200) + } q(".name", player_el).textContent = c.name q(".points.fg", player_el).textContent = prettynum(c.points) q(".points.bg", player_el).textContent = prettynum(c.points) @@ -81,6 +96,21 @@ function redraw_clients(me, clients) { } } +function debounce(func, ms) { + let timer + return function (...args) { + if (timer) { + clearTimeout(timer) + } + timer = setTimeout(() => { + timer = null + func(...args) + }, ms) + } +} + +const redraw_clients = debounce(_redraw_clients, 200) + let highlighted = false function highlight(client_id, until_ns) { if (highlighted) { @@ -105,6 +135,8 @@ function highlight(client_id, until_ns) { } function setup_ws() { + let clients = [], + me const sid = session_id() conn = new Connection() conn.on("helo", () => { @@ -121,11 +153,16 @@ function setup_ws() { highlight(client_id, until_ns) }) conn.on("clients", ({ value }) => { - clients = Object.fromEntries(value.clients.map((c) => [c.id, c])) + clients = value.clients redraw_clients(me, clients) }) conn.on("client", ({ value: { client } }) => { - clients[client.id] = client + const idx = clients.findIndex((c) => c.id === client.id) + if (idx >= 0) { + clients[idx] = client + } else { + clients.push(client) + } redraw_clients(me, clients) }) conn.on("control", ({ value }) => {