Browse Source

Notifications bugfixes

master
Igor Zhukov 8 years ago
parent
commit
a6cf0a7772
  1. 3
      app/js/directives.js
  2. 41
      app/js/lib/ng_utils.js
  3. 72
      app/js/lib/push_worker.js
  4. 6
      app/js/locales/en-us.json
  5. 23
      app/js/services.js
  6. 3
      app/partials/desktop/error_modal.html
  7. 4
      app/service_worker.js

3
app/js/directives.js

@ -803,7 +803,8 @@ angular.module('myApp.directives', ['myApp.filters'])
if (searchFocused && e.keyCode == 13 && !Config.Navigator.mobile) { // Enter if (searchFocused && e.keyCode == 13 && !Config.Navigator.mobile) { // Enter
var currentSelected = $(scrollableWrap).find('.im_dialog_selected')[0] || $(scrollableWrap).find('.im_dialog_wrap a')[0] var currentSelected = $(scrollableWrap).find('.im_dialog_selected')[0] || $(scrollableWrap).find('.im_dialog_wrap a')[0]
if (currentSelected) { if (currentSelected &&
!$(currentSelected).hasClass('disabled')) {
$(currentSelected).trigger('mousedown') $(currentSelected).trigger('mousedown')
} }
return cancelEvent(e) return cancelEvent(e)

41
app/js/lib/ng_utils.js

@ -1981,17 +1981,21 @@ angular.module('izhukov.utils', [])
return timeParams return timeParams
}) })
.service('WebPushApiManager', function ($window, $timeout, $q, $rootScope, AppRuntimeManager) { .service('WebPushApiManager', function ($window, $timeout, $q, $rootScope, _, AppRuntimeManager) {
var isAvailable = true var isAvailable = true
var isPushEnabled = false var isPushEnabled = false
var localNotificationsAvailable = true
var started = false var started = false
var settings = {}
var isAliveTO
if (!('PushManager' in window) || if (!('PushManager' in window) ||
!('Notification' in window) || !('Notification' in window) ||
!('serviceWorker' in navigator)) { !('serviceWorker' in navigator)) {
console.warn('Push messaging is not supported.') console.warn('Push messaging is not supported.')
isAvailable = false isAvailable = false
localNotificationsAvailable = false
} }
if (Notification.permission === 'denied') { if (Notification.permission === 'denied') {
@ -2006,6 +2010,10 @@ angular.module('izhukov.utils', [])
} }
} }
function setLocalNotificationsDisabled() {
localNotificationsAvailable = false
}
function getSubscription() { function getSubscription() {
if (!isAvailable) { if (!isAvailable) {
return return
@ -2073,12 +2081,33 @@ angular.module('izhukov.utils', [])
$rootScope.idle && $rootScope.idle.deactivated) { $rootScope.idle && $rootScope.idle.deactivated) {
return return
} }
var baseUrl = (location.href || '').replace(/#.*$/, '') + '#/im' var eventData = {
var eventData = {type: 'alive', baseUrl: baseUrl} type: 'ping',
localNotifications: localNotificationsAvailable,
baseUrl: (location.href || '').replace(/#.*$/, '') + '#/im',
lang: {
push_action_mute1d: _(Config.Mobile
? 'push_action_mute1d_mobile_raw'
: 'push_action_mute1d_raw'
),
push_action_settings: _(Config.Mobile
? 'push_action_settings_mobile_raw'
: 'push_action_settings_raw'
),
push_message_nopreview: _('push_message_nopreview_raw'),
},
settings: settings
}
if (navigator.serviceWorker.controller) { if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage(eventData) navigator.serviceWorker.controller.postMessage(eventData)
} }
setTimeout(isAliveNotify, 10000) isAliveTO = setTimeout(isAliveNotify, 10000)
}
function setSettings(newSettings) {
settings = newSettings
clearTimeout(isAliveTO)
isAliveNotify()
} }
function hidePushNotifications() { function hidePushNotifications() {
@ -2128,7 +2157,9 @@ angular.module('izhukov.utils', [])
isPushEnabled: isPushEnabled, isPushEnabled: isPushEnabled,
subscribe: subscribe, subscribe: subscribe,
unsubscribe: unsubscribe, unsubscribe: unsubscribe,
hidePushNotifications: hidePushNotifications hidePushNotifications: hidePushNotifications,
setLocalNotificationsDisabled: setLocalNotificationsDisabled,
setSettings: setSettings
} }
}) })

72
app/js/lib/push_worker.js

