Browse Source

Initial Web Push support

#981
master
Igor Zhukov 8 years ago
parent
commit
820eb3e16f
  1. 3
      app/js/lib/config.js
  2. 110
      app/js/lib/ng_utils.js
  3. 48
      app/js/lib/push_worker.js
  4. 74
      app/js/services.js
  5. 4
      app/service_worker.js

3
app/js/lib/config.js

@ -37,7 +37,8 @@ Config.Modes = {
ios_standalone: window.navigator.standalone && navigator.userAgent.match(/iOS|iPhone|iPad/), ios_standalone: window.navigator.standalone && navigator.userAgent.match(/iOS|iPhone|iPad/),
chrome_packed: window.chrome && chrome.app && chrome.app.window && true || false, chrome_packed: window.chrome && chrome.app && chrome.app.window && true || false,
animations: true, animations: true,
memory_only: false memory_only: false,
push_api: location.search.indexOf('push=1') == -1
} }
Config.Navigator = { Config.Navigator = {

110
app/js/lib/ng_utils.js

@ -1980,3 +1980,113 @@ angular.module('izhukov.utils', [])
return timeParams return timeParams
}) })
.service('WebPushApiManager', function ($timeout, $q, $rootScope) {
var isAvailable = true
var isPushEnabled = false
var started = false
if (!('PushManager' in window) ||
!('Notification' in window) ||
!('serviceWorker' in navigator)) {
console.warn('Push messaging is not supported.')
isAvailable = false
}
if (Notification.permission === 'denied') {
console.warn('The user has blocked notifications.')
}
function start() {
if (!started) {
started = true
getSubscription()
}
}
function getSubscription() {
if (!isAvailable) {
return
}
navigator.serviceWorker.ready.then(function(reg) {
reg.pushManager.getSubscription().then(function(subscription) {
if (!subscription) {
console.log('Not yet subscribed to Push')
subscribe()
return
}
isPushEnabled = true
pushSubscriptionNotify('init', subscription)
})
.catch(function(err) {
console.log('Error during getSubscription()', err)
})
})
}
function subscribe() {
if (!isAvailable) {
return
}
navigator.serviceWorker.ready.then(function(reg) {
reg.pushManager.subscribe({userVisibleOnly: true}).then(function(subscription) {
// The subscription was successful
isPushEnabled = true
pushSubscriptionNotify('subscribe', subscription)
})
.catch(function(e) {
if (Notification.permission === 'denied') {
console.log('Permission for Notifications was denied')
} else {
console.log('Unable to subscribe to push.', e)
}
})
})
}
function unsubscribe() {
if (!isAvailable) {
return
}
navigator.serviceWorker.ready.then(function(reg) {
reg.pushManager.getSubscription().then(function (subscription) {
pushSubscriptionNotify('unsubscribe', subscription)
isPushEnabled = false
if (subscription) {
setTimeout(function() {
subscription.unsubscribe().then(function(successful) {
isPushEnabled = false
}).catch(function(e) {
console.error('Unsubscription error: ', e)
})
}, 3000)
}
}).catch(function(e) {
console.error('Error thrown while unsubscribing from ' +
'push messaging.', e)
})
})
}
function pushSubscriptionNotify(event, subscription) {
console.warn(dT(), 'Push', event, subscription.toJSON())
$rootScope.$emit('push_' + event, {
tokenType: 10,
tokenValue: JSON.stringify(subscription.toJSON())
})
}
return {
isAvailable: isAvailable,
start: start,
isPushEnabled: isPushEnabled,
subscribe: subscribe,
unsubscribe: unsubscribe
}
})

48
app/js/lib/push_worker.js

@ -1 +1,47 @@
console.log('push worker placeholder') console.log('Push worker placeholder')
var port
self.addEventListener('push', function(event) {
var obj = event.data.json()
console.log('push obj', obj)
fireNotification(obj, event)
})
self.onmessage = function(e) {
console.log(e)
port = e.ports[0]
}
function fireNotification(obj, event) {
var title = obj.title || 'Telegram'
var body = obj.description || ''
var icon = 'img/Telegram72.png'
event.waitUntil(self.registration.showNotification(title, {
body: body,
icon: icon
}))
}
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag)
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 ('focus' in client) {
return client.focus()
}
}
if (clients.openWindow)
return clients.openWindow('')
}))
})

