2014-08-28 18:25:40 +02:00
var weechat = angular . module ( 'weechat' ) ;
2014-12-22 22:17:01 +01:00
weechat . factory ( 'notifications' , [ '$rootScope' , '$log' , 'models' , 'settings' , function ( $rootScope , $log , models , settings ) {
2015-12-20 15:07:28 +01:00
var serviceworker = false ;
2014-12-22 22:17:01 +01:00
var notifications = [ ] ;
2015-12-20 15:07:28 +01:00
// Ask for permission to display desktop notifications
2014-08-28 18:25:40 +02:00
var requestNotificationPermission = function ( ) {
// Firefox
if ( window . Notification ) {
Notification . requestPermission ( function ( status ) {
$log . info ( 'Notification permission status: ' , status ) ;
if ( Notification . permission !== status ) {
Notification . permission = status ;
}
} ) ;
}
// Webkit
if ( window . webkitNotifications !== undefined ) {
var havePermission = window . webkitNotifications . checkPermission ( ) ;
if ( havePermission !== 0 ) { // 0 is PERMISSION_ALLOWED
$log . info ( 'Notification permission status: ' , havePermission === 0 ) ;
window . webkitNotifications . requestPermission ( ) ;
}
}
2015-12-20 15:07:28 +01:00
2016-04-01 14:04:31 +02:00
// Check for serviceWorker support, and also disable serviceWorker if we're running in electron process, since that's just problematic and not necessary, since gb then already is in a separate process
if ( 'serviceWorker' in navigator && ( typeof window !== 'undefined' && window . process && window . process . type === "renderer" ) ) {
2015-12-20 15:07:28 +01:00
$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 ) ;
} ) ;
}
} ;
2015-12-22 15:49:09 +01:00
var showNotification = function ( buffer , title , body ) {
2015-12-20 15:07:28 +01:00
if ( serviceworker ) {
navigator . serviceWorker . ready . then ( function ( registration ) {
registration . showNotification ( title , {
body : body ,
icon : 'assets/img/glowing_bear_128x128.png' ,
2015-12-22 14:03:30 +01:00
vibrate : [ 200 , 100 ] ,
2015-12-20 15:07:28 +01:00
tag : 'gb-highlight-vib'
} ) ;
} ) ;
2016-01-26 10:02:02 +01:00
} else if ( typeof Windows !== 'undefined' && typeof Windows . UI !== 'undefined' && typeof Windows . UI . Notifications !== 'undefined' ) {
var winNotifications = Windows . UI . Notifications ;
var toastNotifier = winNotifications . ToastNotificationManager . createToastNotifier ( ) ;
var template = winNotifications . ToastTemplateType . toastText02 ;
var toastXml = winNotifications . ToastNotificationManager . getTemplateContent ( template ) ;
var toastTextElements = toastXml . getElementsByTagName ( "text" ) ;
toastTextElements [ 0 ] . appendChild ( toastXml . createTextNode ( title ) ) ;
toastTextElements [ 1 ] . appendChild ( toastXml . createTextNode ( body ) ) ;
var toast = new winNotifications . ToastNotification ( toastXml ) ;
toast . onactivated = function ( ) {
models . setActiveBuffer ( buffer . id ) ;
window . focus ( ) ;
} ;
toastNotifier . show ( toast ) ;
2015-12-20 15:07:28 +01:00
} else {
2016-01-26 10:02:02 +01:00
2015-12-20 15:07:28 +01:00
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 ] ;
} ;
2016-01-26 10:02:02 +01:00
2015-12-20 15:07:28 +01:00
}
2016-01-26 10:02:02 +01:00
2014-08-28 18:25:40 +02:00
} ;
// Reduce buffers with "+" operation over a key. Mostly useful for unread/notification counts.
var unreadCount = function ( type ) {
if ( ! type ) {
type = "unread" ;
}
// Do this the old-fashioned way with iterating over the keys, as underscore proved to be error-prone
var keys = Object . keys ( models . model . buffers ) ;
var count = 0 ;
for ( var key in keys ) {
count += models . model . buffers [ keys [ key ] ] [ type ] ;
}
return count ;
} ;
var updateTitle = function ( ) {
var notifications = unreadCount ( 'notification' ) ;
if ( notifications > 0 ) {
// New notifications deserve an exclamation mark
$rootScope . notificationStatus = '(' + notifications + ') ' ;
} else {
$rootScope . notificationStatus = '' ;
}
var activeBuffer = models . getActiveBuffer ( ) ;
if ( activeBuffer ) {
2014-11-19 14:25:31 +01:00
$rootScope . pageTitle = activeBuffer . shortName + ' | ' + activeBuffer . rtitle ;
2014-08-28 18:25:40 +02:00
}
} ;
var updateFavico = function ( ) {
var notifications = unreadCount ( 'notification' ) ;
if ( notifications > 0 ) {
$rootScope . favico . badge ( notifications , {
bgColor : '#d00' ,
textColor : '#fff'
} ) ;
2016-04-01 21:50:34 +02:00
updateBadge ( notifications ) ;
2014-08-28 18:25:40 +02:00
} else {
var unread = unreadCount ( 'unread' ) ;
if ( unread === 0 ) {
$rootScope . favico . reset ( ) ;
2016-04-01 21:50:34 +02:00
updateBadge ( '' ) ;
2014-08-28 18:25:40 +02:00
} else {
$rootScope . favico . badge ( unread , {
bgColor : '#5CB85C' ,
textColor : '#ff0'
} ) ;
2016-04-01 21:50:34 +02:00
updateBadge ( "." ) ;
2014-08-28 18:25:40 +02:00
}
}
} ;
2016-04-01 21:50:34 +02:00
var updateBadge = function ( value ) {
// Get ipc
if ( typeof setElectronBadge === 'function' ) {
setElectronBadge ( value ) ;
}
} ;
2014-08-28 18:25:40 +02:00
/* Function gets called from bufferLineAdded code if user should be notified */
var createHighlight = function ( buffer , message ) {
var title = '' ;
var body = '' ;
var numNotifications = buffer . notification ;
2015-12-05 13:58:02 +01:00
if ( buffer . type === "private" ) {
2014-08-28 18:25:40 +02:00
if ( numNotifications > 1 ) {
title = numNotifications . toString ( ) + ' private messages from ' ;
} else {
title = 'Private message from ' ;
}
body = message . text ;
} else {
if ( numNotifications > 1 ) {
title = numNotifications . toString ( ) + ' highlights in ' ;
} else {
title = 'Highlight in ' ;
}
var prefix = '' ;
for ( var i = 0 ; i < message . prefix . length ; i ++ ) {
prefix += message . prefix [ i ] . text ;
}
body = '<' + prefix + '> ' + message . text ;
}
2015-12-05 13:58:02 +01:00
title += buffer . shortName + " (" + buffer . server + ")" ;
2014-08-28 18:25:40 +02:00
2015-12-22 15:49:09 +01:00
showNotification ( buffer , title , body ) ;
2014-10-16 17:12:48 +02:00
2014-12-22 22:17:01 +01:00
if ( settings . soundnotification ) {
2014-08-28 18:25:40 +02:00
// TODO fill in a sound file
var audioFile = "assets/audio/sonar" ;
var soundHTML = '<audio autoplay="autoplay"><source src="' + audioFile + '.ogg" type="audio/ogg" /><source src="' + audioFile + '.mp3" type="audio/mpeg" /></audio>' ;
document . getElementById ( "soundNotification" ) . innerHTML = soundHTML ;
}
} ;
2014-10-16 17:12:48 +02:00
var cancelAll = function ( ) {
while ( notifications . length > 0 ) {
var notification = notifications . pop ( ) ;
if ( notification !== undefined ) {
notification . close ( ) ;
}
}
} ;
2014-08-28 18:25:40 +02:00
return {
2014-12-22 22:17:01 +01:00
requestNotificationPermission : requestNotificationPermission ,
updateTitle : updateTitle ,
updateFavico : updateFavico ,
2016-04-01 21:50:34 +02:00
updateBadge : updateBadge ,
2014-12-22 22:17:01 +01:00
createHighlight : createHighlight ,
2014-10-16 17:12:48 +02:00
cancelAll : cancelAll ,
2015-03-24 22:36:21 +01:00
unreadCount : unreadCount
2014-08-28 18:25:40 +02:00
} ;
} ] ) ;