From bbe07c2788b00711e011f7805e14fa0933bf2d73 Mon Sep 17 00:00:00 2001 From: Leonardo Bishop Date: Fri, 13 Feb 2026 17:07:34 +0000 Subject: Initial commit --- assets/presenter.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 assets/presenter.js (limited to 'assets/presenter.js') diff --git a/assets/presenter.js b/assets/presenter.js new file mode 100644 index 0000000..bfe41b8 --- /dev/null +++ b/assets/presenter.js @@ -0,0 +1,70 @@ +const overlayEl = document.getElementById("solve-overlay"); +const firstBloodEl = document.getElementById("solve-first"); +const teamEl = document.getElementById("solve-team"); +const challengeEl = document.getElementById("solve-challenge"); +const valueEl = document.getElementById("solve-value"); +const scoreboardFrameEl = document.getElementById("scoreboard-frame"); + +const solveQueue = []; +let isShowingOverlay = false; + +function pollNextSolve() { + if (isShowingOverlay) { + return; + } + + if (solveQueue.length > 0) { + const nextSolve = solveQueue.shift(); + showSolve(nextSolve.team, nextSolve.challenge, nextSolve.value, nextSolve.first); + } +} + +function showSolve(team, challenge, value, first) { + teamEl.textContent = team; + teamEl.setAttribute("data-text", team); + challengeEl.textContent = challenge; + challengeEl.setAttribute("data-text", challenge); + valueEl.textContent = `+${value}`; + valueEl.setAttribute("data-text", `+${value}`); + + if (first) { + firstBloodEl.classList.add("visible"); + } + + overlayEl.classList.add("visible"); + isShowingOverlay = true; + + setTimeout(() => { + overlayEl.classList.remove("visible"); + firstBloodEl.classList.remove("visible"); + + setTimeout(() => { + isShowingOverlay = false; + pollNextSolve(); + }, 1000); + }, first ? 8500 : 4500); +} + +let reloadTimeout = null; + +function reloadScoreboard(delay = 1000) { + if (reloadTimeout) { + clearTimeout(reloadTimeout); + } + + reloadTimeout = setTimeout(() => { + scoreboardFrameEl.src = "/scoreboard?ts=" + Date.now(); + reloadTimeout = null; + }, delay); +} + +const es = new EventSource("/presenter/events"); + +es.onmessage = (e) => { + const data = JSON.parse(e.data); + if (data.type === "solve") { + solveQueue.push(data); + reloadScoreboard(); + pollNextSolve(); + } +}; -- cgit v1.2.3-70-g09d2