Skip to content

Commit

Permalink
use service workers for notifications
Browse files Browse the repository at this point in the history
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
  • Loading branch information
torhve committed Dec 20, 2015
1 parent 623ff5a commit 9985e91
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 29 deletions.
84 changes: 55 additions & 29 deletions js/notifications.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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];
};
}
};


Expand Down Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions serviceworker.js
Original file line number Diff line number Diff line change
@@ -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'
}));
});

0 comments on commit 9985e91

Please sign in to comment.