mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 987252 - Using new shared notification system. r=Standard8
This commit is contained in:
parent
3569e14679
commit
1513560b26
@ -10,6 +10,9 @@
|
||||
<link rel="stylesheet" type="text/css" href="shared/css/conversation.css">
|
||||
</head>
|
||||
<body onload="loop.conversation.init();">
|
||||
|
||||
<div id="messages"></div>
|
||||
|
||||
<div id="conversation" class="conversation">
|
||||
<div class="media nested">
|
||||
<div class="remote">
|
||||
@ -20,6 +23,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<script type="text/javascript" src="shared/libs/lodash-2.4.1.js"></script>
|
||||
|
@ -2,15 +2,17 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*global loop*/
|
||||
/* global loop:true */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var loop = loop || {};
|
||||
loop.conversation = (function(TB) {
|
||||
loop.conversation = (function(TB, mozl10n) {
|
||||
"use strict";
|
||||
|
||||
var baseServerUrl = Services.prefs.getCharPref("loop.server");
|
||||
var baseServerUrl = Services.prefs.getCharPref("loop.server"),
|
||||
// aliasing translation function as __ for concision
|
||||
__ = mozl10n.get;
|
||||
|
||||
/**
|
||||
* App router.
|
||||
@ -24,9 +26,17 @@ loop.conversation = (function(TB) {
|
||||
*/
|
||||
var conversation;
|
||||
|
||||
/**
|
||||
* Conversation router.
|
||||
*
|
||||
* Required options:
|
||||
* - {loop.shared.models.ConversationModel} conversation Conversation model.
|
||||
* - {loop.shared.components.Notifier} notifier Notifier component.
|
||||
*/
|
||||
var ConversationRouter = loop.shared.router.BaseRouter.extend({
|
||||
_conversation: undefined,
|
||||
activeView: undefined,
|
||||
_notifier: undefined,
|
||||
activeView: undefined,
|
||||
|
||||
routes: {
|
||||
"start/:version": "start",
|
||||
@ -53,6 +63,11 @@ loop.conversation = (function(TB) {
|
||||
}
|
||||
this._conversation = options.conversation;
|
||||
|
||||
if (!options.notifier) {
|
||||
throw new Error("missing required notifier");
|
||||
}
|
||||
this._notifier = options.notifier;
|
||||
|
||||
this.listenTo(this._conversation, "session:ready", this._onSessionReady);
|
||||
this.listenTo(this._conversation, "session:ended", this._onSessionEnded);
|
||||
},
|
||||
@ -97,6 +112,7 @@ loop.conversation = (function(TB) {
|
||||
// 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"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -121,7 +137,12 @@ loop.conversation = (function(TB) {
|
||||
*/
|
||||
function init() {
|
||||
conversation = new loop.shared.models.ConversationModel();
|
||||
router = new ConversationRouter({conversation: conversation});
|
||||
router = new ConversationRouter({
|
||||
conversation: conversation,
|
||||
notifier: new loop.shared.views.NotificationListView({
|
||||
el: "#messages"
|
||||
})
|
||||
});
|
||||
Backbone.history.start();
|
||||
}
|
||||
|
||||
@ -129,4 +150,4 @@ loop.conversation = (function(TB) {
|
||||
ConversationRouter: ConversationRouter,
|
||||
init: init
|
||||
};
|
||||
})(window.TB);
|
||||
})(window.TB, document.mozL10n);
|
||||
|
@ -2,91 +2,23 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*global loop*/
|
||||
/* global loop:true */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var loop = loop || {};
|
||||
loop.panel = (function(_, __) {
|
||||
loop.panel = (function(TB, mozl10n) {
|
||||
"use strict";
|
||||
|
||||
var baseServerUrl = Services.prefs.getCharPref("loop.server"),
|
||||
panelView;
|
||||
|
||||
/**
|
||||
* Panel initialisation.
|
||||
*/
|
||||
function init() {
|
||||
panelView = new PanelView();
|
||||
panelView.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification model.
|
||||
*/
|
||||
var NotificationModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
level: "info",
|
||||
message: ""
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification collection
|
||||
*/
|
||||
var NotificationCollection = Backbone.Collection.extend({
|
||||
model: NotificationModel
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification view.
|
||||
*/
|
||||
var NotificationView = Backbone.View.extend({
|
||||
template: _.template([
|
||||
'<div class="alert alert-<%- level %>">',
|
||||
' <button class="close"></button>',
|
||||
' <p class="message"><%- message %></p>',
|
||||
'</div>'
|
||||
].join("")),
|
||||
|
||||
events: {
|
||||
"click .close": "dismiss"
|
||||
},
|
||||
|
||||
dismiss: function() {
|
||||
this.$el.addClass("fade-out");
|
||||
setTimeout(function() {
|
||||
this.collection.remove(this.model);
|
||||
this.remove();
|
||||
}.bind(this), 500);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification list view.
|
||||
*/
|
||||
var NotificationListView = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.listenTo(this.collection, "reset add remove", this.render);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.collection.map(function(notification) {
|
||||
return new NotificationView({
|
||||
model: notification,
|
||||
collection: this.collection
|
||||
}).render().$el;
|
||||
}.bind(this)));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
panelView,
|
||||
// aliasing translation function as __ for concision
|
||||
__ = mozl10n.get;
|
||||
|
||||
/**
|
||||
* Panel view.
|
||||
*
|
||||
* XXX view layout changes should be handled by a router really.
|
||||
*/
|
||||
var PanelView = Backbone.View.extend({
|
||||
el: "#default-view",
|
||||
@ -101,19 +33,9 @@ loop.panel = (function(_, __) {
|
||||
this.client = new loop.shared.Client({
|
||||
baseServerUrl: baseServerUrl
|
||||
});
|
||||
this.notificationCollection = new NotificationCollection();
|
||||
this.notificationListView = new NotificationListView({
|
||||
el: this.$(".messages"),
|
||||
collection: this.notificationCollection
|
||||
});
|
||||
this.notificationListView.render();
|
||||
},
|
||||
|
||||
notify: function(message, level) {
|
||||
this.notificationCollection.add({
|
||||
level: level || "info",
|
||||
message: message
|
||||
});
|
||||
this.notifier = new loop.shared.views.NotificationListView({
|
||||
el: this.$(".messages")
|
||||
}).render();
|
||||
},
|
||||
|
||||
getCallUrl: function(event) {
|
||||
@ -121,7 +43,10 @@ loop.panel = (function(_, __) {
|
||||
var nickname = this.$("input[name=caller]").val();
|
||||
var callback = function(err, callUrl) {
|
||||
if (err) {
|
||||
this.notify(__("unable_retrieve_url"), "error");
|
||||
this.notifier.notify({
|
||||
message: __("unable_retrieve_url"),
|
||||
level: "error"
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.onCallUrlReceived(callUrl);
|
||||
@ -137,7 +62,7 @@ loop.panel = (function(_, __) {
|
||||
},
|
||||
|
||||
onCallUrlReceived: function(callUrl) {
|
||||
this.notificationCollection.reset();
|
||||
this.notifier.clear();
|
||||
this.$(".action .invite").hide();
|
||||
this.$(".action .invite input").val("");
|
||||
this.$(".action .result input").val(callUrl);
|
||||
@ -154,12 +79,16 @@ loop.panel = (function(_, __) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Panel initialisation.
|
||||
*/
|
||||
function init() {
|
||||
panelView = new PanelView();
|
||||
panelView.render();
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
NotificationModel: NotificationModel,
|
||||
NotificationCollection: NotificationCollection,
|
||||
NotificationView: NotificationView,
|
||||
NotificationListView: NotificationListView,
|
||||
PanelView: PanelView
|
||||
};
|
||||
})(_, document.mozL10n.get);
|
||||
})(_, document.mozL10n);
|
||||
|
@ -45,6 +45,8 @@
|
||||
<script type="text/javascript" src="shared/libs/lodash-2.4.1.js"></script>
|
||||
<script type="text/javascript" src="shared/libs/backbone-1.1.2.js"></script>
|
||||
<script type="text/javascript" src="shared/js/client.js"></script>
|
||||
<script type="text/javascript" src="shared/js/models.js"></script>
|
||||
<script type="text/javascript" src="shared/js/views.js"></script>
|
||||
<script type="text/javascript" src="js/panel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -10,10 +10,12 @@ describe("loop.conversation", function() {
|
||||
"use strict";
|
||||
|
||||
var ConversationRouter = loop.conversation.ConversationRouter,
|
||||
sandbox;
|
||||
sandbox,
|
||||
notifier;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
notifier = {notify: sandbox.spy()};
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
@ -33,13 +35,22 @@ describe("loop.conversation", function() {
|
||||
new ConversationRouter();
|
||||
}).to.Throw(Error, /missing required conversation/);
|
||||
});
|
||||
|
||||
it("should require a notifier", function() {
|
||||
expect(function() {
|
||||
new ConversationRouter({conversation: conversation});
|
||||
}).to.Throw(Error, /missing required notifier/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Routes", function() {
|
||||
var router;
|
||||
|
||||
beforeEach(function() {
|
||||
router = new ConversationRouter({conversation: conversation});
|
||||
router = new ConversationRouter({
|
||||
conversation: conversation,
|
||||
notifier: notifier
|
||||
});
|
||||
sandbox.stub(router, "loadView");
|
||||
});
|
||||
|
||||
@ -83,6 +94,13 @@ describe("loop.conversation", function() {
|
||||
|
||||
sinon.assert.notCalled(router.loadView);
|
||||
});
|
||||
|
||||
it("should notify the user when session is not set",
|
||||
function() {
|
||||
router.conversation();
|
||||
|
||||
sinon.assert.calledOnce(router._notifier.notify);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#ended", function() {
|
||||
@ -113,7 +131,8 @@ describe("loop.conversation", function() {
|
||||
function() {
|
||||
sandbox.stub(ConversationRouter.prototype, "navigate");
|
||||
var router = new ConversationRouter({
|
||||
conversation: conversation
|
||||
conversation: conversation,
|
||||
notifier: notifier
|
||||
});
|
||||
|
||||
conversation.setReady(fakeSessionData);
|
||||
@ -126,7 +145,8 @@ describe("loop.conversation", function() {
|
||||
function() {
|
||||
sandbox.stub(ConversationRouter.prototype, "navigate");
|
||||
var router = new ConversationRouter({
|
||||
conversation: conversation
|
||||
conversation: conversation,
|
||||
notifier: notifier
|
||||
});
|
||||
|
||||
conversation.trigger("session:ended");
|
||||
|
@ -26,61 +26,6 @@ describe("loop.panel", function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("loop.panel.NotificationView", function() {
|
||||
describe("#render", function() {
|
||||
it("should render template with model attribute values", function() {
|
||||
var view = new loop.panel.NotificationView({
|
||||
el: $("#fixtures"),
|
||||
model: new loop.panel.NotificationModel({
|
||||
level: "error",
|
||||
message: "plop"
|
||||
})
|
||||
});
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view.$(".message").text()).eql("plop");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.panel.NotificationListView", function() {
|
||||
describe("Collection events", function() {
|
||||
var coll, testNotif, view;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(loop.panel.NotificationListView.prototype, "render");
|
||||
testNotif = new loop.panel.NotificationModel({
|
||||
level: "error",
|
||||
message: "plop"
|
||||
});
|
||||
coll = new loop.panel.NotificationCollection();
|
||||
view = new loop.panel.NotificationListView({collection: coll});
|
||||
});
|
||||
|
||||
it("should render on notification added to the collection", function() {
|
||||
coll.add(testNotif);
|
||||
|
||||
sinon.assert.calledOnce(view.render);
|
||||
});
|
||||
|
||||
it("should render on notification removed from the collection",
|
||||
function() {
|
||||
coll.add(testNotif);
|
||||
coll.remove(testNotif);
|
||||
|
||||
sinon.assert.calledTwice(view.render);
|
||||
});
|
||||
|
||||
it("should render on collection reset",
|
||||
function() {
|
||||
coll.reset();
|
||||
|
||||
sinon.assert.calledOnce(view.render);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.panel.PanelView", function() {
|
||||
beforeEach(function() {
|
||||
$("#fixtures").append([
|
||||
@ -104,7 +49,7 @@ describe("loop.panel", function() {
|
||||
].join(""));
|
||||
});
|
||||
|
||||
describe("#getCallurl", function() {
|
||||
describe("#getCallUrl", function() {
|
||||
it("should request a call url to the server", function() {
|
||||
var requestCallUrl = sandbox.stub(loop.shared.Client.prototype,
|
||||
"requestCallUrl");
|
||||
@ -115,6 +60,20 @@ describe("loop.panel", function() {
|
||||
sinon.assert.calledOnce(requestCallUrl);
|
||||
sinon.assert.calledWith(requestCallUrl, "foo");
|
||||
});
|
||||
|
||||
it("should notify the user when the operation failed", function() {
|
||||
var requestCallUrl = sandbox.stub(
|
||||
loop.shared.Client.prototype, "requestCallUrl", function(_, cb) {
|
||||
cb("fake error");
|
||||
});
|
||||
var view = new loop.panel.PanelView();
|
||||
sandbox.stub(view.notifier, "notify");
|
||||
|
||||
view.getCallUrl({preventDefault: sandbox.spy()});
|
||||
|
||||
sinon.assert.calledOnce(view.notifier.notify);
|
||||
sinon.assert.calledWithMatch(view.notifier.notify, {level: "error"});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#onCallUrlReceived", function() {
|
||||
@ -126,6 +85,15 @@ describe("loop.panel", function() {
|
||||
|
||||
expect(view.$("#call-url").val()).eql("http://call.me/");
|
||||
});
|
||||
|
||||
it("should reset all pending notifications", function() {
|
||||
var view = new loop.panel.PanelView().render();
|
||||
sandbox.stub(view.notifier, "clear");
|
||||
|
||||
view.onCallUrlReceived("http://call.me/");
|
||||
|
||||
sinon.assert.calledOnce(view.notifier.clear, "clear");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -4,3 +4,4 @@ new_url=New url
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user