74
app/js/services.js

@ -3516,7 +3516,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
}) })
.service('NotificationsManager', function ($rootScope, $window, $interval, $q, _, MtpApiManager, AppPeersManager, IdleManager, Storage, AppRuntimeManager, FileManager) { .service('NotificationsManager', function ($rootScope, $window, $interval, $q, _, MtpApiManager, AppPeersManager, IdleManager, Storage, AppRuntimeManager, FileManager, WebPushApiManager) {
navigator.vibrate = navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate navigator.vibrate = navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate
var notificationsMsSiteMode = false var notificationsMsSiteMode = false
@ -3598,18 +3598,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}) })
var registeredDevice = false var registeredDevice = false
if (window.navigator.mozSetMessageHandler) { $rootScope.$on('push_init', function (e, tokenData) {
window.navigator.mozSetMessageHandler('push', function (e) { if (tokenData) {
console.log(dT(), 'received push', e) registerDevice(tokenData)
$rootScope.$broadcast('push_received') }
}) })
$rootScope.$on('push_subscribe', function (e, tokenData) {
window.navigator.mozSetMessageHandler('push-register', function (e) { registerDevice(tokenData)
console.log(dT(), 'received push', e) })
registeredDevice = false $rootScope.$on('push_unsubscribe', function (e, tokenData) {
registerDevice() unregisterDevice(tokenData)
}) })
}
return { return {
start: start, start: start,
@ -3702,7 +3701,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function start () { function start () {
updateNotifySettings() updateNotifySettings()
$rootScope.$on('settings_changed', updateNotifySettings) $rootScope.$on('settings_changed', updateNotifySettings)
registerDevice() WebPushApiManager.start()
if (!notificationsUiSupport) { if (!notificationsUiSupport) {
return false return false
@ -3904,40 +3903,26 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
notificationsCount = 0 notificationsCount = 0
} }
var registerDevicePeriod = 1000 function registerDevice (tokenData) {
var registerDeviceTO if (registeredDevice &&
function registerDevice () { angular.equals(registeredDevice, tokenData)) {
if (registeredDevice) {
return false return false
} }
if (navigator.push && Config.Navigator.ffos && Config.Modes.packed) { MtpApiManager.invokeApi('account.registerDevice', {
var req = navigator.push.register() token_type: tokenData.tokenType,
token: tokenData.tokenValue
req.onsuccess = function (e) { }).then(function () {
clearTimeout(registerDeviceTO) registeredDevice = tokenData
console.log(dT(), 'Push registered', req.result) })
registeredDevice = req.result
MtpApiManager.invokeApi('account.registerDevice', {
token_type: 4,
token: registeredDevice
})
}
req.onerror = function (e) {
console.error('Push register error', e, e.toString())
registerDeviceTO = setTimeout(registerDevice, registerDevicePeriod)
registerDevicePeriod = Math.min(30000, registerDevicePeriod * 1.5)
}
}
} }
function unregisterDevice () { function unregisterDevice (tokenData) {
if (!registeredDevice) { if (!registeredDevice) {
return false return false
} }
MtpApiManager.invokeApi('account.unregisterDevice', { MtpApiManager.invokeApi('account.unregisterDevice', {
token_type: 4, token_type: tokenData.tokenType,
token: registeredDevice token: tokenData.tokenValue
}).then(function () { }).then(function () {
registeredDevice = false registeredDevice = false
}) })
@ -4533,15 +4518,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
started = true started = true
if ('registerProtocolHandler' in navigator) {
try {
navigator.registerProtocolHandler('tg', '#im?tgaddr=%s', 'Telegram Web')
} catch (e) {}
try {
navigator.registerProtocolHandler('web+tg', '#im?tgaddr=%s', 'Telegram Web')
} catch (e) {}
}
if (window.navigator.mozSetMessageHandler) { if (window.navigator.mozSetMessageHandler) {
console.log(dT(), 'Set activity message handler') console.log(dT(), 'Set activity message handler')
window.navigator.mozSetMessageHandler('activity', function (activityRequest) { window.navigator.mozSetMessageHandler('activity', function (activityRequest) {

4
app/service_worker.js

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

Loading…
Cancel
Save