142 lines
No EOL
4.7 KiB
JavaScript
142 lines
No EOL
4.7 KiB
JavaScript
var periodicSyncNewMsgReminderText;
|
|
|
|
const OFFLINE_CACHE = `offline`;
|
|
const offlineCacheFiles = ['offline.html','config.json'];
|
|
|
|
// on install we download the routes we want to cache for offline
|
|
self.addEventListener('install', evt => evt.waitUntil(caches.open(OFFLINE_CACHE).then(cache => {
|
|
console.log("SW Caching offline files");
|
|
self.skipWaiting();
|
|
return cache.addAll(offlineCacheFiles);
|
|
})));
|
|
|
|
self.addEventListener("activate", event => {
|
|
event.waitUntil(clients.claim());
|
|
});
|
|
|
|
// Notification click event listener
|
|
self.addEventListener("notificationclick", (e) => {
|
|
e.notification.close();
|
|
e.waitUntil(
|
|
clients.matchAll({ type: "window" }).then((clientsArr) => {
|
|
// If a Window tab matching the targeted URL already exists, focus that;
|
|
const hadWindowToFocus = clientsArr.some((windowClient) =>
|
|
windowClient.url === e.notification.data.url
|
|
? (windowClient.focus(), true)
|
|
: false,
|
|
);
|
|
|
|
// Otherwise, open a new tab to the applicable URL and focus it.
|
|
if (!hadWindowToFocus)
|
|
clients
|
|
.openWindow(e.notification.data.url)
|
|
.then((windowClient) => (windowClient ? windowClient.focus() : null));
|
|
}),
|
|
);
|
|
});
|
|
|
|
self.addEventListener("message", (event) => {
|
|
periodicSyncNewMsgReminderText = event.data;
|
|
});
|
|
|
|
async function checkNewMessages() {
|
|
const cachedCredentials = await caches.open('cachedCredentials');
|
|
// Todo...
|
|
}
|
|
|
|
// Install PWA in mobile or web to test if periodicSync notification works
|
|
// see browser compatibility: https://developer.mozilla.org/en-US/docs/Web/API/Web_Periodic_Background_Synchronization_API#browser_compatibility
|
|
self.addEventListener('periodicsync', (event) => {
|
|
if (event.tag === 'check-new-messages') {
|
|
let notificationTitle = periodicSyncNewMsgReminderText || "You may have new messages";
|
|
self.registration.showNotification(notificationTitle);
|
|
|
|
event.waitUntil(checkNewMessages());
|
|
}
|
|
});
|
|
|
|
self.addEventListener("fetch", (event) => {
|
|
if (event.request.mode === 'navigate') {
|
|
return event.respondWith(
|
|
fetch(event.request).catch((e) => {
|
|
console.log("OFFLINE, serve offline page", e);
|
|
return serveOfflinePage();
|
|
}));
|
|
} else if (event.request.url.endsWith("config.json")) {
|
|
return fetch(event.request)
|
|
.then((response) => {
|
|
console.log("Caching a new version of config.json");
|
|
let responseClone = response.clone();
|
|
caches
|
|
.open(OFFLINE_CACHE)
|
|
.then((cache) => cache.put(event.request, responseClone));
|
|
return response;
|
|
})
|
|
}
|
|
});
|
|
|
|
async function serveOfflinePage() {
|
|
let mirrorUrl = null;
|
|
const rConfig = await caches.match("config.json", { cacheName: OFFLINE_CACHE});
|
|
if (rConfig) {
|
|
const json = await rConfig.json();
|
|
const mirrors = json.mirrors;
|
|
if (mirrors && Array.isArray(mirrors) && mirrors.length > 0) {
|
|
mirrorUrl = json.mirrors[Math.floor(Math.random() * mirrors.length)];
|
|
}
|
|
}
|
|
const offlinePage = await caches.match("offline.html", { cacheName: OFFLINE_CACHE});
|
|
if (mirrorUrl && offlinePage) {
|
|
let text = await offlinePage.text();
|
|
text = text.replaceAll("<!--MIRROR_URL-->", mirrorUrl);
|
|
|
|
let title = undefined;
|
|
let message = undefined;
|
|
let redirect = undefined;
|
|
|
|
await new Promise((resolve, reject) => {
|
|
var open = indexedDB.open("ServiceWorker", 1);
|
|
open.onerror = function() {
|
|
resolve(false);
|
|
}
|
|
open.onsuccess = function() {
|
|
// Start a new transaction
|
|
var db = open.result;
|
|
var tx = db.transaction("offline_strings", "readonly");
|
|
var store = tx.objectStore("offline_strings");
|
|
|
|
var get1 = store.get("offline_title");
|
|
var get2 = store.get("offline_message");
|
|
var get3 = store.get("offline_redirect");
|
|
|
|
get1.onsuccess = function() {
|
|
title = get1.result.translation;
|
|
};
|
|
get2.onsuccess = function() {
|
|
message = get2.result.translation;
|
|
};
|
|
get3.onsuccess = function() {
|
|
redirect = get3.result.translation;
|
|
};
|
|
|
|
// Close the db when the transaction is done
|
|
tx.oncomplete = function() {
|
|
db.close();
|
|
resolve(true);
|
|
};
|
|
}
|
|
});
|
|
|
|
if (title) {
|
|
text = text.replaceAll(/<!--OFFLINE_TITLE_START-->(.*?)<!--OFFLINE_TITLE_END-->/g, title);
|
|
}
|
|
if (message) {
|
|
text = text.replaceAll(/<!--OFFLINE_MESSAGE_START-->(.*?)<!--OFFLINE_MESSAGE_END-->/g, message);
|
|
}
|
|
if (redirect) {
|
|
text = text.replaceAll(/<!--OFFLINE_REDIRECT_START-->(.*?)<!--OFFLINE_REDIRECT_END-->/g, redirect);
|
|
}
|
|
return new Response(text, { headers: {"content-type": "text/html"}});
|
|
}
|
|
throw new Error("Offline");
|
|
} |