Bug 972019: Terminate a call. r=Standard8

This commit is contained in:
Nicolas Perriault 2014-05-29 21:13:43 +01:00
parent 8db84a03e6
commit 85debee2c2
6 changed files with 95 additions and 42 deletions

View File

@ -14,6 +14,9 @@
<div id="messages"></div>
<div id="conversation" class="conversation">
<nav class="controls">
<button class="btn stop" data-l10n-id="stop"></button>
</nav>
<div class="media nested">
<div class="remote">
<div id="incoming"></div>
@ -24,6 +27,7 @@
</div>
</div>
<script type="text/javascript" src="js/fxcom.js"></script>
<script type="text/javascript" src="libs/l10n.js"></script>
<script type="text/javascript" src="shared/libs/sdk.js"></script>
<script type="text/javascript" src="shared/libs/jquery-2.1.0.js"></script>

View File

@ -7,12 +7,13 @@
Components.utils.import("resource://gre/modules/Services.jsm");
var loop = loop || {};
loop.conversation = (function(TB, mozl10n) {
loop.conversation = (function(TB, mozL10n) {
"use strict";
var baseServerUrl = Services.prefs.getCharPref("loop.server"),
var sharedViews = loop.shared.views,
baseServerUrl = Services.prefs.getCharPref("loop.server"),
// aliasing translation function as __ for concision
__ = mozl10n.get;
__ = mozL10n.get;
/**
* App router.
@ -34,9 +35,17 @@ loop.conversation = (function(TB, mozl10n) {
* - {loop.shared.components.Notifier} notifier Notifier component.
*/
var ConversationRouter = loop.shared.router.BaseRouter.extend({
/**
* Current conversation.
* @type {loop.shared.models.ConversationModel}
*/
_conversation: undefined,
_notifier: undefined,
activeView: undefined,
/**
* Notifications dispatcher.
* @type {loop.shared.views.NotificationListView}
*/
_notifier: undefined,
routes: {
"start/:version": "start",
@ -44,18 +53,6 @@ loop.conversation = (function(TB, mozl10n) {
"call/ended": "ended"
},
/**
* Loads and render current active view.
*
* @param {loop.shared.BaseView} view View.
*/
loadView : function(view) {
if (this.activeView) {
this.activeView.hide();
}
this.activeView = view.render().show();
},
initialize: function(options) {
options = options || {};
if (!options.conversation) {
@ -70,6 +67,9 @@ loop.conversation = (function(TB, mozl10n) {
this.listenTo(this._conversation, "session:ready", this._onSessionReady);
this.listenTo(this._conversation, "session:ended", this._onSessionEnded);
this.listenTo(this._conversation, "session:peer-hung", this._onPeerHung);
this.listenTo(this._conversation, "session:network-disconnected",
this._onNetworkDisconnected);
},
/**
@ -80,12 +80,35 @@ loop.conversation = (function(TB, mozl10n) {
},
/**
* Navigates to ended state when the call has ended
* Navigates to ended state when the call has ended.
*/
_onSessionEnded: function() {
this.navigate("call/ended", {trigger: true});
},
/**
* Peer hung up. Navigates back to call initiation so the user can start
* calling again.
*
* Event properties:
* - {String} connectionId: OT session id
*
* @param {Object} event
*/
_onPeerHung: function(event) {
this._notifier.warn(__("peer_ended_conversation"));
this.navigate("call/ended", {trigger: true});
},
/**
* Network disconnected. Navigates back to call initiation so the user can
* start calling again.
*/
_onNetworkDisconnected: function() {
this._notifier.warn(__("network_disconnected"));
this.navigate("call/ended", {trigger: true});
},
/**
* start is the initial route that does any necessary prompting and set
* up for the call.
@ -109,10 +132,9 @@ loop.conversation = (function(TB, mozl10n) {
*/
conversation: function() {
if (!this._conversation.isSessionReady()) {
// XXX: notify user that something has gone wrong.
console.error("Error: navigated to conversation route without " +
"the start route to initialise the call first");
this._notifier.notify(__("cannot_start_call_session_not_ready"));
this._notifier.error(__("cannot_start_call_session_not_ready"));
return;
}
@ -139,9 +161,7 @@ loop.conversation = (function(TB, mozl10n) {
conversation = new loop.shared.models.ConversationModel();
router = new ConversationRouter({
conversation: conversation,
notifier: new loop.shared.views.NotificationListView({
el: "#messages"
})
notifier: new sharedViews.NotificationListView({el: "#messages"})
});
Backbone.history.start();
}

View File

@ -7,13 +7,13 @@
Components.utils.import("resource://gre/modules/Services.jsm");
var loop = loop || {};
loop.panel = (function(TB, mozl10n) {
loop.panel = (function(mozL10n) {
"use strict";
var baseServerUrl = Services.prefs.getCharPref("loop.server"),
panelView,
// aliasing translation function as __ for concision
__ = mozl10n.get;
__ = mozL10n.get;
/**
* Panel view.
@ -91,4 +91,4 @@ loop.panel = (function(TB, mozl10n) {
init: init,
PanelView: PanelView
};
})(_, document.mozL10n);
})(document.mozL10n);

View File

@ -15,7 +15,11 @@ describe("loop.conversation", function() {
beforeEach(function() {
sandbox = sinon.sandbox.create();
notifier = {notify: sandbox.spy()};
notifier = {
notify: sandbox.spy(),
warn: sandbox.spy(),
error: sandbox.spy()
};
});
afterEach(function() {
@ -99,7 +103,7 @@ describe("loop.conversation", function() {
function() {
router.conversation();
sinon.assert.calledOnce(router._notifier.notify);
sinon.assert.calledOnce(router._notifier.error);
});
});
@ -117,7 +121,7 @@ describe("loop.conversation", function() {
});
describe("Events", function() {
var fakeSessionData;
var router, fakeSessionData;
beforeEach(function() {
fakeSessionData = {
@ -125,16 +129,17 @@ describe("loop.conversation", function() {
sessionToken: "sessionToken",
apiKey: "apiKey"
};
sandbox.stub(loop.conversation.ConversationRouter.prototype,
"navigate");
conversation.set("loopToken", "fakeToken");
router = new loop.conversation.ConversationRouter({
conversation: conversation,
notifier: notifier
});
});
it("should navigate to call/ongoing once the call session is ready",
function() {
sandbox.stub(ConversationRouter.prototype, "navigate");
var router = new ConversationRouter({
conversation: conversation,
notifier: notifier
});
conversation.setReady(fakeSessionData);
sinon.assert.calledOnce(router.navigate);
@ -143,14 +148,35 @@ describe("loop.conversation", function() {
it("should navigate to call/ended when the call session ends",
function() {
sandbox.stub(ConversationRouter.prototype, "navigate");
var router = new ConversationRouter({
conversation: conversation,
notifier: notifier
});
conversation.trigger("session:ended");
sinon.assert.calledOnce(router.navigate);
sinon.assert.calledWith(router.navigate, "call/ended");
});
it("should warn the user when peer hangs up", function() {
conversation.trigger("session:peer-hung");
sinon.assert.calledOnce(notifier.warn);
});
it("should navigate to call/ended when peer hangs up", function() {
conversation.trigger("session:peer-hung");
sinon.assert.calledOnce(router.navigate);
sinon.assert.calledWith(router.navigate, "call/ended");
});
it("should warn the user when network disconnects", function() {
conversation.trigger("session:network-disconnected");
sinon.assert.calledOnce(notifier.warn);
});
it("should navigate to call/{token} when network disconnects",
function() {
conversation.trigger("session:network-disconnected");
sinon.assert.calledOnce(router.navigate);
sinon.assert.calledWith(router.navigate, "call/ended");
});

View File

@ -10,7 +10,7 @@
</head>
<body>
<div id="mocha">
<p><a href=".">Index</a></p>
<p><a href="../">Index</a></p>
</div>
<div id="messages"></div>
<div id="fixtures"></div>

View File

@ -5,3 +5,6 @@ unable_retrieve_url=Sorry, we were unable to retrieve a call url.
share_link_url=Share the link below with your friend to start your call!
caller.placeholder=Identify this call
cannot_start_call_session_not_ready=Can't start call, session is not ready.
network_disconnected=The network connection terminated abruptly.
peer_ended_conversation=Your peer ended the conversation.
stop=Stop