set up a new view for displaying the network status
// FREEBIE
This commit is contained in:
parent
e4a21d1a53
commit
ed4991974b
13 changed files with 326 additions and 76 deletions
|
@ -62,6 +62,25 @@
|
||||||
"disconnected": {
|
"disconnected": {
|
||||||
"message": "Disconnected"
|
"message": "Disconnected"
|
||||||
},
|
},
|
||||||
|
"connecting": {
|
||||||
|
"message": "Connecting"
|
||||||
|
},
|
||||||
|
"offline": {
|
||||||
|
"message": "Offline"
|
||||||
|
},
|
||||||
|
"checkNetworkConnection": {
|
||||||
|
"message": "Check your network connection.",
|
||||||
|
"description": "Obvious instructions for when a user's computer loses its network connection"
|
||||||
|
},
|
||||||
|
"attemptingReconnection": {
|
||||||
|
"message": "Attempting reconnect in $reconnect_duration_in_seconds$ seconds",
|
||||||
|
"placeholders": {
|
||||||
|
"reconnect_duration_in_seconds": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"submitDebugLog": {
|
"submitDebugLog": {
|
||||||
"message": "Submit debug log",
|
"message": "Submit debug log",
|
||||||
"description": "Menu item and header text for debug log modal, title case."
|
"description": "Menu item and header text for debug log modal, title case."
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<script type='text/x-tmpl-mustache' id='two-column'>
|
<script type='text/x-tmpl-mustache' id='two-column'>
|
||||||
<div class='gutter'>
|
<div class='gutter'>
|
||||||
|
<div class='network-status-container'></div>
|
||||||
<div class='title-bar active' id='header'>
|
<div class='title-bar active' id='header'>
|
||||||
<div class='header-buttons right'>
|
<div class='header-buttons right'>
|
||||||
<div class='vertical-align'>
|
<div class='vertical-align'>
|
||||||
|
@ -15,7 +16,6 @@
|
||||||
<li class='restart-signal'>{{ restartSignal }}</li>
|
<li class='restart-signal'>{{ restartSignal }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<span class='socket-status'></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1>Signal</h1>
|
<h1>Signal</h1>
|
||||||
|
@ -490,6 +490,19 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type='text/x-tmpl-mustache' id='networkStatus'>
|
||||||
|
<div class='network-status-message' style='{{^instructions}}margin-top:3px;{{/instructions}}{{#instructions}}margin-top:-6px{{/instructions}}'>
|
||||||
|
<h3 style='{{^instructions}}font-size:17px;{{/instructions}}'>{{ message }}</h3>
|
||||||
|
<span>{{ instructions }}</span>
|
||||||
|
</div>
|
||||||
|
{{ #reconnectDurationAsSeconds }}
|
||||||
|
<div class="network-status-message">
|
||||||
|
{{ attemptingReconnectionMessage }}
|
||||||
|
</div>
|
||||||
|
{{/reconnectDurationAsSeconds }}
|
||||||
|
</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>
|
||||||
|
@ -537,6 +550,7 @@
|
||||||
<script type='text/javascript' src='js/views/conversation_search_view.js'></script>
|
<script type='text/javascript' src='js/views/conversation_search_view.js'></script>
|
||||||
<script type='text/javascript' src='js/views/hint_view.js'></script>
|
<script type='text/javascript' src='js/views/hint_view.js'></script>
|
||||||
<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/network_status_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/views/settings_view.js'></script>
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 500 B |
1
images/error_red.svg
Normal file
1
images/error_red.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><circle cx="11" cy="-1041.36" r="8" transform="matrix(1 0 0-1 0-1030.36)" opacity=".98" fill="#da4453"/><path d="m-26.309 18.07c-1.18 0-2.135.968-2.135 2.129v12.82c0 1.176.948 2.129 2.135 2.129 1.183 0 2.135-.968 2.135-2.129v-12.82c0-1.176-.946-2.129-2.135-2.129zm0 21.348c-1.18 0-2.135.954-2.135 2.135 0 1.18.954 2.135 2.135 2.135 1.181 0 2.135-.954 2.135-2.135 0-1.18-.952-2.135-2.135-2.135z" transform="matrix(.30056 0 0 .30056 18.902 1.728)" fill="#fff" stroke="#fff"/></svg>
|
After Width: | Height: | Size: 539 B |
|
@ -232,6 +232,10 @@
|
||||||
if (navigator.onLine) {
|
if (navigator.onLine) {
|
||||||
console.log('retrying in 1 minute');
|
console.log('retrying in 1 minute');
|
||||||
setTimeout(init, 60000);
|
setTimeout(init, 60000);
|
||||||
|
|
||||||
|
if (owsDesktopApp.inboxView) {
|
||||||
|
owsDesktopApp.inboxView.networkStatusView.setSocketReconnectInterval(60000);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('offline');
|
console.log('offline');
|
||||||
messageReceiver.close();
|
messageReceiver.close();
|
||||||
|
|
|
@ -32,12 +32,18 @@
|
||||||
return { unreadCount : 0 };
|
return { unreadCount : 0 };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleMessageError: function(message, errors) {
|
||||||
|
this.trigger('messageError', message, errors);
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.contactCollection = new Backbone.Collection();
|
this.contactCollection = new Backbone.Collection();
|
||||||
this.messageCollection = new Whisper.MessageCollection([], {
|
this.messageCollection = new Whisper.MessageCollection([], {
|
||||||
conversation: this
|
conversation: this
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.messageCollection.on('change:errors', this.handleMessageError, this);
|
||||||
|
|
||||||
this.on('change:avatar', this.updateAvatarUrl);
|
this.on('change:avatar', this.updateAvatarUrl);
|
||||||
this.on('destroy', this.revokeAvatarUrl);
|
this.on('destroy', this.revokeAvatarUrl);
|
||||||
this.on('read', this.onReadMessage);
|
this.on('read', this.onReadMessage);
|
||||||
|
|
|
@ -6,37 +6,6 @@
|
||||||
|
|
||||||
window.Whisper = window.Whisper || {};
|
window.Whisper = window.Whisper || {};
|
||||||
|
|
||||||
var SocketView = Whisper.View.extend({
|
|
||||||
className: 'status',
|
|
||||||
initialize: function() {
|
|
||||||
setInterval(this.updateStatus.bind(this), 5000);
|
|
||||||
},
|
|
||||||
updateStatus: function() {
|
|
||||||
var className, message = '';
|
|
||||||
if (typeof getSocketStatus === 'function') {
|
|
||||||
switch(getSocketStatus()) {
|
|
||||||
case WebSocket.CONNECTING:
|
|
||||||
className = 'connecting';
|
|
||||||
break;
|
|
||||||
case WebSocket.OPEN:
|
|
||||||
className = 'open';
|
|
||||||
break;
|
|
||||||
case WebSocket.CLOSING:
|
|
||||||
className = 'closing';
|
|
||||||
break;
|
|
||||||
case WebSocket.CLOSED:
|
|
||||||
className = 'closed';
|
|
||||||
message = i18n('disconnected');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!this.$el.hasClass(className)) {
|
|
||||||
this.$el.attr('class', className);
|
|
||||||
this.$el.text(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Whisper.ConversationStack = Whisper.View.extend({
|
Whisper.ConversationStack = Whisper.View.extend({
|
||||||
className: 'conversation-stack',
|
className: 'conversation-stack',
|
||||||
open: function(conversation) {
|
open: function(conversation) {
|
||||||
|
@ -112,6 +81,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var inboxCollection = getInboxCollection();
|
var inboxCollection = getInboxCollection();
|
||||||
|
|
||||||
|
inboxCollection.on('messageError', function() {
|
||||||
|
this.networkStatusView.render();
|
||||||
|
});
|
||||||
|
|
||||||
this.inboxListView = new Whisper.ConversationListView({
|
this.inboxListView = new Whisper.ConversationListView({
|
||||||
el : this.$('.inbox'),
|
el : this.$('.inbox'),
|
||||||
collection : inboxCollection
|
collection : inboxCollection
|
||||||
|
@ -139,7 +113,8 @@
|
||||||
this.listenTo(this.searchView, 'open',
|
this.listenTo(this.searchView, 'open',
|
||||||
this.openConversation.bind(this, null));
|
this.openConversation.bind(this, null));
|
||||||
|
|
||||||
new SocketView().render().$el.appendTo(this.$('.socket-status'));
|
this.networkStatusView = new Whisper.NetworkStatusView();
|
||||||
|
this.$el.find('.network-status-container').append(this.networkStatusView.render().el);
|
||||||
|
|
||||||
extension.windows.onClosed(function() {
|
extension.windows.onClosed(function() {
|
||||||
this.inboxListView.stopListening();
|
this.inboxListView.stopListening();
|
||||||
|
|
92
js/views/network_status_view.js
Normal file
92
js/views/network_status_view.js
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
window.Whisper = window.Whisper || {};
|
||||||
|
|
||||||
|
Whisper.NetworkStatusView = Whisper.View.extend({
|
||||||
|
className: 'network-status',
|
||||||
|
initialize: function() {
|
||||||
|
this.$el.hide();
|
||||||
|
|
||||||
|
var renderIntervalHandle = setInterval(this.render.bind(this), 5000);
|
||||||
|
extension.windows.onClosed(function () { clearInterval(renderIntervalHandle); });
|
||||||
|
|
||||||
|
setTimeout(this.finishConnectingGracePeriod.bind(this), 5000);
|
||||||
|
|
||||||
|
this.withinConnectingGracePeriod = true;
|
||||||
|
this.setSocketReconnectInterval(null);
|
||||||
|
|
||||||
|
window.addEventListener('online', this.render.bind(this));
|
||||||
|
window.addEventListener('offline', this.render.bind(this));
|
||||||
|
},
|
||||||
|
finishConnectingGracePeriod: function() {
|
||||||
|
this.withinConnectingGracePeriod = false;
|
||||||
|
},
|
||||||
|
setSocketReconnectInterval: function(millis) {
|
||||||
|
this.socketReconnectWaitDuration = moment.duration(millis);
|
||||||
|
},
|
||||||
|
navigatorOnLine: function() { return navigator.onLine; },
|
||||||
|
getSocketStatus: function() { return window.getSocketStatus(); },
|
||||||
|
getNetworkStatus: function() {
|
||||||
|
|
||||||
|
var message = '';
|
||||||
|
var instructions = '';
|
||||||
|
var hasInterruption = false;
|
||||||
|
|
||||||
|
var socketStatus = this.getSocketStatus();
|
||||||
|
switch(socketStatus) {
|
||||||
|
case WebSocket.CONNECTING:
|
||||||
|
message = i18n('connecting');
|
||||||
|
this.setSocketReconnectInterval(null);
|
||||||
|
break;
|
||||||
|
case WebSocket.OPEN:
|
||||||
|
this.setSocketReconnectInterval(null);
|
||||||
|
break;
|
||||||
|
case WebSocket.CLOSING:
|
||||||
|
message = i18n('disconnected');
|
||||||
|
instructions = i18n('checkNetworkConnection');
|
||||||
|
hasInterruption = true;
|
||||||
|
break;
|
||||||
|
case WebSocket.CLOSED:
|
||||||
|
message = i18n('disconnected');
|
||||||
|
instructions = i18n('checkNetworkConnection');
|
||||||
|
hasInterruption = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socketStatus == WebSocket.CONNECTING && !this.withinConnectingGracePeriod) {
|
||||||
|
hasInterruption = true;
|
||||||
|
}
|
||||||
|
if (this.socketReconnectWaitDuration.asSeconds() > 0) {
|
||||||
|
instructions = i18n('attemptingReconnection', [this.socketReconnectWaitDuration.asSeconds()]);
|
||||||
|
}
|
||||||
|
if (!this.navigatorOnLine()) {
|
||||||
|
hasInterruption = true;
|
||||||
|
message = i18n('offline');
|
||||||
|
instructions = i18n('checkNetworkConnection');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: message,
|
||||||
|
instructions: instructions,
|
||||||
|
hasInterruption: hasInterruption
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var status = this.getNetworkStatus();
|
||||||
|
|
||||||
|
if (status.hasInterruption) {
|
||||||
|
this.$el.slideDown();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.$el.hide();
|
||||||
|
}
|
||||||
|
var template = Whisper.View.Templates['networkStatus'];
|
||||||
|
this.$el.html(Mustache.render(template, status, Whisper.View.Templates));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
|
@ -28,25 +28,33 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.socket-status {
|
.network-status-container {
|
||||||
float: right;
|
|
||||||
line-height: $button-height;
|
.network-status {
|
||||||
|
|
||||||
|
height:2 * $button-height;
|
||||||
|
background: url('/images/error_red.svg') no-repeat left 10px center;
|
||||||
|
background-size: 25px 25px;
|
||||||
|
background-color: #fcd156;
|
||||||
|
padding-top: 0.5 * $button-height;
|
||||||
|
padding-left: 2 * $button-height;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.network-status-message{
|
||||||
|
h3{
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
span{
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
|
||||||
display: inline;
|
|
||||||
padding-left: 20px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.connecting .icon {
|
|
||||||
background-color: $blue;
|
|
||||||
}
|
|
||||||
.closing {
|
|
||||||
background-color: $blue_l;
|
|
||||||
}
|
|
||||||
.closed {
|
|
||||||
background: url('/images/error_red.png') no-repeat left center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,10 +158,4 @@ $ios-border-color: rgba(0,0,0,0.1);
|
||||||
.hourglass {
|
.hourglass {
|
||||||
@include hourglass(#999);
|
@include hourglass(#999);
|
||||||
}
|
}
|
||||||
.socket-status {
|
|
||||||
position: absolute;
|
|
||||||
padding-top:-3px;
|
|
||||||
top:0;
|
|
||||||
right:5px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -747,20 +747,21 @@ img.emoji {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
|
.gutter .network-status-container .network-status {
|
||||||
.socket-status {
|
height: 48px;
|
||||||
float: right;
|
background: url("/images/error_red.svg") no-repeat left 10px center;
|
||||||
line-height: 24px; }
|
background-size: 25px 25px;
|
||||||
.socket-status * {
|
background-color: #fcd156;
|
||||||
display: inline;
|
padding-top: 12px;
|
||||||
padding-left: 20px;
|
padding-left: 48px;
|
||||||
vertical-align: middle; }
|
display: none; }
|
||||||
.socket-status .connecting .icon {
|
.gutter .network-status-container .network-status .network-status-message h3 {
|
||||||
background-color: #2090ea; }
|
padding: 0px;
|
||||||
.socket-status .closing {
|
margin: 0px;
|
||||||
background-color: #a2d2f4; }
|
margin-bottom: 4px;
|
||||||
.socket-status .closed {
|
font-size: 14px; }
|
||||||
background: url("/images/error_red.png") no-repeat left center; }
|
.gutter .network-status-container .network-status .network-status-message span {
|
||||||
|
font-size: 12px; }
|
||||||
|
|
||||||
.conversation-stack {
|
.conversation-stack {
|
||||||
padding-left: 300px; }
|
padding-left: 300px; }
|
||||||
|
@ -1559,11 +1560,6 @@ li.entry .error-icon-container {
|
||||||
-webkit-mask: url("/images/hourglass_empty.svg") no-repeat center;
|
-webkit-mask: url("/images/hourglass_empty.svg") no-repeat center;
|
||||||
-webkit-mask-size: 100%;
|
-webkit-mask-size: 100%;
|
||||||
background-color: #999; }
|
background-color: #999; }
|
||||||
.ios .socket-status {
|
|
||||||
position: absolute;
|
|
||||||
padding-top: -3px;
|
|
||||||
top: 0;
|
|
||||||
right: 5px; }
|
|
||||||
|
|
||||||
.android #header {
|
.android #header {
|
||||||
background-color: #2090ea;
|
background-color: #2090ea;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
<script type='text/x-tmpl-mustache' id='two-column'>
|
<script type='text/x-tmpl-mustache' id='two-column'>
|
||||||
<div class='gutter'>
|
<div class='gutter'>
|
||||||
|
<div class='network-status-container'></div>
|
||||||
<div class='title-bar active' id='header'>
|
<div class='title-bar active' id='header'>
|
||||||
<div class='header-buttons right'>
|
<div class='header-buttons right'>
|
||||||
<div class='vertical-align'>
|
<div class='vertical-align'>
|
||||||
|
@ -29,7 +30,6 @@
|
||||||
<li class='restart-signal'>{{ restartSignal }}</li>
|
<li class='restart-signal'>{{ restartSignal }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<span class='socket-status'></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1>Signal</h1>
|
<h1>Signal</h1>
|
||||||
|
@ -485,6 +485,19 @@
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script type='text/x-tmpl-mustache' id='networkStatus'>
|
||||||
|
<div class='network-status-message' style='{{^instructions}}margin-top:3px;{{/instructions}}{{#instructions}}margin-top:-6px{{/instructions}}'>
|
||||||
|
<h3 style='{{^instructions}}font-size:17px;{{/instructions}}'>{{ message }}</h3>
|
||||||
|
<span>{{ instructions }}</span>
|
||||||
|
</div>
|
||||||
|
{{ #reconnectDurationAsSeconds }}
|
||||||
|
<div class="network-status-message">
|
||||||
|
{{ attemptingReconnectionMessage }}
|
||||||
|
</div>
|
||||||
|
{{/reconnectDurationAsSeconds }}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript" src="test.js"></script>
|
<script type="text/javascript" src="test.js"></script>
|
||||||
<script type="text/javascript" src="blanket_mocha.js"></script>
|
<script type="text/javascript" src="blanket_mocha.js"></script>
|
||||||
|
|
||||||
|
@ -529,7 +542,9 @@
|
||||||
<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/conversation_search_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/conversation_search_view.js' data-cover></script>
|
||||||
<script type='text/javascript' src='../js/views/hint_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/hint_view.js' data-cover></script>
|
||||||
|
<script type='text/javascript' src='../js/views/network_status_view.js' data-cover></script>
|
||||||
<script type='text/javascript' src='../js/views/inbox_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/inbox_view.js' data-cover></script>
|
||||||
|
<script type='text/javascript' src='../js/views/network_status_view.js'></script>
|
||||||
<script type='text/javascript' src='../js/views/confirmation_dialog_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/confirmation_dialog_view.js' data-cover></script>
|
||||||
<script type='text/javascript' src='../js/views/identicon_svg_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/identicon_svg_view.js' data-cover></script>
|
||||||
<script type='text/javascript' src='../js/views/settings_view.js' data-cover></script>
|
<script type='text/javascript' src='../js/views/settings_view.js' data-cover></script>
|
||||||
|
@ -542,6 +557,7 @@
|
||||||
<script type="text/javascript" src="views/timestamp_view_test.js"></script>
|
<script type="text/javascript" src="views/timestamp_view_test.js"></script>
|
||||||
<script type="text/javascript" src="views/list_view_test.js"></script>
|
<script type="text/javascript" src="views/list_view_test.js"></script>
|
||||||
<script type="text/javascript" src="views/conversation_search_view_test.js"></script>
|
<script type="text/javascript" src="views/conversation_search_view_test.js"></script>
|
||||||
|
<script type="text/javascript" src="views/network_status_view_test.js"></script>
|
||||||
<script type="text/javascript" src="models/conversations_test.js"></script>
|
<script type="text/javascript" src="models/conversations_test.js"></script>
|
||||||
<script type="text/javascript" src="models/messages_test.js"></script>
|
<script type="text/javascript" src="models/messages_test.js"></script>
|
||||||
<script type="text/javascript" src="storage_test.js"></script>
|
<script type="text/javascript" src="storage_test.js"></script>
|
||||||
|
|
125
test/views/network_status_view_test.js
Normal file
125
test/views/network_status_view_test.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
|
||||||
|
describe('NetworkStatusView', function() {
|
||||||
|
describe('getNetworkStatus', function() {
|
||||||
|
var networkStatusView;
|
||||||
|
var socketStatus = WebSocket.OPEN;
|
||||||
|
|
||||||
|
var oldGetMessage;
|
||||||
|
var oldGetSocketStatus;
|
||||||
|
|
||||||
|
/* BEGIN stubbing globals */
|
||||||
|
before(function() {
|
||||||
|
oldGetSocketStatus = window.getSocketStatus;
|
||||||
|
/* chrome i18n support is missing in 'regular' webpages */
|
||||||
|
window.chrome.i18n = { getMessage: function(message, args) {
|
||||||
|
// translationMessageName-arg1-arg2
|
||||||
|
return _([message, args]).chain().flatten().compact().value().join('-');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.getSocketStatus = function() { return socketStatus; };
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
window.getSocketStatus = oldGetSocketStatus;
|
||||||
|
});
|
||||||
|
/* END stubbing globals */
|
||||||
|
|
||||||
|
beforeEach(function(done) {
|
||||||
|
|
||||||
|
networkStatusView = new Whisper.NetworkStatusView();
|
||||||
|
$('.network-status-container').append(networkStatusView.el);
|
||||||
|
// stubbing global
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
describe('initialization', function() {
|
||||||
|
it('should have an empty interval', function() {
|
||||||
|
assert.equal(networkStatusView.socketReconnectWaitDuration.asSeconds(), 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('network status with no connection', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
networkStatusView.navigatorOnLine = function() { return false; };
|
||||||
|
});
|
||||||
|
it('should be interrupted', function() {
|
||||||
|
networkStatusView.render();
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
assert(status.hasInterruption);
|
||||||
|
assert.equal(status.instructions, "checkNetworkConnection");
|
||||||
|
});
|
||||||
|
it('should display an offline message', function() {
|
||||||
|
networkStatusView.render();
|
||||||
|
assert.match(networkStatusView.$el.text(), /offline/);
|
||||||
|
});
|
||||||
|
it('should override socket status', function() {
|
||||||
|
_([WebSocket.CONNECTING,
|
||||||
|
WebSocket.OPEN,
|
||||||
|
WebSocket.CLOSING,
|
||||||
|
WebSocket.CLOSED]).map(function(socketStatusVal) {
|
||||||
|
socketStatus = socketStatusVal;
|
||||||
|
networkStatusView.render();
|
||||||
|
assert.match(networkStatusView.$el.text(), /offline/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('network status when socket is connecting', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
socketStatus = WebSocket.CONNECTING;
|
||||||
|
networkStatusView.render();
|
||||||
|
});
|
||||||
|
it('it should display a connecting string if connecting and not in the connecting grace period', function() {
|
||||||
|
networkStatusView.withinConnectingGracePeriod = false;
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
|
||||||
|
assert.match(networkStatusView.$el.text(), /connecting/);
|
||||||
|
});
|
||||||
|
it('it should not be interrupted if in connecting grace period', function() {
|
||||||
|
assert(networkStatusView.withinConnectingGracePeriod);
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
|
||||||
|
assert.match(networkStatusView.$el.text(), /connecting/);
|
||||||
|
assert(!status.hasInterruption);
|
||||||
|
});
|
||||||
|
it('it should be interrupted if connecting grace period is over', function() {
|
||||||
|
networkStatusView.withinConnectingGracePeriod = false;
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
|
||||||
|
assert(status.hasInterruption);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('network status when socket is open', function() {
|
||||||
|
before(function() {
|
||||||
|
socketStatus = WebSocket.OPEN;
|
||||||
|
});
|
||||||
|
it('should not be interrupted', function() {
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
assert(!status.hasInterruption);
|
||||||
|
assert.match(networkStatusView.$el.find('.network-status-message').text().trim(), /^$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('network status when socket is closed or closing', function() {
|
||||||
|
_([WebSocket.CLOSED, WebSocket.CLOSING]).map(function(socketStatusVal) {
|
||||||
|
it('should be interrupted', function() {
|
||||||
|
socketStatus = socketStatusVal;
|
||||||
|
networkStatusView.render();
|
||||||
|
var status = networkStatusView.getNetworkStatus();
|
||||||
|
assert(status.hasInterruption);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('the socket reconnect interval', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
socketStatus = WebSocket.CLOSED;
|
||||||
|
networkStatusView.setSocketReconnectInterval(61000);
|
||||||
|
networkStatusView.render();
|
||||||
|
});
|
||||||
|
it('should format the message based on the socketReconnectWaitDuration property', function() {
|
||||||
|
assert.equal(networkStatusView.socketReconnectWaitDuration.asSeconds(), 61);
|
||||||
|
assert.match(networkStatusView.$('.network-status-message:last').text(), /attemptingReconnection-61/);
|
||||||
|
});
|
||||||
|
it('should be reset by changing the socketStatus to CONNECTING', function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue