diff --git a/theme/common.mjs b/theme/common.mjs index c9e49a8..69e752e 100644 --- a/theme/common.mjs +++ b/theme/common.mjs @@ -8,6 +8,9 @@ const Minute = Second * 60 /** URL to the top of this MOTH server */ const BaseURL = new URL(".", location) +/** A channel to monitor for state updates (or to notify of state updates) */ +const StateUpdateChannel = new BroadcastChannel("StateUpdate") + /** * Display a transient message to the user. * @@ -76,6 +79,7 @@ export { Millisecond, Second, Minute, + StateUpdateChannel, BaseURL, Toast, WhenDOMLoaded, diff --git a/theme/index.mjs b/theme/index.mjs index 923b020..d409547 100644 --- a/theme/index.mjs +++ b/theme/index.mjs @@ -17,6 +17,11 @@ class App { e.addEventListener("click", () => this.Logout()) } + common.StateUpdateChannel.addEventListener("message", () => { + // Give mothd time to catch up + setTimeout(() => this.UpdateState(), 1/2 * common.Second) + }) + setInterval(() => this.UpdateState(), common.Minute/3) setInterval(() => this.UpdateConfig(), common.Minute* 5) diff --git a/theme/puzzle.mjs b/theme/puzzle.mjs index f29a809..1738c24 100644 --- a/theme/puzzle.mjs +++ b/theme/puzzle.mjs @@ -28,6 +28,8 @@ async function formSubmitHandler(event) { try { message = await window.app.puzzle.SubmitAnswer(proposed) common.Toast(message) + common.StateUpdateChannel.postMessage({}) + document.dispatchEvent(new CustomEvent("answerCorrect")) } catch (err) { common.Toast(err) @@ -233,6 +235,16 @@ async function loadPuzzle(category, points) { return puzzle } +const confettiPromise = import("https://cdn.jsdelivr.net/npm/canvas-conefetti@1.9.2/+esm") +async function CorrectAnswer() { + setInterval(window.close, 3 * common.Second) + + let confetti = await confettiPromise + confetti.default({ + disableForReducedMotion: true, + }) +} + async function init() { window.app = {} window.setanswer = (str => SetAnswer(str)) @@ -250,6 +262,9 @@ async function init() { // Workspaces may trigger a "this is the answer" event document.addEventListener("setAnswer", e => SetAnswer(e.detail.value)) + // Celebrate on correct answer + document.addEventListener("answerCorrect", e => CorrectAnswer()) + // 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, common.BaseURL)