diff --git a/www/plugins/es/i18n/locale-en-GB.json b/www/plugins/es/i18n/locale-en-GB.json index 479cd428326aa5568319031f5e4798d120ee919b..566a25eb522852232db62c5ff02fb21fb0a0a385 100644 --- a/www/plugins/es/i18n/locale-en-GB.json +++ b/www/plugins/es/i18n/locale-en-GB.json @@ -10,6 +10,10 @@ "BTN_PICTURE_FAVORISE": "Default", "BTN_PICTURE_ROTATE": "Rotate", "BTN_ADD_PICTURE": "Add picture", + "NOTIFICATION": { + "TITLE": "New notification | {{'COMMON.APP_NAME'|translate}}", + "HAS_UNREAD": "You have {{count}} unread notification{{count>0?'s':''}}" + }, "NOTIFICATIONS": { "TITLE": "Notifications", "MARK_ALL_AS_READ": "Mark all as read", diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json index 479cd428326aa5568319031f5e4798d120ee919b..566a25eb522852232db62c5ff02fb21fb0a0a385 100644 --- a/www/plugins/es/i18n/locale-en.json +++ b/www/plugins/es/i18n/locale-en.json @@ -10,6 +10,10 @@ "BTN_PICTURE_FAVORISE": "Default", "BTN_PICTURE_ROTATE": "Rotate", "BTN_ADD_PICTURE": "Add picture", + "NOTIFICATION": { + "TITLE": "New notification | {{'COMMON.APP_NAME'|translate}}", + "HAS_UNREAD": "You have {{count}} unread notification{{count>0?'s':''}}" + }, "NOTIFICATIONS": { "TITLE": "Notifications", "MARK_ALL_AS_READ": "Mark all as read", diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json index 022c8beab47f2bc049b4ef3c51988d6d13edcdee..62a7d7f1d5e5a444b55fc1259eab05d475b3c0a3 100644 --- a/www/plugins/es/i18n/locale-fr-FR.json +++ b/www/plugins/es/i18n/locale-fr-FR.json @@ -10,6 +10,10 @@ "BTN_PICTURE_FAVORISE": "Principale", "BTN_PICTURE_ROTATE": "Tourner", "BTN_ADD_PICTURE": "Ajouter une photo", + "NOTIFICATION": { + "TITLE": "Nouvelle notification | {{'COMMON.APP_NAME'|translate}}", + "HAS_UNREAD": "Vous avez {{count}} notification{{count>0?'s':''}} non lue{{count>0?'s':''}}" + }, "NOTIFICATIONS": { "TITLE": "Notifications", "MARK_ALL_AS_READ": "Tout marquer comme lu", diff --git a/www/plugins/es/js/entities/notification.js b/www/plugins/es/js/entities/notification.js index 43fb98aeb84b51150e9e9f464010921ca197f44e..3350deab2852dce94d84382c46e5801802bc3527 100644 --- a/www/plugins/es/js/entities/notification.js +++ b/www/plugins/es/js/entities/notification.js @@ -1,5 +1,5 @@ -function Notification(json, markAsReadCallback) { +function EsNotification(json, markAsReadCallback) { var messagePrefixes = { 'registry': 'EVENT.REGISTRY.' @@ -115,4 +115,6 @@ function Notification(json, markAsReadCallback) { that.avatarIcon = 'ion-close'; that.icon = 'ion-close-circled assertive'; } + + return that; } diff --git a/www/plugins/es/js/services/message-services.js b/www/plugins/es/js/services/message-services.js index 26439b291e6b511a29daf0f612709ea19f604bf8..a0f09c57f69203f40051672023e15474f32f4760 100644 --- a/www/plugins/es/js/services/message-services.js +++ b/www/plugins/es/js/services/message-services.js @@ -108,7 +108,7 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.platform', function onNewMessageEvent(event) { console.debug("[ES] [message] detected new message (from notification service)"); - var notification = new Notification(event); + var notification = new EsNotification(event); notification.issuer = notification.pubkey; delete notification.pubkey; diff --git a/www/plugins/es/js/services/notification-services.js b/www/plugins/es/js/services/notification-services.js index 466f4322eb3e7611100852b39bf34990f27466ab..ebfb03828599e810bf71303cc9551328dca4d353 100644 --- a/www/plugins/es/js/services/notification-services.js +++ b/www/plugins/es/js/services/notification-services.js @@ -10,7 +10,7 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es }) -.factory('esNotification', function($rootScope, $q, $timeout, +.factory('esNotification', function($rootScope, $q, $timeout, $translate, $state, esHttp, csConfig, csSettings, csWallet, csWot, UIUtils, filterTranslations, BMA, CryptoUtils, csPlatform, Api) { 'ngInject'; @@ -158,7 +158,7 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es } var notifications = res.hits.hits.reduce(function(res, hit) { - var item = new Notification(hit._source, markNotificationAsRead); + var item = new EsNotification(hit._source, markNotificationAsRead); item.id = hit._id; return res.concat(item); }, events || []); @@ -182,7 +182,7 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es return; } - var notification = new Notification(event, markNotificationAsRead); + var notification = new EsNotification(event, markNotificationAsRead); // Extend the notification entity return csWot.extendAll([notification]) @@ -195,6 +195,9 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es else { addNewNotification(notification); } + }) + .then(function() { + return emitEsNotification(notification); }); } @@ -202,6 +205,66 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es csWallet.data.notifications = csWallet.data.notifications || {}; csWallet.data.notifications.unreadCount++; api.data.raise.new(notification); + + return notification; + } + + function htmlToPlaintext(text) { + return text ? String(text).replace(/<[^>]*>/gm, '').replace(/&[^;]+;/gm, '') : ''; + } + + function emitEsNotification(notification, title) { + + // If it's okay let's create a notification + $q.all([ + $translate(title||'COMMON.NOTIFICATION.TITLE'), + $translate(notification.message, notification) + ]) + .then(function(res) { + var title = htmlToPlaintext(res[0]); + var body = htmlToPlaintext(res[1]); + var icon = notification.avatar && notification.avatar.src || './img/logo.png'; + emitHtml5Notification(title, { + body: body, + icon: icon, + lang: $translate.use(), + tag: notification.id, + onclick: function() { + $rootScope.$applyAsync(function() { + if (typeof notification.markAsRead === "function") { + notification.markAsRead(); + } + if (notification.state) { + $state.go(notification.state, notification.stateParams); + } + }); + } + }); + }); + } + + function emitHtml5Notification(title, options) { + + // Let's check if the browser supports notifications + if (!("Notification" in window)) return; + + // Let's check whether notification permissions have already been granted + if (Notification.permission === "granted") { + + // If it's okay let's create a notification + var browserNotification = new Notification(title, options); + browserNotification.onclick = options.onclick || browserNotification.onclick; + } + + // Otherwise, we need to ask the user for permission + else if (Notification.permission !== "denied") { + Notification.requestPermission(function (permission) { + // If the user accepts, let's create a notification + if (permission === "granted") { + emitHtml5Notification(title, options); // recursive call + } + }); + } } // Mark a notification as read @@ -276,6 +339,17 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es data.notifications.unreadCount = unreadCount; data.notifications.warnCount = countWarnEvents(data); + // Emit HTML5 notification + if (unreadCount > 0) { + $timeout(function() { + emitEsNotification({ + message: 'COMMON.NOTIFICATION.HAS_UNREAD', + count: unreadCount, + state: 'app.view_notifications' + }, 'COMMON.APP_NAME'); + }, 500); + } + console.debug('[ES] [notification] Loaded count (' + unreadCount + ') in '+(Date.now()-now)+'ms'); deferred.resolve(data); }) @@ -364,6 +438,9 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es // Exports that.load = loadNotifications; that.unreadCount = loadUnreadNotificationsCount; + that.html5 = { + emit: emitHtml5Notification + }; that.api = api; that.websocket = { event: that.raw.ws.getUserEvent,