69 lines
2.0 KiB
JavaScript
69 lines
2.0 KiB
JavaScript
const storageKey = "ddc-notifications";
|
|
const finishedTitles = {
|
|
ready: "Download ready",
|
|
completed: "Download moved",
|
|
failed: "Download failed",
|
|
};
|
|
const previousStatuses = new Map();
|
|
|
|
function notificationsSupported() {
|
|
return "Notification" in window;
|
|
}
|
|
|
|
function readPreference() {
|
|
try {
|
|
return localStorage.getItem(storageKey) === "on";
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function storePreference(enabled) {
|
|
try {
|
|
localStorage.setItem(storageKey, enabled ? "on" : "off");
|
|
} catch {
|
|
return;
|
|
}
|
|
}
|
|
|
|
export function notificationsEnabled() {
|
|
return notificationsSupported() && Notification.permission === "granted" && readPreference();
|
|
}
|
|
|
|
export async function setNotificationsEnabled(enabled) {
|
|
if (!enabled) {
|
|
storePreference(false);
|
|
return;
|
|
}
|
|
if (!notificationsSupported()) throw new Error("This browser does not support notifications.");
|
|
const permission = await Notification.requestPermission();
|
|
if (permission !== "granted") throw new Error("Notifications are blocked for this site in the browser settings.");
|
|
storePreference(true);
|
|
}
|
|
|
|
export function collectTransitions(jobs) {
|
|
const transitions = [];
|
|
const seenIds = new Set();
|
|
for (const job of jobs) {
|
|
seenIds.add(job.id);
|
|
const previous = previousStatuses.get(job.id);
|
|
if (previous && previous !== job.status) transitions.push({ job, previous });
|
|
previousStatuses.set(job.id, job.status);
|
|
}
|
|
for (const id of previousStatuses.keys()) {
|
|
if (!seenIds.has(id)) previousStatuses.delete(id);
|
|
}
|
|
return transitions;
|
|
}
|
|
|
|
export function notifyTransitions(transitions) {
|
|
if (!notificationsEnabled()) return;
|
|
for (const { job, previous } of transitions) {
|
|
const title = finishedTitles[job.status];
|
|
const wasWorking = previous === "queued" || previous === "downloading" || previous === "extracting" || previous === "moving";
|
|
if (!title || !wasWorking) continue;
|
|
if (job.status === "ready" && previous === "moving") continue;
|
|
new Notification(title, { body: job.fileName || job.sourceUrl, tag: `ddc-${job.id}` });
|
|
}
|
|
}
|