initial notification checkbox
This commit is contained in:
parent
6ba7d08e97
commit
3f9ee57208
1 changed files with 42 additions and 4 deletions
46
index.html
46
index.html
|
|
@ -410,6 +410,8 @@
|
|||
solution</button>
|
||||
<input id="importFile" type="file" accept="application/json,.json" style="display:none"
|
||||
onchange="onImportFile(event)">
|
||||
<label id="notifyWrap" style="display:none;margin-left:.6rem">
|
||||
<input id="notifyDone" type="checkbox"> Notify when queued items complete</label>
|
||||
</p>
|
||||
|
||||
<div id="error" class="err"></div>
|
||||
|
|
@ -1006,6 +1008,34 @@
|
|||
// queued -> running -> done (rendered) / error / cancelled.
|
||||
const pending = new Map();
|
||||
|
||||
// --- "notify when queue empty" checkbox ---
|
||||
// The checkbox only appears while solves are queued/running. Permission is
|
||||
// requested the first time it's checked (not on page load). When the queue
|
||||
// drains to empty it fires a notification (if still checked), then unchecks
|
||||
// itself and hides until there's work again.
|
||||
const notifyWrap = document.getElementById("notifyWrap");
|
||||
const notifyDone = document.getElementById("notifyDone");
|
||||
notifyDone.onchange = () => {
|
||||
if (notifyDone.checked && "Notification" in window
|
||||
&& Notification.permission === "default") {
|
||||
Notification.requestPermission();
|
||||
}
|
||||
};
|
||||
// Show/hide the checkbox to match the current queue state, and uncheck it
|
||||
// once the queue is empty. Call after any change to `pending`.
|
||||
function updateNotifyUi() {
|
||||
notifyWrap.style.display = pending.size ? "" : "none";
|
||||
if (!pending.size) notifyDone.checked = false;
|
||||
}
|
||||
// Fire the "queue empty" notification if the user opted in and granted it.
|
||||
function notifyQueueEmpty() {
|
||||
if (notifyDone.checked && "Notification" in window
|
||||
&& Notification.permission === "granted") {
|
||||
new Notification("DWS Solver",
|
||||
{body: "All queued solves have finished."});
|
||||
}
|
||||
}
|
||||
|
||||
function uuid() {
|
||||
return crypto.randomUUID ? crypto.randomUUID()
|
||||
: String(Date.now()) + Math.random();
|
||||
|
|
@ -1168,7 +1198,7 @@
|
|||
card.append(
|
||||
el("div", {class: "pending-head"},
|
||||
[el("span", {class: "spinner"}), nameSpan,
|
||||
document.createTextNode(" — "), status]),
|
||||
document.createTextNode(" — "), status]),
|
||||
actions);
|
||||
return card;
|
||||
}
|
||||
|
|
@ -1190,7 +1220,11 @@
|
|||
if (!entry) return;
|
||||
pending.delete(token);
|
||||
action(entry);
|
||||
if (pending.size === 0 && stream) {stream.close(); stream = null;}
|
||||
if (pending.size === 0) {
|
||||
if (stream) {stream.close(); stream = null;}
|
||||
notifyQueueEmpty();
|
||||
}
|
||||
updateNotifyUi();
|
||||
}
|
||||
|
||||
// Put a pending card into a terminal state: show the message, drop the
|
||||
|
|
@ -1283,6 +1317,7 @@
|
|||
// Stash the inputs alongside the pending solve so, once it finishes,
|
||||
// its card can export a self-contained {problem, solution} bundle.
|
||||
pending.set(token, {token, card, n, confirmed: false, problem, maxTime: time});
|
||||
updateNotifyUi();
|
||||
fetch("/solve", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
|
|
@ -1330,8 +1365,10 @@
|
|||
}
|
||||
actions.append(el("button", {
|
||||
class: "mini", type: "button",
|
||||
onclick: () => exportSolve({token, n, solution: s, problem, maxTime,
|
||||
name: solveLabel(token, n)}),
|
||||
onclick: () => exportSolve({
|
||||
token, n, solution: s, problem, maxTime,
|
||||
name: solveLabel(token, n)
|
||||
}),
|
||||
}, "Export"));
|
||||
// The problem may be on hand (a solve queued from this tab) or, for a
|
||||
// solve opened via a share link, fetched from the server by token on
|
||||
|
|
@ -1742,6 +1779,7 @@
|
|||
// Load in reverse so the first id ends up on top (each load prepends).
|
||||
for (const token of sharedTokens.slice().reverse()) loadSharedSolve(token);
|
||||
if (sharedTokens.length) syncStream();
|
||||
updateNotifyUi();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue