2018-02-21 17:48:22 +00:00
|
|
|
// The Lounge - https://github.com/thelounge/thelounge
|
2017-07-10 19:47:03 +00:00
|
|
|
/* global clients */
|
|
|
|
"use strict";
|
|
|
|
|
2019-03-08 10:29:49 +00:00
|
|
|
const cacheName = "__HASH__";
|
2018-06-05 12:28:09 +00:00
|
|
|
const excludedPathsFromCache = /^(?:socket\.io|storage|uploads|cdn-cgi)\//;
|
|
|
|
|
|
|
|
self.addEventListener("install", function() {
|
|
|
|
self.skipWaiting();
|
|
|
|
});
|
|
|
|
|
|
|
|
self.addEventListener("activate", function(event) {
|
2019-03-08 10:29:49 +00:00
|
|
|
event.waitUntil(caches.keys().then((names) => Promise.all(
|
|
|
|
names
|
|
|
|
.filter((name) => name !== cacheName)
|
|
|
|
.map((name) => caches.delete(name))
|
|
|
|
)));
|
|
|
|
|
2018-06-05 12:28:09 +00:00
|
|
|
event.waitUntil(self.clients.claim());
|
|
|
|
});
|
|
|
|
|
|
|
|
self.addEventListener("fetch", function(event) {
|
|
|
|
if (event.request.method !== "GET") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const url = event.request.url;
|
|
|
|
const scope = self.registration.scope;
|
|
|
|
|
|
|
|
// Skip cross-origin requests
|
|
|
|
if (!url.startsWith(scope)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const path = url.substring(scope.length);
|
|
|
|
|
|
|
|
// Skip ignored paths
|
|
|
|
if (excludedPathsFromCache.test(path)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-03-08 10:29:49 +00:00
|
|
|
event.respondWith(networkOrCache(event));
|
2018-06-05 12:28:09 +00:00
|
|
|
});
|
|
|
|
|
2019-03-08 10:29:49 +00:00
|
|
|
async function putInCache(request, response) {
|
2019-03-07 19:14:50 +00:00
|
|
|
const cache = await caches.open(cacheName);
|
2019-03-08 10:29:49 +00:00
|
|
|
await cache.put(request, response);
|
2019-03-07 19:14:50 +00:00
|
|
|
}
|
2019-01-11 19:26:01 +00:00
|
|
|
|
2019-03-08 10:29:49 +00:00
|
|
|
async function networkOrCache(event) {
|
2019-03-07 19:14:50 +00:00
|
|
|
try {
|
2019-03-08 10:29:49 +00:00
|
|
|
const response = await fetch(event.request, {cache: "no-cache"});
|
2019-01-11 19:26:01 +00:00
|
|
|
|
2019-03-07 19:14:50 +00:00
|
|
|
if (response.ok) {
|
2019-03-08 10:29:49 +00:00
|
|
|
event.waitUntil(putInCache(event.request, response));
|
2019-03-07 19:14:50 +00:00
|
|
|
return response.clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error(`Request failed with HTTP ${response.status}`);
|
|
|
|
} catch (e) {
|
|
|
|
// eslint-disable-next-line no-console
|
2019-03-08 10:29:49 +00:00
|
|
|
console.error(e.message, event.request.url);
|
2019-03-07 19:14:50 +00:00
|
|
|
|
|
|
|
const cache = await caches.open(cacheName);
|
2019-03-08 10:29:49 +00:00
|
|
|
const matching = await cache.match(event.request);
|
2019-03-07 19:14:50 +00:00
|
|
|
|
|
|
|
return matching || Promise.reject("request-not-in-cache");
|
|
|
|
}
|
2018-06-05 12:28:09 +00:00
|
|
|
}
|
|
|
|
|
2017-09-28 08:53:32 +00:00
|
|
|
self.addEventListener("message", function(event) {
|
|
|
|
showNotification(event, event.data);
|
|
|
|
});
|
|
|
|
|
2017-07-10 19:47:03 +00:00
|
|
|
self.addEventListener("push", function(event) {
|
|
|
|
if (!event.data) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-09-28 08:53:32 +00:00
|
|
|
showNotification(event, event.data.json());
|
|
|
|
});
|
2017-07-10 19:47:03 +00:00
|
|
|
|
2017-09-28 08:53:32 +00:00
|
|
|
function showNotification(event, payload) {
|
2017-09-03 15:57:07 +00:00
|
|
|
if (payload.type !== "notification") {
|
|
|
|
return;
|
2017-07-10 19:47:03 +00:00
|
|
|
}
|
2017-09-03 15:57:07 +00:00
|
|
|
|
|
|
|
// get current notification, close it, and draw new
|
|
|
|
event.waitUntil(
|
|
|
|
self.registration
|
|
|
|
.getNotifications({
|
2017-11-15 06:35:15 +00:00
|
|
|
tag: `chan-${payload.chanId}`,
|
2017-09-03 15:57:07 +00:00
|
|
|
})
|
|
|
|
.then((notifications) => {
|
|
|
|
for (const notification of notifications) {
|
|
|
|
notification.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.registration.showNotification(payload.title, {
|
|
|
|
tag: `chan-${payload.chanId}`,
|
2018-01-28 07:20:24 +00:00
|
|
|
badge: "img/icon-alerted-black-transparent-bg-72x72px.png",
|
|
|
|
icon: "img/icon-alerted-grey-bg-192x192px.png",
|
2017-09-03 15:57:07 +00:00
|
|
|
body: payload.body,
|
|
|
|
timestamp: payload.timestamp,
|
|
|
|
});
|
|
|
|
})
|
|
|
|
);
|
2017-09-28 08:53:32 +00:00
|
|
|
}
|
2017-07-10 19:47:03 +00:00
|
|
|
|
|
|
|
self.addEventListener("notificationclick", function(event) {
|
|
|
|
event.notification.close();
|
|
|
|
|
|
|
|
event.waitUntil(clients.matchAll({
|
2017-12-24 14:06:23 +00:00
|
|
|
includeUncontrolled: true,
|
2017-11-15 06:35:15 +00:00
|
|
|
type: "window",
|
2017-12-24 14:06:23 +00:00
|
|
|
}).then((clientList) => {
|
|
|
|
if (clientList.length === 0) {
|
|
|
|
if (clients.openWindow) {
|
|
|
|
return clients.openWindow(`.#${event.notification.tag}`);
|
2017-07-10 19:47:03 +00:00
|
|
|
}
|
2017-12-24 14:06:23 +00:00
|
|
|
|
|
|
|
return;
|
2017-07-10 19:47:03 +00:00
|
|
|
}
|
|
|
|
|
2017-12-24 14:06:23 +00:00
|
|
|
const client = findSuitableClient(clientList);
|
|
|
|
|
|
|
|
client.postMessage({
|
|
|
|
type: "open",
|
|
|
|
channel: event.notification.tag,
|
|
|
|
});
|
|
|
|
|
|
|
|
if ("focus" in client) {
|
|
|
|
client.focus();
|
2017-07-10 19:47:03 +00:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
});
|
2017-12-24 14:06:23 +00:00
|
|
|
|
|
|
|
function findSuitableClient(clientList) {
|
|
|
|
for (let i = 0; i < clientList.length; i++) {
|
|
|
|
const client = clientList[i];
|
|
|
|
|
|
|
|
if (client.focused || client.visibilityState === "visible") {
|
|
|
|
return client;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return clientList[0];
|
|
|
|
}
|