From bb4859e7a96c382eea70e8bf7cfb9ec7ec275c90 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 15 Sep 2023 16:09:08 -0600 Subject: [PATCH] URL in scoreboard (configurable) --- theme/basic.css | 35 ++--------------------------------- theme/common.mjs | 21 +++++++++++++++++++++ theme/config.json | 1 + theme/index.mjs | 6 ++---- theme/moth.mjs | 1 + theme/puzzle.mjs | 4 ++-- theme/scoreboard.css | 33 ++++++++++++++++++++++++++++----- theme/scoreboard.html | 7 +++---- theme/scoreboard.mjs | 10 ++++++++-- 9 files changed, 68 insertions(+), 50 deletions(-) diff --git a/theme/basic.css b/theme/basic.css index d67ad72..667e99d 100644 --- a/theme/basic.css +++ b/theme/basic.css @@ -113,36 +113,7 @@ input:invalid { cursor: help; } -/** Scoreboard */ -#rankings { - width: 100%; - position: relative; -} -#rankings div:nth-child(6n){ - background-color: #8881; -} -#rankings div:nth-child(6n+3) { - background-color: #0f01; -} -#rankings span.teamname { - height: auto; - font-size: inherit; - color: white; - background-color: #000e; - border-radius: 3px; - position: absolute; - right: 0.2em; -} -#rankings div * {white-space: nowrap;} -.cat0, .cat8, .cat16 {background-color: #a6cee3; color: black;} -.cat1, .cat9, .cat17 {background-color: #1f78b4; color: white;} -.cat2, .cat10, .cat18 {background-color: #b2df8a; color: black;} -.cat3, .cat11, .cat19 {background-color: #33a02c; color: white;} -.cat4, .cat12, .cat20 {background-color: #fb9a99; color: black;} -.cat5, .cat13, .cat21 {background-color: #e31a1c; color: white;} -.cat6, .cat14, .cat22 {background-color: #fdbf6f; color: black;} -.cat7, .cat15, .cat23 {background-color: #ff7f00; color: black;} - +/** Development mode information */ .debug { overflow: auto; padding: 1em; @@ -203,11 +174,9 @@ li[draggable] { } @media (prefers-color-scheme: light) { - /* - * This uses the alpha channel to apply hue tinting to elements, to get a + /* We uses the alpha channel to apply hue tinting to elements, to get a * similar effect in light or dark mode. That means there aren't a whole lot of * things to change between light and dark mode. - * */ body { background-color: #b9cbd8; diff --git a/theme/common.mjs b/theme/common.mjs index c797475..c9e49a8 100644 --- a/theme/common.mjs +++ b/theme/common.mjs @@ -5,6 +5,9 @@ const Millisecond = 1 const Second = Millisecond * 1000 const Minute = Second * 60 +/** URL to the top of this MOTH server */ +const BaseURL = new URL(".", location) + /** * Display a transient message to the user. * @@ -53,11 +56,29 @@ function Truthy(s) { return true } + +/** + * Fetch the configuration object for this theme. + * + * @returns {Promise.} + */ +async function Config() { + let resp = await fetch( + new URL("config.json", BaseURL), + { + cache: "no-cache" + }, + ) + return resp.json() +} + export { Millisecond, Second, Minute, + BaseURL, Toast, WhenDOMLoaded, Truthy, + Config, } diff --git a/theme/config.json b/theme/config.json index 9f39211..1d5a0a1 100644 --- a/theme/config.json +++ b/theme/config.json @@ -1,4 +1,5 @@ { "TrackSolved": true, + "URLInScoreboard": true, "__sentry__": "this is here so you don't have to remember to take the comma off the last item" } \ No newline at end of file diff --git a/theme/index.mjs b/theme/index.mjs index 9bc79a2..e9de612 100644 --- a/theme/index.mjs +++ b/theme/index.mjs @@ -6,7 +6,6 @@ import * as common from "./common.mjs" class App { constructor(basePath=".") { - this.configURL = new URL("config.json", location) this.config = {} this.server = new moth.Server(basePath) @@ -74,8 +73,7 @@ class App { * load, since configuration should (hopefully) change less frequently. */ async UpdateConfig() { - let resp = await fetch(this.configURL) - this.config = await resp.json() + this.config = await common.Config() } /** @@ -150,7 +148,7 @@ class App { for (let puzzle of this.state.Puzzles(cat)) { let i = l.appendChild(document.createElement("li")) - let url = new URL("puzzle.html", window.location) + let url = new URL("puzzle.html", common.BaseURL) url.hash = `${puzzle.Category}:${puzzle.Points}` let a = i.appendChild(document.createElement("a")) a.textContent = puzzle.Points diff --git a/theme/moth.mjs b/theme/moth.mjs index a617753..c1db74b 100644 --- a/theme/moth.mjs +++ b/theme/moth.mjs @@ -542,6 +542,7 @@ class Server { return fetch(url, { method: "POST", body, + cache: "no-cache", }) } diff --git a/theme/puzzle.mjs b/theme/puzzle.mjs index c53b6a1..6f886d5 100644 --- a/theme/puzzle.mjs +++ b/theme/puzzle.mjs @@ -131,7 +131,7 @@ function writeObject(e, obj) { */ async function loadPuzzle(category, points) { console.groupCollapsed("Loading puzzle:", category, points) - let contentBase = new URL(`content/${category}/${points}/`, location) + let contentBase = new URL(`content/${category}/${points}/`, common.BaseURL) // Tell user we're loading puzzleElement().appendChild(document.createElement("progress")) @@ -209,7 +209,7 @@ async function init() { // Make all links absolute, because we're going to be changing the base URL for (let e of document.querySelectorAll("[href]")) { - e.href = new URL(e.href, location) + e.href = new URL(e.href, common.BaseURL) } let hashpart = location.hash.split("#")[1] || "" diff --git a/theme/scoreboard.css b/theme/scoreboard.css index 470e72d..a3f55d1 100644 --- a/theme/scoreboard.css +++ b/theme/scoreboard.css @@ -47,6 +47,18 @@ text-align: center; } +.location { + color: #acf; + background-color: #0008; + position: fixed; + right: 30vw; + bottom: 0; + padding: 1em; + margin: 0; + font-size: 1.2rem; + font-weight:bold; + text-decoration: underline; +} .qrcode { width: 30vw; } @@ -60,23 +72,34 @@ max-width: 40%; } +/** Scoreboard */ #rankings { width: 100%; - position: relative; - background-color: rgba(0, 0, 0, 0.8); + position: relative; + background-color: #000c; +} +#rankings div { + height: 1.4rem; +} +#rankings div:nth-child(6n){ + background-color: #ccc1; +} +#rankings div:nth-child(6n+3) { + background-color: #0f01; } #rankings span { font-size: 75%; display: inline-block; overflow: hidden; - height: 1.7em; + height: 1.4em; } #rankings span.teamname { + height: auto; font-size: inherit; color: white; - text-shadow: 0 0 3px black; - opacity: 0.8; + background-color: #000e; + border-radius: 3px; position: absolute; right: 0.2em; } diff --git a/theme/scoreboard.html b/theme/scoreboard.html index 74af715..1e14424 100644 --- a/theme/scoreboard.html +++ b/theme/scoreboard.html @@ -10,9 +10,8 @@ - -
-
-
+ +
+
diff --git a/theme/scoreboard.mjs b/theme/scoreboard.mjs index 8f7ce6f..5d2e161 100644 --- a/theme/scoreboard.mjs +++ b/theme/scoreboard.mjs @@ -2,8 +2,8 @@ import * as moth from "./moth.mjs" import * as common from "./common.mjs" const server = new moth.Server(".") -const ReplayDuration = 3 * common.Second -const MaxFrameRate = 24 +const ReplayDuration = 0.3 * common.Second +const MaxFrameRate = 60 /** Don't let any team's score exceed this percentage width */ const MaxScoreWidth = 95 @@ -23,6 +23,12 @@ function sleep(timeout) { * The update is animated, because I think that looks cool. */ async function update() { + let config = await common.Config() + for (let e of document.querySelectorAll(".location")) { + e.textContent = common.BaseURL + e.classList.toggle("hidden", !config.URLInScoreboard) + } + let state = await server.GetState() let rankingsElement = document.querySelector("#rankings") let logSize = state.PointsLog.length