parent
015bbdacc7
commit
a3c6061480
7 changed files with 198 additions and 28 deletions
|
@ -192,5 +192,33 @@
|
||||||
},
|
},
|
||||||
"installTooManyDevices": {
|
"installTooManyDevices": {
|
||||||
"message": "Sorry, you have too many devices linked already. Try removing some."
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<div class='global-menu menu'>
|
<div class='global-menu menu'>
|
||||||
<button class='hamburger'></button>
|
<button class='hamburger'></button>
|
||||||
<ul class='menu-list'>
|
<ul class='menu-list'>
|
||||||
|
<li><a class='settings'>{{ settings }}</a></li>
|
||||||
<li><a class='show-debug-log'>{{ submitDebugLog }}</a></li>
|
<li><a class='show-debug-log'>{{ submitDebugLog }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -319,6 +320,28 @@
|
||||||
<div><button class='close'>{{ close }}</button></div>
|
<div><button class='close'>{{ close }}</button></div>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</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/components.js'></script>
|
||||||
<script type='text/javascript' src='js/database.js'></script>
|
<script type='text/javascript' src='js/database.js'></script>
|
||||||
<script type='text/javascript' src='js/debugLog.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/inbox_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/confirmation_dialog_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/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>
|
<script type='text/javascript' src='js/background.js'></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -5,23 +5,17 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
|
|
||||||
|
var SETTINGS = {
|
||||||
|
OFF : 'off',
|
||||||
|
COUNT : 'count',
|
||||||
|
NAME : 'name',
|
||||||
|
MESSAGE : 'message'
|
||||||
|
};
|
||||||
|
|
||||||
Whisper.Notifications = new (Backbone.Collection.extend({
|
Whisper.Notifications = new (Backbone.Collection.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.on('add', this.onAdd);
|
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() {
|
onclick: function() {
|
||||||
var last = this.last();
|
var last = this.last();
|
||||||
if (!last) {
|
if (!last) {
|
||||||
|
@ -39,25 +33,53 @@
|
||||||
extension.notification.clear();
|
extension.notification.clear();
|
||||||
return;
|
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) {
|
if (this.length > 1) {
|
||||||
var iconUrl = 'images/icon_128.png';
|
|
||||||
var conversationIds = _.uniq(this.map(function(m) {
|
var conversationIds = _.uniq(this.map(function(m) {
|
||||||
return m.get('conversationId');
|
return m.get('conversationId');
|
||||||
}));
|
}));
|
||||||
if (conversationIds.length === 1) {
|
if (conversationIds.length === 1 && this.showSender()) {
|
||||||
iconUrl = this.at(0).get('iconUrl');
|
iconUrl = this.at(0).get('iconUrl');
|
||||||
}
|
}
|
||||||
extension.notification.update({
|
extension.notification.update({
|
||||||
type : 'list',
|
type : 'list',
|
||||||
iconUrl : iconUrl,
|
iconUrl : iconUrl,
|
||||||
title : '' + this.length + ' new messages',
|
title : title,
|
||||||
message : 'Most recent from ' + this.last().get('title'),
|
message : 'Most recent from ' + this.last().get('title'),
|
||||||
items : this.map(function(m) {
|
items : this.map(function(m) {
|
||||||
return {
|
var message, title;
|
||||||
title : m.get('title'),
|
if (this.showMessage()) {
|
||||||
message : m.get('message')
|
return {
|
||||||
};
|
title : m.get('title'),
|
||||||
}),
|
message : m.get('message')
|
||||||
|
};
|
||||||
|
} else if (this.showSender()) {
|
||||||
|
return {
|
||||||
|
title : m.get('title'),
|
||||||
|
message : i18n('newMessage')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}.bind(this)),
|
||||||
buttons : [{
|
buttons : [{
|
||||||
title : 'Mark all as read',
|
title : 'Mark all as read',
|
||||||
iconUrl : 'images/check.png'
|
iconUrl : 'images/check.png'
|
||||||
|
@ -66,18 +88,38 @@
|
||||||
} else {
|
} else {
|
||||||
var m = this.at(0);
|
var m = this.at(0);
|
||||||
var type = 'basic';
|
var type = 'basic';
|
||||||
if (m.get('imageUrl')) {
|
var message = i18n('newMessage');
|
||||||
type = 'image';
|
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({
|
extension.notification.update({
|
||||||
type : type,
|
type : type,
|
||||||
title : m.get('title'),
|
title : title,
|
||||||
message : m.get('message'),
|
message : message,
|
||||||
iconUrl : m.get('iconUrl'),
|
iconUrl : iconUrl,
|
||||||
imageUrl : m.get('imageUrl')
|
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() {
|
onAdd: function() {
|
||||||
extension.notification.clear();
|
extension.notification.clear();
|
||||||
this.update();
|
this.update();
|
||||||
|
|
|
@ -115,15 +115,22 @@
|
||||||
welcomeToSignal: i18n('welcomeToSignal'),
|
welcomeToSignal: i18n('welcomeToSignal'),
|
||||||
selectAContact: i18n('selectAContact'),
|
selectAContact: i18n('selectAContact'),
|
||||||
searchForPeopleOrGroups: i18n('searchForPeopleOrGroups'),
|
searchForPeopleOrGroups: i18n('searchForPeopleOrGroups'),
|
||||||
submitDebugLog: i18n('submitDebugLog')
|
submitDebugLog: i18n('submitDebugLog'),
|
||||||
|
settings: i18n('settings'),
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
'click': 'closeMenu',
|
'click': 'closeMenu',
|
||||||
'click .hamburger': 'toggleMenu',
|
'click .hamburger': 'toggleMenu',
|
||||||
'click .show-debug-log': 'showDebugLog',
|
'click .show-debug-log': 'showDebugLog',
|
||||||
|
'click .settings': 'showSettings',
|
||||||
'select .gutter .conversation-list-item': 'openConversation',
|
'select .gutter .conversation-list-item': 'openConversation',
|
||||||
'input input.search': 'filterContacts'
|
'input input.search': 'filterContacts'
|
||||||
},
|
},
|
||||||
|
showSettings: function() {
|
||||||
|
var view = new Whisper.SettingsView().render();
|
||||||
|
view.update();
|
||||||
|
view.$el.insertAfter(this.el);
|
||||||
|
},
|
||||||
filterContacts: function(e) {
|
filterContacts: function(e) {
|
||||||
this.searchView.filterContacts(e);
|
this.searchView.filterContacts(e);
|
||||||
var input = this.$('input.search');
|
var input = this.$('input.search');
|
||||||
|
|
|
@ -473,3 +473,24 @@ $avatar-size: 44px;
|
||||||
-webkit-user-select: text;
|
-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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -264,3 +264,19 @@ input.search {
|
||||||
top: -30px;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -375,6 +375,25 @@ img.emoji {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
-webkit-user-select: text; }
|
-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 {
|
.gutter {
|
||||||
padding: 36px 0 0; }
|
padding: 36px 0 0; }
|
||||||
|
|
||||||
|
@ -578,6 +597,19 @@ input.search {
|
||||||
border-color: transparent transparent #2eace0 transparent;
|
border-color: transparent transparent #2eace0 transparent;
|
||||||
top: -30px; }
|
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 {
|
.conversation-title {
|
||||||
display: block;
|
display: block;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
|
|
Loading…
Reference in a new issue