@ -8,6 +8,9 @@ var lastAliveTime = false
var pendingNotification = false var pendingNotification = false
var muteUntil = false var muteUntil = false
var baseUrl var baseUrl
var settings
var lang = {}
switch (location.hostname) { switch (location.hostname) {
case 'localhost': case 'localhost':
baseUrl = 'http://localhost:8000/app/index.html#/im' baseUrl = 'http://localhost:8000/app/index.html#/im'
@ -24,7 +27,9 @@ self.addEventListener('push', function(event) {
var obj = event.data.json() var obj = event.data.json()
console.log('[SW] push', obj) console.log('[SW] push', obj)
if (!obj.badge) { if (!obj.badge) {
closeAllNotifications(obj, event) event.waitUntil(self.registration.showNotification('Telegram').then(function () {
return closeAllNotifications(obj)
}))
} else { } else {
fireNotification(obj, event) fireNotification(obj, event)
} }
@ -37,19 +42,30 @@ self.addEventListener('activate', function(event) {
self.addEventListener('message', function(event) { self.addEventListener('message', function(event) {
console.log('[SW] on message', event.data) console.log('[SW] on message', event.data)
port = event.ports[0] || event.source var client = event.ports[0] || event.source
if (event.data.type == 'alive') { if (event.data.type == 'ping') {
lastAliveTime = +(new Date()) if (event.data.localNotifications) {
lastAliveTime = +(new Date())
}
if (pendingNotification && if (pendingNotification &&
port && client &&
'postMessage' in port) { 'postMessage' in client) {
port.postMessage(pendingNotification) client.postMessage(pendingNotification)
pendingNotification = false pendingNotification = false
} }
if (event.data.lang) {
lang = event.data.lang
IDBManager.setItem('push_lang', lang)
}
if (event.data.settings) {
settings = event.data.settings
IDBManager.setItem('push_settings', settings)
}
} }
if (event.data.type == 'notifications_clear') { if (event.data.type == 'notifications_clear') {
closeAllNotifications(event.data, event) closeAllNotifications(event.data)
} }
if (event.data.baseUrl) { if (event.data.baseUrl) {
baseUrl = event.data.baseUrl baseUrl = event.data.baseUrl
@ -60,7 +76,7 @@ function fireNotification(obj, event) {
var nowTime = +(new Date()) var nowTime = +(new Date())
if (nowTime - lastAliveTime < 60000) { if (nowTime - lastAliveTime < 60000) {
console.log('Supress notification because some instance is alive') console.log('Supress notification because some instance is alive')
return false // return false
} }
if (muteUntil && nowTime < muteUntil) { if (muteUntil && nowTime < muteUntil) {
console.log('Supress notification because mute for ', (muteUntil - nowTime) / 60000, 'min') console.log('Supress notification because mute for ', (muteUntil - nowTime) / 60000, 'min')
@ -82,20 +98,27 @@ function fireNotification(obj, event) {
peerID = obj.custom && obj.custom.from_id || 0 peerID = obj.custom && obj.custom.from_id || 0
} }
obj.custom.peerID = peerID obj.custom.peerID = peerID
var tag = 'peer' + peerID
if (settings && settings.nopreview) {
title = 'Telegram'
body = lang.push_message_nopreview || 'You have a new message'
tag = 'unknown_peer'
}
var notificationPromise = self.registration.showNotification(title, { var notificationPromise = self.registration.showNotification(title, {
body: body, body: body,
icon: icon, icon: icon,
tag: 'peer' + peerID, tag: tag,
data: obj, data: obj,
actions: [ actions: [
{ {
action: 'mute1d', action: 'mute1d',
title: 'Mute background alerts for 1 day' title: lang.push_action_mute1d || 'Mute for 1D'
}, },
{ {
action: 'push_settings', action: 'push_settings',
title: 'Background alerts settings' title: lang.push_action_settings || 'Settings'
} }
] ]
}) })
@ -133,22 +156,24 @@ function removeFromNotifications(notification) {
} }
} }
function closeAllNotifications(obj, event) { function closeAllNotifications(obj) {
for (var i = 0, len = notifications.length; i < len; i++) { for (var i = 0, len = notifications.length; i < len; i++) {
try { try {
notifications[i].close() notifications[i].close()
} catch (e) {} } catch (e) {}
} }
event.waitUntil(self.registration.getNotifications({}).then(function(notifications) { var p = self.registration.getNotifications({}).then(function(notifications) {
for (var i = 0, len = notifications.length; i < len; i++) { for (var i = 0, len = notifications.length; i < len; i++) {
try { try {
notifications[i].close() notifications[i].close()
} catch (e) {} } catch (e) {}
} }
})) })
notifications = [] notifications = []
return p
} }
@ -161,7 +186,10 @@ self.addEventListener('notificationclick', function(event) {
if (action == 'mute1d') { if (action == 'mute1d') {
console.log('[SW] mute for 1d') console.log('[SW] mute for 1d')
muteUntil = +(new Date()) + 86400000 muteUntil = +(new Date()) + 86400000
IDBManager.setItem('mute_until', muteUntil.toString()) IDBManager.setItem('push_mute_until', muteUntil.toString())
return
}
if (!notification.data) {
return return
} }
@ -174,7 +202,7 @@ self.addEventListener('notificationclick', function(event) {
var client = clientList[i] var client = clientList[i]
if ('focus' in client) { if ('focus' in client) {
client.focus() client.focus()
;(port || client).postMessage(pendingNotification) client.postMessage(pendingNotification)
pendingNotification = false pendingNotification = false
return return
} }
@ -318,6 +346,14 @@ self.addEventListener('notificationclose', onCloseNotification)
IDBManager.getItem('mute_until').then(function (newMuteUntil) { IDBManager.getItem('push_mute_until').then(function (newMuteUntil) {
muteUntil = Math.max(muteUntil || 0, newMuteUntil || 0) || false muteUntil = Math.max(muteUntil || 0, newMuteUntil || 0) || false
})
IDBManager.getItem('push_lang').then(function (newLang) {
lang = newLang || {}
})
IDBManager.getItem('push_settings').then(function (newSettings) {
settings = newSettings || {}
}) })

6
app/js/locales/en-us.json

@ -601,6 +601,12 @@
"inactive_description_md": "Telegram supports only one active tab with the app.\nPlease reload this page to continue using this tab or close it.", "inactive_description_md": "Telegram supports only one active tab with the app.\nPlease reload this page to continue using this tab or close it.",
"inactive_reload_btn": "Reload App", "inactive_reload_btn": "Reload App",
"push_action_mute1d": "Mute background alerts for 1 day",
"push_action_settings": "Background alerts settings",
"push_action_mute1d_mobile": "Mute for 24H",
"push_action_settings_mobile": "Alerts settings",
"push_message_nopreview": "You have a new message",
"country_select_modal_country_ab": "Abkhazia", "country_select_modal_country_ab": "Abkhazia",
"country_select_modal_country_af": "Afghanistan", "country_select_modal_country_af": "Afghanistan",

23
app/js/services.js

@ -3693,6 +3693,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
} }
} }
WebPushApiManager.setSettings(settings)
}) })
} }
@ -3846,11 +3847,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var notification var notification
if ('Notification' in window) { if ('Notification' in window) {
notification = new Notification(data.title, { try {
icon: data.image || '', notification = new Notification(data.title, {
body: data.message || '', icon: data.image || '',
tag: data.tag || '' body: data.message || '',
}) tag: data.tag || ''
})
} catch (e) {
notificationsUiSupport = false
WebPushApiManager.setLocalNotificationsDisabled()
return
}
} }
else if ('mozNotification' in navigator) { else if ('mozNotification' in navigator) {
notification = navigator.mozNotification.createNotification(data.title, data.message || '', data.image || '') notification = navigator.mozNotification.createNotification(data.title, data.message || '', data.image || '')
@ -3862,7 +3869,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
notification = { notification = {
index: idx index: idx
} }
}else { } else {
return return
} }
@ -3973,6 +3980,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
token: tokenData.tokenValue token: tokenData.tokenValue
}).then(function () { }).then(function () {
registeredDevice = tokenData registeredDevice = tokenData
}, function (error) {
error.handled = true
}) })
} }
@ -3985,6 +3994,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
token: tokenData.tokenValue token: tokenData.tokenValue
}).then(function () { }).then(function () {
registeredDevice = false registeredDevice = false
}, function (error) {
error.handled = true
}) })
} }

