diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 8eb6b295..d3dbacfd 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -192,5 +192,33 @@ }, "installTooManyDevices": { "message": "Sorry, you have too many devices linked already. Try removing some." + }, + "settings": { + "message": "Settings", + "description": "Menu item and header for global settings" + }, + "off": { + "message": "Off", + "description": "Label for disabling notifications" + }, + "nameAndMessage": { + "message": "Name and message", + "description": "Label for setting notifications to display name and message text" + }, + "noNameOrMessage": { + "message": "No name or message", + "description": "Label for setting notifications to display no name and no message text" + }, + "nameOnly": { + "message": "Name only", + "description": "Label for setting notifications to display sender name only" + }, + "newMessage": { + "message": "New Message", + "description": "Displayed in notifications for only 1 message" + }, + "newMessages": { + "message": "New Messages", + "description": "Displayed in notifications for multiple messages" } } diff --git a/background.html b/background.html index a8568263..96c3c2a5 100644 --- a/background.html +++ b/background.html @@ -7,6 +7,7 @@ @@ -319,6 +320,28 @@
+ @@ -362,6 +385,7 @@ + diff --git a/js/notifications.js b/js/notifications.js index 119b5653..140f13dc 100644 --- a/js/notifications.js +++ b/js/notifications.js @@ -5,23 +5,17 @@ 'use strict'; window.Whisper = window.Whisper || {}; + var SETTINGS = { + OFF : 'off', + COUNT : 'count', + NAME : 'name', + MESSAGE : 'message' + }; + Whisper.Notifications = new (Backbone.Collection.extend({ initialize: function() { this.on('add', this.onAdd); }, - isEnabled: function(callback) { - return Notification.permission === 'granted' && - !storage.get('disable-notifications'); - }, - enable: function(callback) { - storage.remove('disable-notifications'); - Notification.requestPermission(function(status) { - callback(status); - }); - }, - disable: function() { - storage.put('disable-notifications', true); - }, onclick: function() { var last = this.last(); if (!last) { @@ -39,25 +33,53 @@ extension.notification.clear(); return; } + + var setting = storage.get('notification-setting') || 'message'; + if (setting === SETTINGS.OFF) { + return; + } + + var iconUrl = 'images/icon_128.png'; + var title = [ + this.length, + this.length === 1 ? i18n('newMessage') : i18n('newMessages') + ].join(' '); + + if (setting === SETTINGS.COUNT) { + extension.notification.update({ + type : 'basic', + title : title, + iconUrl : iconUrl + }); + return; + } + if (this.length > 1) { - var iconUrl = 'images/icon_128.png'; var conversationIds = _.uniq(this.map(function(m) { return m.get('conversationId'); })); - if (conversationIds.length === 1) { + if (conversationIds.length === 1 && this.showSender()) { iconUrl = this.at(0).get('iconUrl'); } extension.notification.update({ type : 'list', iconUrl : iconUrl, - title : '' + this.length + ' new messages', + title : title, message : 'Most recent from ' + this.last().get('title'), items : this.map(function(m) { - return { - title : m.get('title'), - message : m.get('message') - }; - }), + var message, title; + if (this.showMessage()) { + return { + title : m.get('title'), + message : m.get('message') + }; + } else if (this.showSender()) { + return { + title : m.get('title'), + message : i18n('newMessage') + }; + } + }.bind(this)), buttons : [{ title : 'Mark all as read', iconUrl : 'images/check.png' @@ -66,18 +88,38 @@ } else { var m = this.at(0); var type = 'basic'; - if (m.get('imageUrl')) { - type = 'image'; + var message = i18n('newMessage'); + var imageUrl; + if (this.showMessage()) { + message = m.get('message'); + if (m.get('imageUrl')) { + type = 'image'; + imageUrl = m.get('imageUrl'); + } + } + if (this.showSender()) { + title = m.get('title'); + iconUrl = m.get('iconUrl'); } extension.notification.update({ type : type, - title : m.get('title'), - message : m.get('message'), - iconUrl : m.get('iconUrl'), - imageUrl : m.get('imageUrl') + title : title, + message : message, + iconUrl : iconUrl, + imageUrl : imageUrl }); } }, + getSetting: function() { + return storage.get('notification-setting') || 'message'; + }, + showMessage: function() { + return this.getSetting() === SETTINGS.MESSAGE; + }, + showSender: function() { + var setting = this.getSetting(); + return (setting === SETTINGS.MESSAGE || setting === SETTINGS.NAME); + }, onAdd: function() { extension.notification.clear(); this.update(); diff --git a/js/views/inbox_view.js b/js/views/inbox_view.js index 9a6a6400..4883d982 100644 --- a/js/views/inbox_view.js +++ b/js/views/inbox_view.js @@ -115,15 +115,22 @@ welcomeToSignal: i18n('welcomeToSignal'), selectAContact: i18n('selectAContact'), searchForPeopleOrGroups: i18n('searchForPeopleOrGroups'), - submitDebugLog: i18n('submitDebugLog') + submitDebugLog: i18n('submitDebugLog'), + settings: i18n('settings'), }, events: { 'click': 'closeMenu', 'click .hamburger': 'toggleMenu', 'click .show-debug-log': 'showDebugLog', + 'click .settings': 'showSettings', 'select .gutter .conversation-list-item': 'openConversation', 'input input.search': 'filterContacts' }, + showSettings: function() { + var view = new Whisper.SettingsView().render(); + view.update(); + view.$el.insertAfter(this.el); + }, filterContacts: function(e) { this.searchView.filterContacts(e); var input = this.$('input.search'); diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 74116ef8..dcf8d5ab 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -473,3 +473,24 @@ $avatar-size: 44px; -webkit-user-select: text; } } +.modal { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: rgba(0, 0, 0, 0.3); + padding: 0 20px; + z-index: 10; + + .content { + position: relative; + max-width: 350px; + margin: 100px auto; + padding: 1em; + background: white; + border-radius: 10px; + overflow: auto; + box-shadow: 0px 3px 5px 0px rgba(0,0,0,0.2); + } +} diff --git a/stylesheets/_index.scss b/stylesheets/_index.scss index 85f08f27..a2ac4f49 100644 --- a/stylesheets/_index.scss +++ b/stylesheets/_index.scss @@ -264,3 +264,19 @@ input.search { top: -30px; } } +.settings { + .close { + float: right; + font-family: sans-serif; + color: white; + cursor: pointer; + border-radius: 50%; + width: 20px; + height: 20px; + padding: 0px; + + background: #666; + color: #fff; + text-align: center; + } +} diff --git a/stylesheets/manifest.css b/stylesheets/manifest.css index f9c9613e..63c26eb4 100644 --- a/stylesheets/manifest.css +++ b/stylesheets/manifest.css @@ -375,6 +375,25 @@ img.emoji { text-align: center; -webkit-user-select: text; } +.modal { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: rgba(0, 0, 0, 0.3); + padding: 0 20px; + z-index: 10; } + .modal .content { + position: relative; + max-width: 350px; + margin: 100px auto; + padding: 1em; + background: white; + border-radius: 10px; + overflow: auto; + box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.2); } + .gutter { padding: 36px 0 0; } @@ -578,6 +597,19 @@ input.search { border-color: transparent transparent #2eace0 transparent; top: -30px; } +.settings .close { + float: right; + font-family: sans-serif; + color: white; + cursor: pointer; + border-radius: 50%; + width: 20px; + height: 20px; + padding: 0px; + background: #666; + color: #fff; + text-align: center; } + .conversation-title { display: block; line-height: 36px;