URL in scoreboard (configurable)

This commit is contained in:
Neale Pickett 2023-09-15 16:09:08 -06:00
parent d18de0fe8b
commit bb4859e7a9
9 changed files with 68 additions and 50 deletions

View File

@ -113,36 +113,7 @@ input:invalid {
cursor: help; cursor: help;
} }
/** Scoreboard */ /** Development mode information */
#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;}
.debug { .debug {
overflow: auto; overflow: auto;
padding: 1em; padding: 1em;
@ -203,11 +174,9 @@ li[draggable] {
} }
@media (prefers-color-scheme: light) { @media (prefers-color-scheme: light) {
/* /* We uses the alpha channel to apply hue tinting to elements, to get a
* This 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 * similar effect in light or dark mode. That means there aren't a whole lot of
* things to change between light and dark mode. * things to change between light and dark mode.
*
*/ */
body { body {
background-color: #b9cbd8; background-color: #b9cbd8;

View File

@ -5,6 +5,9 @@ const Millisecond = 1
const Second = Millisecond * 1000 const Second = Millisecond * 1000
const Minute = Second * 60 const Minute = Second * 60
/** URL to the top of this MOTH server */
const BaseURL = new URL(".", location)
/** /**
* Display a transient message to the user. * Display a transient message to the user.
* *
@ -53,11 +56,29 @@ function Truthy(s) {
return true return true
} }
/**
* Fetch the configuration object for this theme.
*
* @returns {Promise.<Object>}
*/
async function Config() {
let resp = await fetch(
new URL("config.json", BaseURL),
{
cache: "no-cache"
},
)
return resp.json()
}
export { export {
Millisecond, Millisecond,
Second, Second,
Minute, Minute,
BaseURL,
Toast, Toast,
WhenDOMLoaded, WhenDOMLoaded,
Truthy, Truthy,
Config,
} }

View File

@ -1,4 +1,5 @@
{ {
"TrackSolved": true, "TrackSolved": true,
"URLInScoreboard": true,
"__sentry__": "this is here so you don't have to remember to take the comma off the last item" "__sentry__": "this is here so you don't have to remember to take the comma off the last item"
} }

View File

@ -6,7 +6,6 @@ import * as common from "./common.mjs"
class App { class App {
constructor(basePath=".") { constructor(basePath=".") {
this.configURL = new URL("config.json", location)
this.config = {} this.config = {}
this.server = new moth.Server(basePath) this.server = new moth.Server(basePath)
@ -74,8 +73,7 @@ class App {
* load, since configuration should (hopefully) change less frequently. * load, since configuration should (hopefully) change less frequently.
*/ */
async UpdateConfig() { async UpdateConfig() {
let resp = await fetch(this.configURL) this.config = await common.Config()
this.config = await resp.json()
} }
/** /**
@ -150,7 +148,7 @@ class App {
for (let puzzle of this.state.Puzzles(cat)) { for (let puzzle of this.state.Puzzles(cat)) {
let i = l.appendChild(document.createElement("li")) 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}` url.hash = `${puzzle.Category}:${puzzle.Points}`
let a = i.appendChild(document.createElement("a")) let a = i.appendChild(document.createElement("a"))
a.textContent = puzzle.Points a.textContent = puzzle.Points

View File

@ -542,6 +542,7 @@ class Server {
return fetch(url, { return fetch(url, {
method: "POST", method: "POST",
body, body,
cache: "no-cache",
}) })
} }

View File

@ -131,7 +131,7 @@ function writeObject(e, obj) {
*/ */
async function loadPuzzle(category, points) { async function loadPuzzle(category, points) {
console.groupCollapsed("Loading puzzle:", 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 // Tell user we're loading
puzzleElement().appendChild(document.createElement("progress")) 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 // Make all links absolute, because we're going to be changing the base URL
for (let e of document.querySelectorAll("[href]")) { 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] || "" let hashpart = location.hash.split("#")[1] || ""

View File

@ -47,6 +47,18 @@
text-align: center; 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 { .qrcode {
width: 30vw; width: 30vw;
} }
@ -60,23 +72,34 @@
max-width: 40%; max-width: 40%;
} }
/** Scoreboard */
#rankings { #rankings {
width: 100%; width: 100%;
position: relative; position: relative;
background-color: rgba(0, 0, 0, 0.8); 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 { #rankings span {
font-size: 75%; font-size: 75%;
display: inline-block; display: inline-block;
overflow: hidden; overflow: hidden;
height: 1.7em; height: 1.4em;
} }
#rankings span.teamname { #rankings span.teamname {
height: auto;
font-size: inherit; font-size: inherit;
color: white; color: white;
text-shadow: 0 0 3px black; background-color: #000e;
opacity: 0.8; border-radius: 3px;
position: absolute; position: absolute;
right: 0.2em; right: 0.2em;
} }

View File

@ -10,9 +10,8 @@
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@0.2.1"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@0.2.1"></script>
<script type="module" src="scoreboard.mjs"></script> <script type="module" src="scoreboard.mjs"></script>
</head> </head>
<body class="wide"> <body>
<section class="rotate"> <div id="rankings"></div>
<div id="rankings"></div> <div class="location"></div>
</section>
</body> </body>
</html> </html>

View File

@ -2,8 +2,8 @@ import * as moth from "./moth.mjs"
import * as common from "./common.mjs" import * as common from "./common.mjs"
const server = new moth.Server(".") const server = new moth.Server(".")
const ReplayDuration = 3 * common.Second const ReplayDuration = 0.3 * common.Second
const MaxFrameRate = 24 const MaxFrameRate = 60
/** Don't let any team's score exceed this percentage width */ /** Don't let any team's score exceed this percentage width */
const MaxScoreWidth = 95 const MaxScoreWidth = 95
@ -23,6 +23,12 @@ function sleep(timeout) {
* The update is animated, because I think that looks cool. * The update is animated, because I think that looks cool.
*/ */
async function update() { 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 state = await server.GetState()
let rankingsElement = document.querySelector("#rankings") let rankingsElement = document.querySelector("#rankings")
let logSize = state.PointsLog.length let logSize = state.PointsLog.length