3
app/partials/desktop/error_modal.html

@ -72,8 +72,7 @@
<div ng-if="error" class="error_modal_details" ng-switch="error.detailsShown"> <div ng-if="error" class="error_modal_details" ng-switch="error.detailsShown">
<textarea ng-switch-when="true" rows="3" onclick="this.select()">Method: {{error.input || 'N/A'}} <textarea ng-switch-when="true" rows="3" onclick="this.select()">Method: {{error.input || 'N/A'}}
Url: {{error.url || 'N/A'}} Url: {{error.url || 'N/A'}}
Result: {{error.originalError ? error.originalError : (error.stack ? (error.name || '') + ' ' + (error.description || error.message) : error)}} Result: {{error.originalError ? error.originalError : (error.stack ? (error.name || '') + ' ' + (error.description || error.message) : error)}}</textarea>
Stack: {{error.originalError.stack || error.stack}}</textarea>
<div ng-switch-default> <div ng-switch-default>
<a class="error_modal_details_link" href="" ng-click="error.detailsShown = true" my-i18n="error_modal_tech_details"></a> <a class="error_modal_details_link" href="" ng-click="error.detailsShown = true" my-i18n="error_modal_tech_details"></a>
</div> </div>

4
app/service_worker.js

@ -1,3 +1,3 @@
// Version 44 // Version 45
importScripts('js/lib/push_worker.js?44') importScripts('js/lib/push_worker.js?45')

Loading…
Cancel
Save