diff --git a/public/serviceworker.js b/public/serviceworker.js new file mode 100644 index 00000000..d34b3fc2 --- /dev/null +++ b/public/serviceworker.js @@ -0,0 +1,65 @@ + +// "BMWzSl5zZPWw_lAKVvQb8NZBQwCs83jQJc68cj04yQTYt_kAIvuCMte0wU7BXjODXuGn8ut5qwU0pR_44dZuAmQ" + +self.addEventListener('install', event => { + console.log('Service Worker install', event); +}); + + +// This will be called only once when the service worker is activated. +self.addEventListener('activate', async() => { +try { + const applicationServerKey = urlB64ToUint8Array('BMWzSl5zZPWw_lAKVvQb8NZBQwCs83jQJc68cj04yQTYt_kAIvuCMte0wU7BXjODXuGn8ut5qwU0pR_44dZuAmQ') + const options = { applicationServerKey, userVisibleOnly: true } + const subscription = await self.registration.pushManager.subscribe(options) + console.log(JSON.stringify(subscription)) + } catch (err) { + console.log('Error', err) + } +}) + +self.addEventListener('push', function (event) { + console.log('Service Worker push', event); + if (event.data) { + console.log("Push event!! ", event.data.text()); + showLocalNotification("Yolo", event.data.text(), self.registration); + } else { + console.log("Push event but no data"); + } +}); + + +self.addEventListener('message', function(event) { + console.log('Service Worker message', event); + if (isObject(event.data)) { + if (event.data.type === 'sync') { + // in this way, you can decide your tag + //const id = event.data.id || uuid() + // pass the port into the memory stor + //syncStore[id] = Object.assign({ port: event.ports[0] }, event.data) + //self.registration.sync.register(id) + } + } +}) + +self.addEventListener('sync', function(event) { + console.log('Service Worker sync', event); +}) + +const showLocalNotification = function(title, body, swRegistration) { + const options = { + body + // here you can add more properties like icon, image, vibrate, etc. + }; + swRegistration.showNotification(title, options); +}; + +// Used to convert Base64 public VAPID key to bytearray. +function urlBase64ToUint8Array(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } + return outputArray; +} \ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index 9b66b548..0eac16b0 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -354,6 +354,7 @@

+ Localization Settings
Notification Settings
@@ -1359,6 +1360,37 @@ // Fix links if a loginKey is used if (urlargs.key) { Q('termsLinkFooter').href += '?key=' + urlargs.key; } + /* + // Register the service worker + if ('serviceWorker' in navigator) { + navigator.serviceWorker.addEventListener('message', function(event) { + console.log("Client message from service worker: " + event); + }); + + navigator.serviceWorker.register('serviceworker.js') + .then(function(reg) { + // Registration worked + console.log('Registration succeeded. Scope is ' + reg.scope); + + reg.pushManager.getSubscription().then(function(sub) { + if (sub === null) { + // Update UI to ask user to register for Push + console.log('Not subscribed to push service.'); + } else { + // We have a subscription, update the database + console.log('Subscription object: ', sub); + + navigator.serviceWorker.controller.postMessage({type: 'sync', text: 'Hello!'}) + } + }); + + }).catch((error) => { + // Registration failed + console.log('Registration failed with ' + error); + }); + } + */ + // Check if we are in debug mode args = parseUriArgs(); if (args.key && (isAlphaNumeric(args.key) == false)) { delete args.key; } @@ -2066,6 +2098,7 @@ serverinfo = message.serverinfo; if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); } if (debugmode == 1) { console.log('Server time: ', printDateTime(new Date(serverinfo.serverTime))); } + //console.log(serverinfo); break; } case 'userinfo': { @@ -9659,6 +9692,11 @@ } } + function account_enablePushNotifications() { + if ((serverinfo == null) || (serverinfo.vapidpublickey == null)) return; + return false; + } + function account_enableNotifications() { if (Notification) { Notification.requestPermission().then(function (permission) { QV('accountEnableNotificationsSpan', permission != 'granted'); }); } return false; @@ -14043,6 +14081,7 @@ // Setup web notifications if ((x == 2) && Notification) { QV('accountEnableNotificationsSpan', Notification.permission != 'granted'); } + //QV('accountEnablePushNotificationsSpan', true); // Fetch the server timeline stats if needed if ((x == 40) && (serverTimelineStats == null)) { refreshServerTimelineStats(); } @@ -14449,16 +14488,6 @@ function round(value, precision) { var multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; } function safeNewWindow(url, target) { var newWindow = window.open(url, target, 'noopener,noreferrer'); if (newWindow) { newWindow.opener = null; } } - // Used to convert Base64 public VAPID key to bytearray. - function urlBase64ToUint8Array(base64String) { - const padding = '='.repeat((4 - base64String.length % 4) % 4); - const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); - const rawData = window.atob(base64); - const outputArray = new Uint8Array(rawData.length); - for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } - return outputArray; - } - // Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it. // So we do that for all browsers except FireFox function downloadFile(link, name, closeDialog) {