mirror of https://github.com/dirtbags/moth.git
URL in scoreboard (configurable)
This commit is contained in:
parent
d18de0fe8b
commit
bb4859e7a9
|
@ -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;
|
||||
|
|
|
@ -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.<Object>}
|
||||
*/
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -542,6 +542,7 @@ class Server {
|
|||
return fetch(url, {
|
||||
method: "POST",
|
||||
body,
|
||||
cache: "no-cache",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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] || ""
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@0.2.1"></script>
|
||||
<script type="module" src="scoreboard.mjs"></script>
|
||||
</head>
|
||||
<body class="wide">
|
||||
<section class="rotate">
|
||||
<div id="rankings"></div>
|
||||
</section>
|
||||
<body>
|
||||
<div id="rankings"></div>
|
||||
<div class="location"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue