55 lines
1.9 KiB
JavaScript
55 lines
1.9 KiB
JavaScript
|
|
// Thermograph service worker — push delivery only.
|
||
|
|
//
|
||
|
|
// Deliberately NO fetch/offline caching: the app already has an app-level
|
||
|
|
// IndexedDB response cache (cache.js), and a caching service worker would fight
|
||
|
|
// it. This worker exists purely so the app is installable (a registered SW is a
|
||
|
|
// PWA prerequisite) and can receive Web Push while no tab is open.
|
||
|
|
//
|
||
|
|
// Served from {BASE}/sw.js, so its scope is {BASE}/ — it controls the whole app.
|
||
|
|
|
||
|
|
self.addEventListener("install", () => {
|
||
|
|
self.skipWaiting(); // activate this version immediately
|
||
|
|
});
|
||
|
|
|
||
|
|
self.addEventListener("activate", (event) => {
|
||
|
|
event.waitUntil(self.clients.claim()); // take control of open pages at once
|
||
|
|
});
|
||
|
|
|
||
|
|
// A push arrived. The payload is the JSON we send from push.py:
|
||
|
|
// { title, body, url, tag }.
|
||
|
|
self.addEventListener("push", (event) => {
|
||
|
|
let data = {};
|
||
|
|
try {
|
||
|
|
data = event.data ? event.data.json() : {};
|
||
|
|
} catch (e) {
|
||
|
|
data = { title: "Thermograph", body: event.data ? event.data.text() : "" };
|
||
|
|
}
|
||
|
|
const title = data.title || "Thermograph";
|
||
|
|
const options = {
|
||
|
|
body: data.body || "",
|
||
|
|
icon: "logo-192.png",
|
||
|
|
badge: "logo-192.png",
|
||
|
|
tag: data.tag || "thermograph",
|
||
|
|
data: { url: data.url || "./" },
|
||
|
|
};
|
||
|
|
event.waitUntil(self.registration.showNotification(title, options));
|
||
|
|
});
|
||
|
|
|
||
|
|
// Tapping a notification: focus an existing app tab if one is open, else open the
|
||
|
|
// deep link the notification carried.
|
||
|
|
self.addEventListener("notificationclick", (event) => {
|
||
|
|
event.notification.close();
|
||
|
|
const target = (event.notification.data && event.notification.data.url) || "./";
|
||
|
|
event.waitUntil(
|
||
|
|
self.clients.matchAll({ type: "window", includeUncontrolled: true }).then((clients) => {
|
||
|
|
for (const client of clients) {
|
||
|
|
if ("focus" in client) {
|
||
|
|
client.navigate(target).catch(() => {});
|
||
|
|
return client.focus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return self.clients.openWindow(target);
|
||
|
|
})
|
||
|
|
);
|
||
|
|
});
|