Add Notification Settings

Fixes #471

// FREEBIE
This commit is contained in:
lilia 2016-02-17 16:08:17 -08:00
parent 015bbdacc7
commit a3c6061480
7 changed files with 198 additions and 28 deletions

View File

@ -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"
}
}

View File

@ -7,6 +7,7 @@
<div class='global-menu menu'>
<button class='hamburger'></button>
<ul class='menu-list'>
<li><a class='settings'>{{ settings }}</a></li>
<li><a class='show-debug-log'>{{ submitDebugLog }}</a></li>
</ul>
</div>
@ -319,6 +320,28 @@
<div><button class='close'>{{ close }}</button></div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='settings'>
<div class='content'>
<div class='close'>x</div>
<h3>Notifications</h3>
<div>
<input type='radio' name='notifications' id='notification-setting-message' value='message'>
<label for='notification-setting-message'>{{ nameAndMessage }} </label>
</div>
<div>
<input type='radio' name='notifications' id='notification-setting-name' value='name'/>
<label for='notification-setting-name'>{{ nameOnly }} </label>
</div>
<div>
<input type='radio' name='notifications' id='notification-setting-count' value='count'/>
<label for='notification-setting-count'>{{ noNameOrMessage }} </label>
</div>
<div>
<input type='radio' name='notifications' id='notification-setting-off' value='off'/>
<label for='notification-setting-off'>{{ off }} </label>
</div>
</div>
</script>
<script type='text/javascript' src='js/components.js'></script>
<script type='text/javascript' src='js/database.js'></script>
<script type='text/javascript' src='js/debugLog.js'></script>
@ -362,6 +385,7 @@
<script type='text/javascript' src='js/views/inbox_view.js'></script>
<script type='text/javascript' src='js/views/confirmation_dialog_view.js'></script>
<script type='text/javascript' src='js/views/identicon_svg_view.js'></script>
<script type='text/javascript' src='js/views/settings_view.js'></script>
<script type='text/javascript' src='js/background.js'></script>
</head>

View File

@ -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();

View File

@ -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');

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;