From 9985e91a69fd77919b8cf8db0b2fd860f377bee7 Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Sun, 20 Dec 2015 15:07:28 +0100 Subject: [PATCH] use service workers for notifications If Service Workers are available use them to display notifications instead of the old way of creating notifications directly. This has the side effect that it works nicely on chrome on android which the old method does not. This also paves the way to set up GCM for push notification in the future which can give us push notifications without having the app running. This patch can be improved in the future to get existing notifications and change the message instead of just adding more and more notifications. See: ServiceWorkerRegistration.getNotifications() and ServiceWorkerRegistration.update() from https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration --- js/notifications.js | 84 +++++++++++++++++++++++++++++---------------- serviceworker.js | 22 ++++++++++++ 2 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 serviceworker.js diff --git a/js/notifications.js b/js/notifications.js index 1e03db6..2ed9d1b 100644 --- a/js/notifications.js +++ b/js/notifications.js @@ -1,8 +1,9 @@ var weechat = angular.module('weechat'); weechat.factory('notifications', ['$rootScope', '$log', 'models', 'settings', function($rootScope, $log, models, settings) { - // Ask for permission to display desktop notifications + var serviceworker = false; var notifications = []; + // Ask for permission to display desktop notifications var requestNotificationPermission = function() { // Firefox if (window.Notification) { @@ -22,6 +23,58 @@ weechat.factory('notifications', ['$rootScope', '$log', 'models', 'settings', fu window.webkitNotifications.requestPermission(); } } + + if ('serviceWorker' in navigator) { + $log.info('Service Worker is supported'); + navigator.serviceWorker.register('serviceworker.js').then(function(reg) { + $log.info('Service Worker install:', reg); + serviceworker = true; + }).catch(function(err) { + $log.info('Service Worker err:', err); + }); + } + }; + + var showNotification = function(title, body) { + if (serviceworker) { + navigator.serviceWorker.ready.then(function(registration) { + registration.showNotification(title, { + body: body, + icon: 'assets/img/glowing_bear_128x128.png', + vibrate: [200, 100, 200, 100, 200, 100, 200], + tag: 'gb-highlight-vib' + }); + }); + } else { + var notification = new Notification(title, { + body: body, + icon: 'assets/img/favicon.png' + }); + + // Save notification, so we can close all outstanding ones when disconnecting + notification.id = notifications.length; + notifications.push(notification); + + // Cancel notification automatically + var timeout = 15*1000; + notification.onshow = function() { + setTimeout(function() { + notification.close(); + }, timeout); + }; + + // Click takes the user to the buffer + notification.onclick = function() { + models.setActiveBuffer(buffer.id); + window.focus(); + notification.close(); + }; + + // Remove from list of active notifications + notification.onclose = function() { + delete notifications[this.id]; + }; + } }; @@ -104,34 +157,7 @@ weechat.factory('notifications', ['$rootScope', '$log', 'models', 'settings', fu } title += buffer.shortName + " (" + buffer.server + ")"; - var notification = new Notification(title, { - body: body, - icon: 'assets/img/favicon.png' - }); - - // Save notification, so we can close all outstanding ones when disconnecting - notification.id = notifications.length; - notifications.push(notification); - - // Cancel notification automatically - var timeout = 15*1000; - notification.onshow = function() { - setTimeout(function() { - notification.close(); - }, timeout); - }; - - // Click takes the user to the buffer - notification.onclick = function() { - models.setActiveBuffer(buffer.id); - window.focus(); - notification.close(); - }; - - // Remove from list of active notifications - notification.onclose = function() { - delete notifications[this.id]; - }; + showNotification(title, body); if (settings.soundnotification) { // TODO fill in a sound file diff --git a/serviceworker.js b/serviceworker.js new file mode 100644 index 0000000..99f97c5 --- /dev/null +++ b/serviceworker.js @@ -0,0 +1,22 @@ +// File needs to be stored in the root of the app. + +this.addEventListener('install', function(event) { + event.waitUntil( + caches.open('v1').then(function(cache) { + return cache.addAll([ + 'assets/img/glowing_bear_128x128.png', + ]); + }) + ); +}); + +this.addEventListener('push', function(event) { + // TODO, support GCM here + var title = 'Push message'; + event.waitUntil( + self.registration.showNotification(title, { + body: 'The Message', + icon: 'assets/img/favicon.png', + tag: 'my-tag' + })); +});