2023-09-13 18:52:52 -06:00
|
|
|
/**
|
|
|
|
* Common functionality
|
|
|
|
*/
|
|
|
|
const Millisecond = 1
|
|
|
|
const Second = Millisecond * 1000
|
|
|
|
const Minute = Second * 60
|
|
|
|
|
2023-09-15 16:09:08 -06:00
|
|
|
/** URL to the top of this MOTH server */
|
|
|
|
const BaseURL = new URL(".", location)
|
|
|
|
|
2024-04-08 14:38:08 -06:00
|
|
|
/** A channel to monitor for state updates (or to notify of state updates) */
|
|
|
|
const StateUpdateChannel = new BroadcastChannel("StateUpdate")
|
|
|
|
|
2023-09-13 18:52:52 -06:00
|
|
|
/**
|
|
|
|
* Display a transient message to the user.
|
|
|
|
*
|
|
|
|
* @param {String} message Message to display
|
|
|
|
* @param {Number} timeout How long before removing this message
|
|
|
|
*/
|
|
|
|
function Toast(message, timeout=5*Second) {
|
|
|
|
console.info(message)
|
|
|
|
for (let toasts of document.querySelectorAll(".toasts")) {
|
|
|
|
let p = toasts.appendChild(document.createElement("p"))
|
|
|
|
p.classList.add("toast")
|
|
|
|
p.textContent = message
|
|
|
|
setTimeout(() => p.remove(), timeout)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run a function when the DOM has been loaded.
|
|
|
|
*
|
|
|
|
* @param {function():void} cb Callback function
|
|
|
|
*/
|
|
|
|
function WhenDOMLoaded(cb) {
|
|
|
|
if (document.readyState === "loading") {
|
|
|
|
document.addEventListener("DOMContentLoaded", cb)
|
|
|
|
} else {
|
|
|
|
cb()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-14 17:42:02 -06:00
|
|
|
/**
|
|
|
|
* Interprets a String as a Boolean.
|
|
|
|
*
|
|
|
|
* Values like "no" or "disabled" to mean false here.
|
|
|
|
*
|
|
|
|
* @param {String} s
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
2024-04-17 17:17:58 -06:00
|
|
|
function StringTruthy(s) {
|
2023-09-14 17:42:02 -06:00
|
|
|
switch (s.toLowerCase()) {
|
|
|
|
case "disabled":
|
|
|
|
case "no":
|
|
|
|
case "off":
|
|
|
|
case "false":
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2023-09-15 16:09:08 -06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch the configuration object for this theme.
|
|
|
|
*
|
|
|
|
* @returns {Promise.<Object>}
|
|
|
|
*/
|
|
|
|
async function Config() {
|
2024-04-17 17:17:58 -06:00
|
|
|
let obj = {}
|
|
|
|
try {
|
|
|
|
let resp = await fetch(
|
2024-04-17 17:31:17 -06:00
|
|
|
new URL("config.json", BaseURL),
|
2024-04-17 17:17:58 -06:00
|
|
|
{
|
|
|
|
cache: "no-cache"
|
|
|
|
},
|
|
|
|
)
|
|
|
|
obj = await resp.json()
|
|
|
|
}
|
|
|
|
catch(err) {
|
|
|
|
obj = {}
|
|
|
|
}
|
|
|
|
return obj
|
2023-09-15 16:09:08 -06:00
|
|
|
}
|
|
|
|
|
2023-09-13 18:52:52 -06:00
|
|
|
export {
|
|
|
|
Millisecond,
|
|
|
|
Second,
|
|
|
|
Minute,
|
2024-04-08 14:38:08 -06:00
|
|
|
StateUpdateChannel,
|
2023-09-15 16:09:08 -06:00
|
|
|
BaseURL,
|
2023-09-13 18:52:52 -06:00
|
|
|
Toast,
|
|
|
|
WhenDOMLoaded,
|
2024-04-17 17:17:58 -06:00
|
|
|
StringTruthy,
|
2023-09-15 16:09:08 -06:00
|
|
|
Config,
|
2023-09-13 18:52:52 -06:00
|
|
|
}
|