Add frontend support for expiring releases
When a release expires, it gets a persistent banner notification to upgrade, and an ephemeral toast warning when trying to send a message. // FREEBIE
This commit is contained in:
parent
c442a02cb6
commit
9aa429e18a
9 changed files with 104 additions and 8 deletions
|
@ -257,5 +257,13 @@
|
||||||
"learnMore": {
|
"learnMore": {
|
||||||
"message": "Learn more about verifying keys.",
|
"message": "Learn more about verifying keys.",
|
||||||
"description": "Text that links to a support article on verifying identity keys"
|
"description": "Text that links to a support article on verifying identity keys"
|
||||||
|
},
|
||||||
|
"expiredWarning": {
|
||||||
|
"message": "This version of Signal Desktop has expired. Please upgrade to the latest version to continue messaging.",
|
||||||
|
"description": "Warning notification that this version of the app has expired"
|
||||||
|
},
|
||||||
|
"upgrade": {
|
||||||
|
"message": "Upgrade",
|
||||||
|
"description": "Label text for button to upgrade the app to the latest version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
<script type='text/x-tmpl-mustache' id='expired_alert'>
|
||||||
|
<a target='_blank' href='https://chrome.google.com/webstore/detail/bikioccmkafdpakkkcpdbppfkghcmihk'>
|
||||||
|
<button class='upgrade'>{{ upgrade }}</button>
|
||||||
|
</a>
|
||||||
|
{{ expiredWarning }}
|
||||||
|
</script>
|
||||||
|
<script type='text/x-tmpl-mustache' id='expired_toast'>
|
||||||
|
{{ expiredWarning }}
|
||||||
|
</script>
|
||||||
<script type='text/x-tmpl-mustache' id='hint'>
|
<script type='text/x-tmpl-mustache' id='hint'>
|
||||||
<p> {{ content }}</p>
|
<p> {{ content }}</p>
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -94,7 +94,9 @@
|
||||||
var mySignalingKey = storage.get('signaling_key');
|
var mySignalingKey = storage.get('signaling_key');
|
||||||
|
|
||||||
// initialize the socket and start listening for messages
|
// initialize the socket and start listening for messages
|
||||||
messageReceiver = new textsecure.MessageReceiver(SERVER_URL, USERNAME, PASSWORD, mySignalingKey, ATTACHMENT_SERVER_URL);
|
messageReceiver = new textsecure.MessageReceiver(
|
||||||
|
SERVER_URL, USERNAME, PASSWORD, mySignalingKey, ATTACHMENT_SERVER_URL
|
||||||
|
);
|
||||||
messageReceiver.addEventListener('message', onMessageReceived);
|
messageReceiver.addEventListener('message', onMessageReceived);
|
||||||
messageReceiver.addEventListener('receipt', onDeliveryReceipt);
|
messageReceiver.addEventListener('receipt', onDeliveryReceipt);
|
||||||
messageReceiver.addEventListener('contact', onContactReceived);
|
messageReceiver.addEventListener('contact', onContactReceived);
|
||||||
|
@ -103,7 +105,9 @@
|
||||||
messageReceiver.addEventListener('read', onReadReceipt);
|
messageReceiver.addEventListener('read', onReadReceipt);
|
||||||
messageReceiver.addEventListener('error', onError);
|
messageReceiver.addEventListener('error', onError);
|
||||||
|
|
||||||
window.textsecure.messaging = new textsecure.MessageSender(SERVER_URL, USERNAME, PASSWORD, ATTACHMENT_SERVER_URL);
|
window.textsecure.messaging = new textsecure.MessageSender(
|
||||||
|
SERVER_URL, USERNAME, PASSWORD, ATTACHMENT_SERVER_URL
|
||||||
|
);
|
||||||
if (firstRun === true && textsecure.storage.user.getDeviceId() != '1') {
|
if (firstRun === true && textsecure.storage.user.getDeviceId() != '1') {
|
||||||
var syncRequest = new textsecure.SyncRequest(textsecure.messaging, messageReceiver);
|
var syncRequest = new textsecure.SyncRequest(textsecure.messaging, messageReceiver);
|
||||||
syncRequest.addEventListener('success', function() {
|
syncRequest.addEventListener('success', function() {
|
||||||
|
|
|
@ -6,6 +6,15 @@
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
emoji.init_colons();
|
emoji.init_colons();
|
||||||
|
|
||||||
|
Whisper.ExpiredToast = Whisper.ToastView.extend({
|
||||||
|
templateName: 'expired_toast',
|
||||||
|
render_attributes: function() {
|
||||||
|
return {
|
||||||
|
expiredWarning: i18n('expiredWarning')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Whisper.ConversationView = Whisper.View.extend({
|
Whisper.ConversationView = Whisper.View.extend({
|
||||||
className: function() {
|
className: function() {
|
||||||
return [ 'conversation', this.model.get('type') ].join(' ');
|
return [ 'conversation', this.model.get('type') ].join(' ');
|
||||||
|
@ -232,6 +241,12 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
sendMessage: function(e) {
|
sendMessage: function(e) {
|
||||||
|
if (extension.expired()) {
|
||||||
|
var toast = new Whisper.ExpiredToast();
|
||||||
|
toast.$el.insertAfter(this.$el);
|
||||||
|
toast.render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var input = this.$messageField;
|
var input = this.$messageField;
|
||||||
var message = this.replace_colons(input.val()).trim();
|
var message = this.replace_colons(input.val()).trim();
|
||||||
|
|
|
@ -94,14 +94,20 @@
|
||||||
extension.windows.onClosed(function() {
|
extension.windows.onClosed(function() {
|
||||||
this.inboxListView.stopListening();
|
this.inboxListView.stopListening();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
if (extension.expired()) {
|
||||||
|
var banner = new Whisper.ExpiredAlertBanner().render();
|
||||||
|
banner.$el.prependTo(this.$el);
|
||||||
|
this.$el.addClass('expired');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
render_attributes: {
|
render_attributes: {
|
||||||
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'),
|
settings : i18n('settings'),
|
||||||
restartSignal: i18n('restartSignal')
|
restartSignal : i18n('restartSignal'),
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
'click': 'closeMenu',
|
'click': 'closeMenu',
|
||||||
|
@ -166,4 +172,15 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Whisper.ExpiredAlertBanner = Whisper.View.extend({
|
||||||
|
templateName: 'expired_alert',
|
||||||
|
className: 'expiredAlert clearfix',
|
||||||
|
render_attributes: function() {
|
||||||
|
return {
|
||||||
|
expiredWarning: i18n('expiredWarning'),
|
||||||
|
upgrade: i18n('upgrade'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -496,3 +496,21 @@ input[type=text], input[type=search], textarea {
|
||||||
outline: 1px solid $blue;
|
outline: 1px solid $blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expiredAlert {
|
||||||
|
background: #F3F3A7;
|
||||||
|
padding: 10px;
|
||||||
|
line-height: 36px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
float: right;
|
||||||
|
border: none;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 36px;
|
||||||
|
padding: 0 20px;
|
||||||
|
background: $blue;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expired {
|
||||||
|
.conversation-stack, .gutter {
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.scrollable {
|
.scrollable {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
@ -420,6 +420,21 @@ img.emoji {
|
||||||
input[type=text]:active, input[type=text]:focus, input[type=search]:active, input[type=search]:focus, textarea:active, textarea:focus {
|
input[type=text]:active, input[type=text]:focus, input[type=search]:active, input[type=search]:focus, textarea:active, textarea:focus {
|
||||||
outline: 1px solid #2090ea; }
|
outline: 1px solid #2090ea; }
|
||||||
|
|
||||||
|
.expiredAlert {
|
||||||
|
background: #F3F3A7;
|
||||||
|
padding: 10px;
|
||||||
|
line-height: 36px; }
|
||||||
|
.expiredAlert button {
|
||||||
|
float: right;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 36px;
|
||||||
|
padding: 0 20px;
|
||||||
|
background: #2090ea;
|
||||||
|
margin-left: 20px; }
|
||||||
|
|
||||||
@keyframes progress-bar-stripes {
|
@keyframes progress-bar-stripes {
|
||||||
from {
|
from {
|
||||||
background-position: 40px 0; }
|
background-position: 40px 0; }
|
||||||
|
@ -451,6 +466,9 @@ input[type=text]:active, input[type=text]:focus, input[type=search]:active, inpu
|
||||||
.new-conversation, .inbox, .gutter {
|
.new-conversation, .inbox, .gutter {
|
||||||
height: 100%; }
|
height: 100%; }
|
||||||
|
|
||||||
|
.expired .conversation-stack, .expired .gutter {
|
||||||
|
height: calc(100% - 56px); }
|
||||||
|
|
||||||
.scrollable {
|
.scrollable {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto; }
|
overflow: auto; }
|
||||||
|
|
|
@ -124,6 +124,7 @@
|
||||||
<script type="text/javascript" src="../js/views/message_list_view.js" data-cover></script>
|
<script type="text/javascript" src="../js/views/message_list_view.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/views/conversation_list_item_view.js" data-cover></script>
|
<script type="text/javascript" src="../js/views/conversation_list_item_view.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/views/conversation_list_view.js" data-cover></script>
|
<script type="text/javascript" src="../js/views/conversation_list_view.js" data-cover></script>
|
||||||
|
<script type="text/javascript" src="../js/views/toast_view.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/views/conversation_view.js" data-cover></script>
|
<script type="text/javascript" src="../js/views/conversation_view.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/views/new_conversation_view.js" data-cover></script>
|
<script type="text/javascript" src="../js/views/new_conversation_view.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/views/conversation_search_view.js"></script>
|
<script type="text/javascript" src="../js/views/conversation_search_view.js"></script>
|
||||||
|
|
Loading…
Reference in a new issue