Implement notifications for queries and highlights
- Asks for permission when opening the app if it isn't already granted - Highlights with a notification that stays for 2s - Clicking on the notification brings that window/channel to focus - Uses document.hasFocus() rather than document.hidden, since it seems to be more accurate when the tab is in focus but the window is not Imlements issue #128
This commit is contained in:
parent
fbfb9056d1
commit
d1b3f375c5
8
client/js/libs.min.js
vendored
8
client/js/libs.min.js
vendored
File diff suppressed because one or more lines are too long
218
client/js/libs/notification.js
Normal file
218
client/js/libs/notification.js
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/**
|
||||||
|
* Notification JS
|
||||||
|
* Shims up the Notification API
|
||||||
|
*
|
||||||
|
* @author Andrew Dodson
|
||||||
|
* @website http://adodson.com/notification.js/
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Does the browser support the the Notification API?
|
||||||
|
// .. and does it have a permission property?
|
||||||
|
//
|
||||||
|
|
||||||
|
(function(window, document){
|
||||||
|
|
||||||
|
var PERMISSION_GRANTED = 'granted',
|
||||||
|
PERMISSION_DENIED = 'denied',
|
||||||
|
PERMISSION_UNKNOWN = 'unknown';
|
||||||
|
|
||||||
|
var a = [], iv, i=0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Swap the document.title with the notification
|
||||||
|
//
|
||||||
|
function swaptitle(title){
|
||||||
|
|
||||||
|
if(a.length===0){
|
||||||
|
a = [document.title];
|
||||||
|
}
|
||||||
|
|
||||||
|
a.push(title);
|
||||||
|
|
||||||
|
if(!iv){
|
||||||
|
iv = setInterval(function(){
|
||||||
|
|
||||||
|
// has document.title changed externally?
|
||||||
|
if(a.indexOf(document.title) === -1 ){
|
||||||
|
// update the default title
|
||||||
|
a[0] = document.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.title = a[++i%a.length];
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function swapTitleCancel(){
|
||||||
|
|
||||||
|
// dont do any more if we haven't got anything open
|
||||||
|
if(a.length===0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if an IE overlay is present, kill it
|
||||||
|
if("external" in window && "msSiteModeClearIconOverlay" in window.external ){
|
||||||
|
window.external.msSiteModeClearIconOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearInterval(iv);
|
||||||
|
|
||||||
|
iv = false;
|
||||||
|
document.title = a[0];
|
||||||
|
a = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add aevent handlers
|
||||||
|
function addEvent(el,name,func){
|
||||||
|
if(name.match(" ")){
|
||||||
|
var a = name.split(' ');
|
||||||
|
for(var i=0;i<a.length;i++){
|
||||||
|
addEvent( el, a[i], func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(el.addEventListener){
|
||||||
|
el.removeEventListener(name, func, false);
|
||||||
|
el.addEventListener(name, func, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.detachEvent('on'+name, func);
|
||||||
|
el.attachEvent('on'+name, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function check_permission(){
|
||||||
|
// Check whether the current desktop supports notifications and if they are authorised,
|
||||||
|
// PERMISSION_GRANTED (yes they are supported and permission is granted),
|
||||||
|
// PERMISSION_DENIED (yes they are supported, permission has not been granted),
|
||||||
|
// -1 (Notifications are not supported)
|
||||||
|
|
||||||
|
// IE9
|
||||||
|
if(("external" in window) && ("msIsSiteMode" in window.external)){
|
||||||
|
return window.external.msIsSiteMode()? PERMISSION_GRANTED : PERMISSION_UNKNOWN;
|
||||||
|
}
|
||||||
|
else if("webkitNotifications" in window){
|
||||||
|
return window.webkitNotifications.checkPermission() === 0 ? PERMISSION_GRANTED : PERMISSION_DENIED;
|
||||||
|
}
|
||||||
|
else if("mozNotification" in window.navigator){
|
||||||
|
return PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return PERMISSION_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_permission(){
|
||||||
|
// Define the current state
|
||||||
|
window.Notification.permission = check_permission();
|
||||||
|
return window.Notification.permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!Object(window.Notification).permission){
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bind event handlers to the body
|
||||||
|
addEvent(window, "focus scroll click", swapTitleCancel);
|
||||||
|
|
||||||
|
// Assign it.
|
||||||
|
window.Notification = function(message, options){
|
||||||
|
|
||||||
|
// ensure this is an instance
|
||||||
|
if(!(this instanceof window.Notification)){
|
||||||
|
return new window.Notification(message,options);
|
||||||
|
}
|
||||||
|
|
||||||
|
var n, self = this;
|
||||||
|
|
||||||
|
//
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
this.body = options.body || '';
|
||||||
|
this.icon = options.icon || '';
|
||||||
|
this.lang = options.lang || '';
|
||||||
|
this.tag = options.tag || '';
|
||||||
|
this.close = function(){
|
||||||
|
|
||||||
|
// remove swapTitle
|
||||||
|
swapTitleCancel();
|
||||||
|
|
||||||
|
// Close
|
||||||
|
if(Object(n).close){
|
||||||
|
n.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onclose();
|
||||||
|
};
|
||||||
|
this.onclick = function(){};
|
||||||
|
this.onclose = function(){};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Swap document.title
|
||||||
|
//
|
||||||
|
swaptitle(message);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Desktop Notifications
|
||||||
|
//
|
||||||
|
if(("external" in window) && ("msIsSiteMode" in window.external)){
|
||||||
|
if(window.external.msIsSiteMode()){
|
||||||
|
window.external.msSiteModeActivate();
|
||||||
|
if(this.icon){
|
||||||
|
window.external.msSiteModeSetIconOverlay(this.icon, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if("webkitNotifications" in window){
|
||||||
|
if(window.webkitNotifications.checkPermission() === 0){
|
||||||
|
n = window.webkitNotifications.createNotification(this.icon, message, this.body );
|
||||||
|
n.show();
|
||||||
|
n.onclick = function(){
|
||||||
|
|
||||||
|
// Fire any user bound events to the onclick function
|
||||||
|
self.onclick();
|
||||||
|
|
||||||
|
// redirect the user back to the page
|
||||||
|
window.focus();
|
||||||
|
setTimeout( function(){ n.cancel(); }, 1000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( "mozNotification" in window.navigator ){
|
||||||
|
var m = window.navigator.mozNotification.createNotification( message, this.body, this.icon );
|
||||||
|
m.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Notification.requestPermission = function(cb){
|
||||||
|
// Setup
|
||||||
|
// triggers the authentication to create a notification
|
||||||
|
cb = cb || function(){};
|
||||||
|
|
||||||
|
// IE9
|
||||||
|
if(("external" in window) && ("msIsSiteMode" in window.external)){
|
||||||
|
try{
|
||||||
|
if( !window.external.msIsSiteMode() ){
|
||||||
|
window.external.msAddSiteMode();
|
||||||
|
cb( PERMISSION_UNKNOWN );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e){}
|
||||||
|
cb( update_permission() );
|
||||||
|
}
|
||||||
|
else if("webkitNotifications" in window){
|
||||||
|
window.webkitNotifications.requestPermission(function(){
|
||||||
|
cb( update_permission() );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cb( update_permission() );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the current permission
|
||||||
|
update_permission();
|
||||||
|
}
|
||||||
|
})(window, document);
|
@ -40,6 +40,11 @@ $(function() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request notification permissions if we don't already have it
|
||||||
|
if (Notification.permission !== 'granted') {
|
||||||
|
Notification.requestPermission();
|
||||||
|
}
|
||||||
|
|
||||||
$("#play").on("click", function() { pop.play(); });
|
$("#play").on("click", function() { pop.play(); });
|
||||||
$("#footer .icon").tooltip();
|
$("#footer .icon").tooltip();
|
||||||
|
|
||||||
@ -412,8 +417,22 @@ $(function() {
|
|||||||
var highlight = type.contains("highlight");
|
var highlight = type.contains("highlight");
|
||||||
if (highlight || query) {
|
if (highlight || query) {
|
||||||
pop.play();
|
pop.play();
|
||||||
if (document.hidden || !$(target).hasClass("active")) {
|
if (!document.hasFocus() || !$(target).hasClass("active")) {
|
||||||
favico.badge("!");
|
favico.badge("!");
|
||||||
|
if (Notification.permission === 'granted') {
|
||||||
|
var n = new Notification( msg.from + ' - ' + btn.data('title'), {
|
||||||
|
body: msg.text
|
||||||
|
} );
|
||||||
|
n.onclick = function() {
|
||||||
|
window.focus();
|
||||||
|
btn.click();
|
||||||
|
this.close();
|
||||||
|
};
|
||||||
|
// Close notification after 2s
|
||||||
|
window.setTimeout(function() {
|
||||||
|
n.close();
|
||||||
|
}, 2 * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user