From 5f2f37897aa8406f15da2cee1664bf333b831e12 Mon Sep 17 00:00:00 2001 From: neobii Date: Mon, 23 May 2016 16:03:58 -0400 Subject: [PATCH 1/6] browser init --- lib/client/browserPush.js | 114 ++++++++++++++++++++++++++++++++++++++ lib/client/client.js | 4 ++ package.js | 1 + 3 files changed, 119 insertions(+) create mode 100644 lib/client/browserPush.js diff --git a/lib/client/browserPush.js b/lib/client/browserPush.js new file mode 100644 index 0000000..e2cdf5d --- /dev/null +++ b/lib/client/browserPush.js @@ -0,0 +1,114 @@ +Push.browserInit = function(){ + console.log("registering service worker"); + navigator.serviceWorker.register('/service-worker.js').then(initialiseState); +} + + +function initialiseState() { + // Are Notifications supported in the service worker? + if (!('showNotification' in ServiceWorkerRegistration.prototype)) { + console.warn('Notifications aren\'t supported.'); + return; + } + + // Check the current Notification permission. + // If its denied, it's a permanent block until the + // user changes the permission + if (Notification.permission === 'denied') { + console.warn('The user has blocked notifications.'); + return; + } + + // Check if push messaging is supported + if (!('PushManager' in window)) { + console.warn('Push messaging isn\'t supported.'); + return; + } + + // We need the service worker registration to check for a subscription + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + // Do we already have a push message subscription? + serviceWorkerRegistration.pushManager.getSubscription() + .then(function(subscription) { + if (!subscription) { + // We aren't subscribed to push, so set UI + // to allow the user to enable push + return; + } + // Keep your server in sync with the latest subscriptionId + //???sendSubscriptionToServer(subscription); + }) + .catch(function(err) { + console.warn('Error during getSubscription()', err); + }); + }); +} + +Push.browserUnsubscribe = function() { + + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + // To unsubscribe from push messaging, you need get the + // subscription object, which you can call unsubscribe() on. + serviceWorkerRegistration.pushManager.getSubscription().then( + function(pushSubscription) { + // Check we have a subscription to unsubscribe + if (!pushSubscription) { + // No subscription object, so set the state + // to allow the user to subscribe to push + isPushEnabled = false; + return; + } + + var subscriptionId = pushSubscription.subscriptionId; + // TODO: Make a request to your server to remove + // the subscriptionId from your data store so you + // don't attempt to send them push messages anymore + + // We have a subscription, so call unsubscribe on it + pushSubscription.unsubscribe().then(function(successful) { + isPushEnabled = false; + }).catch(function(e) { + // We failed to unsubscribe, this can lead to + // an unusual state, so may be best to remove + // the users data from your data store and + // inform the user that you have done so + + console.log('Unsubscription error: ', e); + }); + }).catch(function(e) { + console.error('Error thrown while unsubscribing from push messaging.', e); + }); + }); +} + +Push.browserSubscribe = function() { + // Disable the button so it can't be changed while + // we process the permission request + + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true}) + .then(function(subscription) { + // The subscription was successful + console.log("success"); + // TODO: Send the subscription.endpoint to your server + // and save it to send a push message at a later date + //return sendSubscriptionToServer(subscription); + }) + .catch(function(e) { + if (Notification.permission === 'denied') { + // The user denied the notification permission which + // means we failed to subscribe and the user will need + // to manually change the notification permission to + // subscribe to push messages + console.warn('Permission for Notifications was denied'); + + } else { + // A problem occurred with the subscription; common reasons + // include network errors, and lacking gcm_sender_id and/or + // gcm_user_visible_only in the manifest. + console.error('Unable to subscribe to push.', e); + } + }); + }); +} + diff --git a/lib/client/client.js b/lib/client/client.js index cd2c468..ae57782 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -75,6 +75,10 @@ Push.enabled = function(state) { if (state !== stored.enabled && stored.id) { // Latency compensation _setEnabled(state); + if(!Meteor.isCordova){ + Push.browserInit(); + Push.browserSubscribe(); + } // Update server Meteor.call('raix:push-enable', { id: stored.id, diff --git a/package.js b/package.js index 97cb77d..fd7c90b 100644 --- a/package.js +++ b/package.js @@ -68,6 +68,7 @@ Package.onUse(function(api) { // API's api.addFiles('lib/client/browser.js', 'web.browser'); + api.addFiles('lib/client/browserPush.js', 'web.browser'); api.addFiles('lib/server/push.api.js', 'server'); // // Unified api From 83a3d095c4c8fc6687bf2c5b981a8f36b3a060d8 Mon Sep 17 00:00:00 2001 From: neobii Date: Mon, 23 May 2016 16:37:15 -0400 Subject: [PATCH 2/6] emit state? --- lib/client/browserPush.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/client/browserPush.js b/lib/client/browserPush.js index e2cdf5d..df632c6 100644 --- a/lib/client/browserPush.js +++ b/lib/client/browserPush.js @@ -36,7 +36,7 @@ function initialiseState() { return; } // Keep your server in sync with the latest subscriptionId - //???sendSubscriptionToServer(subscription); + sendSubscriptionToServer(subscription); }) .catch(function(err) { console.warn('Error during getSubscription()', err); @@ -90,9 +90,13 @@ Push.browserSubscribe = function() { .then(function(subscription) { // The subscription was successful console.log("success"); - // TODO: Send the subscription.endpoint to your server - // and save it to send a push message at a later date - //return sendSubscriptionToServer(subscription); + self.emitState('token', { + SimplePush: { + channel: "push", + endPoint: subscription.endpoint + } + }); + return sendSubscriptionToServer(subscription); }) .catch(function(e) { if (Notification.permission === 'denied') { @@ -112,3 +116,11 @@ Push.browserSubscribe = function() { }); } +function sendSubscriptonToServer(subscription){ + /*self.emitState('token', { + SimplePush: { + channel: "push", + endPoint: subscription.endpoint + } + })*/ +} \ No newline at end of file From ff6cc83d9a00b8f179a478446748c140e01a6e21 Mon Sep 17 00:00:00 2001 From: neobii Date: Mon, 23 May 2016 21:08:08 -0400 Subject: [PATCH 3/6] public files as assets --- browser/push-manifest.json | 13 +++++++++++++ browser/service-worker.js | 40 ++++++++++++++++++++++++++++++++++++++ lib/client/browser.js | 2 ++ lib/client/browserPush.js | 6 +++--- lib/client/client.js | 1 - package.js | 4 ++++ 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 browser/push-manifest.json create mode 100644 browser/service-worker.js diff --git a/browser/push-manifest.json b/browser/push-manifest.json new file mode 100644 index 0000000..e25c25a --- /dev/null +++ b/browser/push-manifest.json @@ -0,0 +1,13 @@ +{ + "name": "code33chat", + "short_name": "code33chat", + "icons": [{ + "src": "images/defaultPic.jpg", + "sizes": "148x148", + "type": "image/jpg" + }], + "start_url": "/", + "display": "standalone", + "gcm_sender_id": "959772988286", + "gcm_user_visible_only": true +} \ No newline at end of file diff --git a/browser/service-worker.js b/browser/service-worker.js new file mode 100644 index 0000000..454f9bf --- /dev/null +++ b/browser/service-worker.js @@ -0,0 +1,40 @@ +self.addEventListener('push', showNotification) +self.addEventListener('notificationclick', closeNotificationAndOpenWindow) + +function showNotification(event) { + console.log('Received a push message', event) + + var title = 'Yay a message.' + var body = 'We have received a push message.' + var icon = '/images/icon-192x192.png' + var tag = 'simple-push-demo-notification-tag' + + event.waitUntil( + self.registration.showNotification(title, { + body: body, + icon: icon, + tag: tag + }) + ) +} + +function closeNotificationAndOpenWindow(event) { + console.log('On notification click: ', event.notification.tag) + // Android doesn’t close the notification when you click on it + // See: http://crbug.com/463146 + event.notification.close() + + // This looks to see if the current is already open and + // focuses if it is + event.waitUntil(clients.matchAll({ + type: "window" + }).then(function(clientList) { + for (var i = 0; i < clientList.length; i++) { + var client = clientList[i] + if (client.url == '/' && 'focus' in client) + return client.focus() + } + if (clients.openWindow) + return clients.openWindow('/') + })) +} \ No newline at end of file diff --git a/lib/client/browser.js b/lib/client/browser.js index 31979f9..18ddfbe 100644 --- a/lib/client/browser.js +++ b/lib/client/browser.js @@ -64,6 +64,7 @@ Push.Configure = function(options) { // Start token updates initPushUpdates(options.appName); + Push.browserInit(); // Add support for the raix:iframe push solution Deprecate this at some // point mid aug 2015 if (options.iframe) { @@ -230,6 +231,7 @@ Push.Configure = function(options) { Meteor.startup(function() { // Ensure that the user can receive Safari Push Notifications. + Push.browserInit(); var permissionData = window.safari.pushNotification.permission(options.apn.websitePushId); checkRemotePermission(permissionData); }); diff --git a/lib/client/browserPush.js b/lib/client/browserPush.js index df632c6..3441d29 100644 --- a/lib/client/browserPush.js +++ b/lib/client/browserPush.js @@ -1,10 +1,10 @@ Push.browserInit = function(){ - console.log("registering service worker"); - navigator.serviceWorker.register('/service-worker.js').then(initialiseState); + $("body").append(''); + navigator.serviceWorker.register('/packages/raix_push/browser/service-worker.js').then(initialiseState); } -function initialiseState() { +function initialiseState() { // Are Notifications supported in the service worker? if (!('showNotification' in ServiceWorkerRegistration.prototype)) { console.warn('Notifications aren\'t supported.'); diff --git a/lib/client/client.js b/lib/client/client.js index ae57782..1f664db 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -76,7 +76,6 @@ Push.enabled = function(state) { // Latency compensation _setEnabled(state); if(!Meteor.isCordova){ - Push.browserInit(); Push.browserSubscribe(); } // Update server diff --git a/package.js b/package.js index fd7c90b..02c6e0a 100644 --- a/package.js +++ b/package.js @@ -53,6 +53,10 @@ Package.onUse(function(api) { api.use('mongo', 'server'); + // public for browser + api.addFiles('browser/push-manifest.json', 'web.browser', {isAsset: true}); + api.addFiles('browser/service-worker.js', 'web.browser', {isAsset: true}); + // API api.addFiles('lib/client/cordova.js', 'web.cordova'); From 0811be2b1f4273cc8d0046404c442b06e7c45596 Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 25 May 2016 04:08:44 -0400 Subject: [PATCH 4/6] manifest generation --- lib/client/browserPush.js | 2 +- lib/server/manifest.js | 20 ++++++++++++++++++++ package.js | 9 ++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 lib/server/manifest.js diff --git a/lib/client/browserPush.js b/lib/client/browserPush.js index 3441d29..ceeae34 100644 --- a/lib/client/browserPush.js +++ b/lib/client/browserPush.js @@ -1,5 +1,5 @@ Push.browserInit = function(){ - $("body").append(''); + $("body").append(''); navigator.serviceWorker.register('/packages/raix_push/browser/service-worker.js').then(initialiseState); } diff --git a/lib/server/manifest.js b/lib/server/manifest.js new file mode 100644 index 0000000..e01eaff --- /dev/null +++ b/lib/server/manifest.js @@ -0,0 +1,20 @@ +// necessary to parse POST data +var connect = Npm.require('connect'); +// necessary for Collection use and other wrapped methods +var Fiber = Npm.require('fibers'); + +var bodyParser = Npm.require("body-parser"); + +WebApp.connectHandlers + .use(bodyParser.urlencoded()) // these two replace + .use(bodyParser.json()) // the old bodyParser + .use('/push-manifest.json', function(req, res, next) { + + // necessary for Collection use and other wrapped methods + Fiber(function() { + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(); + //res.end(JSON.parse(Assets.getText("/config.push.json"))); + + }).run(); + }); diff --git a/package.js b/package.js index 02c6e0a..4dba545 100644 --- a/package.js +++ b/package.js @@ -9,6 +9,9 @@ Package.describe({ Npm.depends({ 'apn' : '1.6.2', // '1.7.4', // working: 1.6.2 'node-gcm' : '0.9.6', // '0.12.0' // working: 0.9.6 + 'connect': '3.4.1', + 'fibers': '1.0.13', + 'body-parser': '1.15.1' }); Cordova.depends({ @@ -48,13 +51,14 @@ Package.onUse(function(api) { 'check', 'mongo', 'underscore', + 'webapp', 'ejson' ], ['client', 'server']); api.use('mongo', 'server'); // public for browser - api.addFiles('browser/push-manifest.json', 'web.browser', {isAsset: true}); +// api.addFiles('browser/push-manifest.json', 'web.browser', {isAsset: true}); api.addFiles('browser/service-worker.js', 'web.browser', {isAsset: true}); // API @@ -79,6 +83,9 @@ Package.onUse(function(api) { api.addFiles('lib/client/client.js', 'client'); api.addFiles('lib/server/server.js', 'server'); + //browser + api.addFiles('lib/server/manifest.js', 'server'); + api.export('Push'); api.export('_matchToken', { testOnly: true }); From d22a94d3c0a854117f8a834982811f079a6b7c4d Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 25 May 2016 05:08:07 -0400 Subject: [PATCH 5/6] manifest generating in proper location --- lib/server/manifest.js | 20 -------------------- lib/server/push.api.js | 23 +++++++++++++++++++++++ plugin/push.configuration.js | 3 ++- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/server/manifest.js b/lib/server/manifest.js index e01eaff..e69de29 100644 --- a/lib/server/manifest.js +++ b/lib/server/manifest.js @@ -1,20 +0,0 @@ -// necessary to parse POST data -var connect = Npm.require('connect'); -// necessary for Collection use and other wrapped methods -var Fiber = Npm.require('fibers'); - -var bodyParser = Npm.require("body-parser"); - -WebApp.connectHandlers - .use(bodyParser.urlencoded()) // these two replace - .use(bodyParser.json()) // the old bodyParser - .use('/push-manifest.json', function(req, res, next) { - - // necessary for Collection use and other wrapped methods - Fiber(function() { - res.writeHead(200, {'Content-Type': 'application/json'}); - res.end(); - //res.end(JSON.parse(Assets.getText("/config.push.json"))); - - }).run(); - }); diff --git a/lib/server/push.api.js b/lib/server/push.api.js index 63d0a63..15bf84b 100644 --- a/lib/server/push.api.js +++ b/lib/server/push.api.js @@ -1,3 +1,9 @@ +// necessary to parse POST data +var connect = Npm.require('connect'); +// necessary for Collection use and other wrapped methods +var Fiber = Npm.require('fibers'); + +var bodyParser = Npm.require("body-parser"); /* A general purpose user CordovaPush ios, android, mail, twitter?, facebook?, sms?, snailMail? :) @@ -41,6 +47,23 @@ Push.Configure = function(options) { console.log('Push.Configure', options); } + WebApp.connectHandlers + .use(bodyParser.urlencoded()) + .use(bodyParser.json()) + .use('/push-manifest.json', function(req, res, next) { + + // necessary for Collection use and other wrapped methods + Fiber(function() { + res.writeHead(200, {'Content-Type': 'application/json'}); + //console.log(self.config) + + res.end(JSON.stringify(options.browser)); + //HTTP.get(Meteor.absoluteUrl("/config.push.json")).data; + //res.end(Assets.getText("config.push.json")); + + }).run(); + }); + // This function is called when a token is replaced on a device - normally // this should not happen, but if it does we should take action on it _replaceToken = function(currentToken, newToken) { diff --git a/plugin/push.configuration.js b/plugin/push.configuration.js index 34a0849..523b5b9 100644 --- a/plugin/push.configuration.js +++ b/plugin/push.configuration.js @@ -4,6 +4,7 @@ var stripComments = Npm.require('strip-json-comments'); // Check the config and log errors var checkConfig = function(config) { // jshint ignore:line check(config, { + browser: Match.Optional(Object), apn: Match.Optional({ passphrase: String, cert: String, @@ -54,6 +55,7 @@ var clone = function(name, config, result) { }; var cloneCommon = function(config, result) { + clone('browser', config, result); clone('production', config, result); clone('sound', config, result); clone('badge', config, result); @@ -189,7 +191,6 @@ Plugin.registerSourceHandler('push.json', function(compileStep) { try { // Try parsing the json var config = JSON.parse(configString); - // Clone the relevant config var cloneConfig = archConfig[compileStep.arch]; From 4e5874229be71d20b83515c26ce0efd725ce608a Mon Sep 17 00:00:00 2001 From: neobii Date: Wed, 25 May 2016 06:14:28 -0400 Subject: [PATCH 6/6] cleaned up push pacakage more --- README.md | 3 + browser/push-manifest.json | 13 -- lib/client/browser.js | 343 +++++++++---------------------------- lib/client/browserPush.js | 126 -------------- package.js | 5 - 5 files changed, 83 insertions(+), 407 deletions(-) delete mode 100644 browser/push-manifest.json delete mode 100644 lib/client/browserPush.js diff --git a/README.md b/README.md index c1531da..b2d41e0 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ Add a `config.push.json` file in your project and configure credentials / keys / ```js { + "browser": { + //manifest.json contents goes here + }, "apn": { "passphrase": "xxxxxxxxx", "key": "apnProdKey.pem", diff --git a/browser/push-manifest.json b/browser/push-manifest.json deleted file mode 100644 index e25c25a..0000000 --- a/browser/push-manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "code33chat", - "short_name": "code33chat", - "icons": [{ - "src": "images/defaultPic.jpg", - "sizes": "148x148", - "type": "image/jpg" - }], - "start_url": "/", - "display": "standalone", - "gcm_sender_id": "959772988286", - "gcm_user_visible_only": true -} \ No newline at end of file diff --git a/lib/client/browser.js b/lib/client/browser.js index 18ddfbe..c4b4dc6 100644 --- a/lib/client/browser.js +++ b/lib/client/browser.js @@ -64,269 +64,86 @@ Push.Configure = function(options) { // Start token updates initPushUpdates(options.appName); - Push.browserInit(); - // Add support for the raix:iframe push solution Deprecate this at some - // point mid aug 2015 - if (options.iframe) { - - var coldstart = true; - var startupTime = new Date(); - var startupThreshold = 1000; // ms - - var _atStartup = function() { - // If startup time is less than startupThreshold ago then lets say this is - // at startup. - return (new Date() - startupTime < startupThreshold); - }; - - var _parsePayload = function(value) { - // Android actually parses payload into an object - this is not the case with - // iOS (here is it just a string) - if (value !== ''+value) { - value = JSON.stringify(value); - } - - // Run the string through ejson - try { - return EJSON.parse(value); - } catch(err) { - return { error: err }; - } - }; - - // Rig iframe event listeners - options.iframe.addEventListener('deviceready', function() { - - // Maintain properties - - // At initial startup set startup time - startupTime = new Date(); - - // Update flag if app coldstart - options.iframe.addEventListener("pause", function() { - coldstart = false; - }, false); - - options.iframe.addEventListener('resume', function() { - // Reset startup time at resume - startupTime = new Date(); - }); - - // EO Maintain properties - - options.iframe.addEventListener('pushLaunch', function(e) { - - if (e.event === 'message') { - // Android event - - var sound = e.soundname || e.payload.sound; - - // Only prefix sound if actual text found - if (sound && sound.length) { - sound = '/android_asset/www/' + sound; - } - - // XXX: Investigate if we need more defaults - var unifiedMessage = { - message: e.payload.message || e.msg || '', - sound: sound, - badge: e.payload.msgcnt, - // Coldstart on android is a bit inconsistent - its only set when the - // notification opens the app - coldstart: (e.coldstart === Boolean(e.coldstart)) ? e.coldstart : coldstart, - background: !e.foreground, - foreground: !!e.foreground, - // open: _atStartup(), // This is the iOS implementation - open: (e.coldstart === Boolean(e.coldstart)), // If set true / false its an open event - type: 'gcm.cordova' - }; - - // If payload.ejson this is an object - we hand it over to parsePayload, - // parsePayload will do the convertion for us - if (e.payload.ejson) { - unifiedMessage.payload = _parsePayload(e.payload.ejson); - } - - // Trigger notification - onNotification(unifiedMessage); - - } else { - // iOS event - var sound = e.sound; // jshint ignore: line - - // Only prefix sound if actual text found - if (sound && sound.length) { - sound = '' + sound; - } - - // XXX: Investigate if we need more defaults - var unifiedMessage = { // jshint ignore: line - message: e.alert, - sound: sound, - badge: e.badge, - coldstart: coldstart, - background: !e.foreground, - foreground: !!e.foreground, - open: _atStartup(), - type: 'apn.cordova' - }; - - // E.ejson should be a string - we send it directly to payload - if (e.ejson) { - unifiedMessage.payload = _parsePayload(e.ejson); - } - - // Trigger notification - onNotification(unifiedMessage); - - } - - }); - - - options.iframe.addEventListener('pushSuccess', function(evt) { - // Reformat into new event - self.emit('register', evt.success); - }); - - options.iframe.addEventListener('pushToken', function(evt) { - if (evt.androidToken) { - // Format the android token - Push.emitState('token', { gcm: evt.androidToken }); - } else if (evt.iosToken) { - // Format the ios token - Push.emitState('token', { apn: evt.iosToken }); - } - }); - - options.iframe.addEventListener('pushError', function(evt) { - Push.emit('error', { type: 'cordova.browser', error: evt.error || evt }); - }); - - }); - } // EO options iframe - - if (typeof chrome !== 'undefined' && chrome.gcm) { - // chrome.gcm api is supported! - // https://developer.chrome.com/extensions/gcm - - // Set max message size - // chrome.gcm.MAX_MESSAGE_SIZE = 4096; - - if (options.gcm.projectNumber) { - chrome.gcm.register(options.gcm.projectNumber, function(token) { - if (token) { - self.emitState('token', { gcm: token }); - } else { - // Error - self.emit('error', { type: 'gcm.browser', error: 'Access denied' }); - } - }); + Meteor.startup(function() { + if (Notification.permission === 'denied') { + console.warn('The user has blocked notifications.'); + return; } - - } else if ('safari' in window && 'pushNotification' in window.safari) { - // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW1 - - if (options.apn) { - - Meteor.startup(function() { - // Ensure that the user can receive Safari Push Notifications. - Push.browserInit(); - var permissionData = window.safari.pushNotification.permission(options.apn.websitePushId); - checkRemotePermission(permissionData); - }); - - var checkRemotePermission = function (permissionData) { - if (permissionData.permission === 'default') { - // This is a new web service URL and its validity is unknown. - window.safari.pushNotification.requestPermission( - options.apn.webServiceUrl, // The web service URL. - options.apn.websitePushId, // The Website Push ID. - {}, // Data that you choose to send to your server to help you identify the user. - checkRemotePermission // The callback function. - ); - } - else if (permissionData.permission === 'denied') { - // alert('denied'); - // The user said no. - self.emit('error', { type: 'apn.browser', error: 'Access denied' }); - } - else if (permissionData.permission === 'granted') { - // alert('granted'); - // The web service URL is a valid push provider, and the user said yes. - // permissionData.deviceToken is now available to use. - self.emitState('token', { apn: permissionData.deviceToken }); - } - }; - + if (!('showNotification' in ServiceWorkerRegistration.prototype)) { + console.warn('Notifications aren\'t supported.'); + return; } - - - } else if (navigator && navigator.push && navigator.push.register && navigator.mozSetMessageHandler) { - // check navigator.mozPush should be enough? - // https://wiki.mozilla.org/WebAPI/SimplePush - - var channel = 'push'; - - // Store the pushEndpoint - var pushEndpoint; - - Meteor.startup(function() { - setupAppRegistrations(); - }); - - function setupAppRegistrations() { // jshint ignore: line - // Issue a register() call - // to register to listen for a notification, - // you simply call push.register - // Here, we'll register a channel for "email" updates. - // Channels can be for anything the app would like to get notifications for. - var requestAccess = navigator.push.register(); - - requestAccess.onsuccess = function(e) { - // Store the endpoint - pushEndpoint = e.target.result; - - self.emitState('token', { - SimplePush: { - channel: channel, - endPoint: pushEndpoint - } - }); - }; - + // Check if push messaging is supported + if (!('PushManager' in window)) { + console.warn('Push messaging isn\'t supported.'); + return; } - - // Once we've registered, the AppServer can send version pings to the EndPoint. - // This will trigger a 'push' message to be sent to this handler. - navigator.mozSetMessageHandler('push', function(message) { - if (message.pushEndpoint === pushEndpoint) { - // Did we launch or were we already running? - self.emit('startup', message); - } - }); - - // // to unregister, you simply call.. - // AppFramework.addEventListener('user-logout', function() { - // navigator.push.unregister(pushEndpoint); - // }); - - // error recovery mechanism - // will be called very rarely, but application - // should register again when it is called - navigator.mozSetMessageHandler('register', function(/* e */) { - setupAppRegistrations(); - }); - - - - } - -}; - -/* -TODO: - -add event listener api - -*/ + Push.browserInit(); + }); +} + +Push.browserInit = function(){ + $("body").append(''); + navigator.serviceWorker.register('/packages/raix_push/browser/service-worker.js').then(initialiseState); +} + +Push.browserUnsubscribe = function() { + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + serviceWorkerRegistration.pushManager.getSubscription().then( + function(pushSubscription) { + if (!pushSubscription) { + isPushEnabled = false; + return; + } + + var subscriptionId = pushSubscription.subscriptionId; + pushSubscription.unsubscribe().then(function(successful) { + isPushEnabled = false; + }).catch(function(e) { + console.log('Unsubscription error: ', e); + }); + }).catch(function(e) { + console.error('Error thrown while unsubscribing from push messaging.', e); + }); + }); +} + +Push.browserSubscribe = function() { + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true}) + .then(function(subscription) { + return sendSubscriptionToServer(subscription); + }) + .catch(function(e) { + if (Notification.permission === 'denied') { + console.warn('Permission for Notifications was denied'); + } else { + console.error('Unable to subscribe to push.', e); + } + }); + }); +} + +function sendSubscriptionToServer(subscription){ + Push.emit('startup', subscription); + /*Push.emitState('token', { + SimplePush: { + channel: "push", + endPoint: subscription.endpoint + } + });*/ +} + +function initialiseState() { + navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { + serviceWorkerRegistration.pushManager.getSubscription() + .then(function(subscription) { + if (subscription) { + sendSubscriptionToServer(subscription); + } + }) + .catch(function(err) { + console.warn('Error during getSubscription()', err); + }); + }); +} \ No newline at end of file diff --git a/lib/client/browserPush.js b/lib/client/browserPush.js deleted file mode 100644 index ceeae34..0000000 --- a/lib/client/browserPush.js +++ /dev/null @@ -1,126 +0,0 @@ -Push.browserInit = function(){ - $("body").append(''); - navigator.serviceWorker.register('/packages/raix_push/browser/service-worker.js').then(initialiseState); -} - - -function initialiseState() { - // Are Notifications supported in the service worker? - if (!('showNotification' in ServiceWorkerRegistration.prototype)) { - console.warn('Notifications aren\'t supported.'); - return; - } - - // Check the current Notification permission. - // If its denied, it's a permanent block until the - // user changes the permission - if (Notification.permission === 'denied') { - console.warn('The user has blocked notifications.'); - return; - } - - // Check if push messaging is supported - if (!('PushManager' in window)) { - console.warn('Push messaging isn\'t supported.'); - return; - } - - // We need the service worker registration to check for a subscription - navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { - // Do we already have a push message subscription? - serviceWorkerRegistration.pushManager.getSubscription() - .then(function(subscription) { - if (!subscription) { - // We aren't subscribed to push, so set UI - // to allow the user to enable push - return; - } - // Keep your server in sync with the latest subscriptionId - sendSubscriptionToServer(subscription); - }) - .catch(function(err) { - console.warn('Error during getSubscription()', err); - }); - }); -} - -Push.browserUnsubscribe = function() { - - navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { - // To unsubscribe from push messaging, you need get the - // subscription object, which you can call unsubscribe() on. - serviceWorkerRegistration.pushManager.getSubscription().then( - function(pushSubscription) { - // Check we have a subscription to unsubscribe - if (!pushSubscription) { - // No subscription object, so set the state - // to allow the user to subscribe to push - isPushEnabled = false; - return; - } - - var subscriptionId = pushSubscription.subscriptionId; - // TODO: Make a request to your server to remove - // the subscriptionId from your data store so you - // don't attempt to send them push messages anymore - - // We have a subscription, so call unsubscribe on it - pushSubscription.unsubscribe().then(function(successful) { - isPushEnabled = false; - }).catch(function(e) { - // We failed to unsubscribe, this can lead to - // an unusual state, so may be best to remove - // the users data from your data store and - // inform the user that you have done so - - console.log('Unsubscription error: ', e); - }); - }).catch(function(e) { - console.error('Error thrown while unsubscribing from push messaging.', e); - }); - }); -} - -Push.browserSubscribe = function() { - // Disable the button so it can't be changed while - // we process the permission request - - navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) { - serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true}) - .then(function(subscription) { - // The subscription was successful - console.log("success"); - self.emitState('token', { - SimplePush: { - channel: "push", - endPoint: subscription.endpoint - } - }); - return sendSubscriptionToServer(subscription); - }) - .catch(function(e) { - if (Notification.permission === 'denied') { - // The user denied the notification permission which - // means we failed to subscribe and the user will need - // to manually change the notification permission to - // subscribe to push messages - console.warn('Permission for Notifications was denied'); - - } else { - // A problem occurred with the subscription; common reasons - // include network errors, and lacking gcm_sender_id and/or - // gcm_user_visible_only in the manifest. - console.error('Unable to subscribe to push.', e); - } - }); - }); -} - -function sendSubscriptonToServer(subscription){ - /*self.emitState('token', { - SimplePush: { - channel: "push", - endPoint: subscription.endpoint - } - })*/ -} \ No newline at end of file diff --git a/package.js b/package.js index 4dba545..6487bfd 100644 --- a/package.js +++ b/package.js @@ -58,7 +58,6 @@ Package.onUse(function(api) { api.use('mongo', 'server'); // public for browser -// api.addFiles('browser/push-manifest.json', 'web.browser', {isAsset: true}); api.addFiles('browser/service-worker.js', 'web.browser', {isAsset: true}); // API @@ -76,16 +75,12 @@ Package.onUse(function(api) { // API's api.addFiles('lib/client/browser.js', 'web.browser'); - api.addFiles('lib/client/browserPush.js', 'web.browser'); api.addFiles('lib/server/push.api.js', 'server'); // // Unified api api.addFiles('lib/client/client.js', 'client'); api.addFiles('lib/server/server.js', 'server'); - //browser - api.addFiles('lib/server/manifest.js', 'server'); - api.export('Push'); api.export('_matchToken', { testOnly: true });