diff --git a/background.html b/background.html index c215ab2736..2507aab720 100644 --- a/background.html +++ b/background.html @@ -202,6 +202,7 @@ + diff --git a/js/background.js b/js/background.js index 441cc22440..621751232e 100644 --- a/js/background.js +++ b/js/background.js @@ -115,12 +115,12 @@ e.args.push(message.id); message.save({ errors : [e] }).then(function() { extension.trigger('message', message); - openConversation(conversation.id); + notifyConversation(message); }); } else if (e.message === 'Bad MAC') { message.save({ errors : [ _.pick(e, ['name', 'message'])]}).then(function() { extension.trigger('message', message); - openConversation(conversation.id); + notifyConversation(message); }); } else { console.log(e); @@ -220,7 +220,7 @@ conversation.save().then(function() { message.save().then(function() { extension.trigger('message', message); // notify frontend listeners - openConversation(conversation.id); + notifyConversation(message); }); }); }); diff --git a/js/models/conversations.js b/js/models/conversations.js index 817042344f..629552a062 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -36,6 +36,8 @@ this.messageCollection = new Whisper.MessageCollection([], { conversation: this }); + + this.on('change:avatar', this.updateAvatarUrl); }, validate: function(attributes, options) { @@ -190,6 +192,28 @@ }, isPrivate: function() { return this.get('type') === 'private'; + }, + + updateAvatarUrl: function() { + if (this.avatarUrl) { + URL.revokeObjectURL(this.avatarUrl); + this.avatarUrl = null; + } + var avatar = this.get('avatar'); + if (avatar) { + this.avatarUrl = URL.createObjectURL( + new Blob([avatar.data], {type: avatar.contentType}) + ); + } else { + this.avatarUrl = null; + } + }, + + getAvatarUrl: function() { + if (this.avatarUrl === undefined) { + this.updateAvatarUrl(); + } + return this.avatarUrl || '/images/default.png'; } }); diff --git a/js/notifications.js b/js/notifications.js new file mode 100644 index 0000000000..599d8e2efc --- /dev/null +++ b/js/notifications.js @@ -0,0 +1,36 @@ +/* vim: ts=4:sw=4 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +;(function() { + 'use strict'; + window.Whisper = window.Whisper || {}; + + Whisper.Notifications = { + isEnabled: function(callback) { + return Notification.permission === 'granted' && + !localStorage.getItem('disable-notifications'); + }, + enable: function(callback) { + localStorage.removeItem('disable-notifications'); + Notification.requestPermission(function(status) { + callback(status); + }); + }, + disable: function() { + localStorage.setItem('disable-notifications', true); + } + }; + +})(); diff --git a/js/options.js b/js/options.js index 74753dbf04..56d63e360c 100644 --- a/js/options.js +++ b/js/options.js @@ -15,6 +15,26 @@ */ ;(function() { 'use strict'; + $('.notifications .on button').click(function() { + Whisper.Notifications.disable(); + initOptions(); + }); + + $('.notifications .off button').click(function() { + Whisper.Notifications.enable(initOptions); + initOptions(); + }); + + function initOptions() { + if (Whisper.Notifications.isEnabled()) { + $('.notifications .on').show(); + $('.notifications .off').hide(); + } else { + $('.notifications .on').hide(); + $('.notifications .off').show(); + } + } + $(function() { if (textsecure.registration.isDone()) { $('#complete-number').text( @@ -23,6 +43,7 @@ )[0] );//TODO: no $('#setup-complete').show().addClass('in'); + initOptions(); } else { $('#init-setup').show().addClass('in'); $('#status').text("Connecting..."); @@ -55,6 +76,7 @@ textsecure.registration.done(); $('#init-setup').hide(); $('#setup-complete').show().addClass('in'); + initOptions(); } }); } else diff --git a/js/panel_controller.js b/js/panel_controller.js index 79bcd11737..dcfd684a31 100644 --- a/js/panel_controller.js +++ b/js/panel_controller.js @@ -41,9 +41,32 @@ windowMap.remove('windowId', windowId); } - window.openConversation = function openConversation (modelId) { + function getConversation(modelId) { var conversation = window.inbox.get(modelId) || {id: modelId}; conversation = conversations.add(conversation); + return conversation; + } + + window.notifyConversation = function(message) { + if (Whisper.Notifications.isEnabled()) { + var conversation = getConversation(message.get('conversationId')); + conversation.fetch().then(function() { + var notification = new Notification(conversation.getTitle(), { + body: message.get('body'), + icon: conversation.getAvatarUrl(), + tag: conversation.id + }); + notification.onclick = function() { + openConversation(conversation.id); + }; + }); + } else { + openConversation(message.get('conversationId')); + } + }; + + window.openConversation = function openConversation (modelId) { + var conversation = getConversation(modelId); conversation.fetch().then(function() { conversation.fetchContacts(); }); diff --git a/options.html b/options.html index e0ba36c7e6..2e7b793cb3 100644 --- a/options.html +++ b/options.html @@ -93,12 +93,17 @@

You are registered on TextSecure with number

+
+ Desktop notifcations are enabled. + Desktop notifcations are not enabled. +
+