diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 49da008e7479..4fb543bcfda8 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1505,6 +1505,7 @@ pref("image.mem.max_decoded_image_kb", 256000);
// XXX This is a temporary development server. The production one will be
// coming soon.
pref("loop.server", "http://loop.dev.mozaws.net");
+pref("loop.do_not_disturb", false);
#endif
// serverURL to be assigned by services team
diff --git a/browser/components/loop/MozLoopAPI.jsm b/browser/components/loop/MozLoopAPI.jsm
index ad317ff6191c..9fe14bd0b163 100644
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -25,6 +25,20 @@ this.EXPORTED_SYMBOLS = ["injectLoopAPI"];
*/
function injectLoopAPI(targetWindow) {
let api = {
+ /**
+ * Sets and gets the "do not disturb" mode activation flag.
+ */
+ doNotDisturb: {
+ enumerable: true,
+ configurable: true,
+ get: function() {
+ return MozLoopService.doNotDisturb;
+ },
+ set: function(aFlag) {
+ MozLoopService.doNotDisturb = aFlag;
+ }
+ },
+
/**
* Returns the url for the Loop server from preferences.
*
diff --git a/browser/components/loop/MozLoopService.jsm b/browser/components/loop/MozLoopService.jsm
index 9783f8dda2ac..d66fe1ee200c 100644
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -200,6 +200,24 @@ let MozLoopServiceInternal = {
}
},
+ /**
+ * Retrieves MozLoopService "do not disturb" pref value.
+ *
+ * @return {Boolean} aFlag
+ */
+ get doNotDisturb() {
+ return Services.prefs.getBoolPref("loop.do_not_disturb");
+ },
+
+ /**
+ * Sets MozLoopService "do not disturb" pref value.
+ *
+ * @param {Boolean} aFlag
+ */
+ set doNotDisturb(aFlag) {
+ Services.prefs.setBoolPref("loop.do_not_disturb", Boolean(aFlag));
+ },
+
/**
* Starts the initialization of the service, which goes and registers
* with the push server and the loop server.
@@ -327,6 +345,10 @@ let MozLoopServiceInternal = {
* @param {String} version The version information from the server.
*/
onHandleNotification: function(version) {
+ if (this.doNotDisturb) {
+ return;
+ }
+
this.openChatWindow(null, "LooP", "about:loopconversation#start/" + version);
},
@@ -503,6 +525,24 @@ this.MozLoopService = {
return JSON.stringify(stringData[key]);
},
+ /**
+ * Retrieves MozLoopService "do not disturb" value.
+ *
+ * @return {Boolean}
+ */
+ get doNotDisturb() {
+ return MozLoopServiceInternal.doNotDisturb;
+ },
+
+ /**
+ * Sets MozLoopService "do not disturb" value.
+ *
+ * @param {Boolean} aFlag
+ */
+ set doNotDisturb(aFlag) {
+ MozLoopServiceInternal.doNotDisturb = aFlag;
+ },
+
/**
* Returns the current locale
*
diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js
index 6ddc69a454ee..60456bd8dc52 100644
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -18,6 +18,37 @@ loop.panel = (function(_, mozL10n) {
*/
var router;
+ /**
+ * Do not disturb panel subview.
+ */
+ var DoNotDisturbView = sharedViews.BaseView.extend({
+ template: _.template([
+ '',
+ ].join('')),
+
+ events: {
+ "click input[type=checkbox]": "toggle"
+ },
+
+ /**
+ * Toggles mozLoop activation status.
+ */
+ toggle: function() {
+ navigator.mozLoop.doNotDisturb = !navigator.mozLoop.doNotDisturb;
+ this.render();
+ },
+
+ render: function() {
+ this.$el.html(this.template({
+ checked: navigator.mozLoop.doNotDisturb ? "checked" : ""
+ }));
+ return this;
+ }
+ });
+
/**
* Panel view.
*/
@@ -27,23 +58,30 @@ loop.panel = (function(_, mozL10n) {
'
',
'',
'',
- '
',
- ' ',
- '
',
+ ' ',
'
',
' ',
' ',
'
',
+ '
',
'
',
].join("")),
className: "share generate-url",
+ /**
+ * Do not disturb view.
+ * @type {DoNotDisturbView|undefined}
+ */
+ dndView: undefined,
+
events: {
"keyup input[name=caller]": "changeButtonState",
- "click .get-url": "getCallUrl",
+ "submit form.invite": "getCallUrl",
"click a.go-back": "goBack"
},
@@ -54,7 +92,7 @@ loop.panel = (function(_, mozL10n) {
}
this.notifier = options.notifier;
this.client = new loop.shared.Client({
- baseServerUrl: window.navigator.mozLoop.serverUrl
+ baseServerUrl: navigator.mozLoop.serverUrl
});
},
@@ -69,6 +107,7 @@ loop.panel = (function(_, mozL10n) {
this.clearPending();
if (err) {
this.notifier.errorL10n("unable_retrieve_url");
+ this.render();
return;
}
this.onCallUrlReceived(callUrlData);
@@ -113,6 +152,13 @@ loop.panel = (function(_, mozL10n) {
} else {
this.$(".get-url").addClass("disabled").attr("disabled", "disabled");
}
+ },
+
+ render: function() {
+ this.$el.html(this.template());
+ // Do not Disturb sub view
+ this.dndView = new DoNotDisturbView({el: this.$(".dnd")}).render();
+ return this;
}
});
@@ -179,7 +225,7 @@ loop.panel = (function(_, mozL10n) {
function init() {
// Do the initial L10n setup, we do this before anything
// else to ensure the L10n environment is setup correctly.
- mozL10n.initialize(window.navigator.mozLoop);
+ mozL10n.initialize(navigator.mozLoop);
router = new PanelRouter({
document: document,
@@ -196,6 +242,7 @@ loop.panel = (function(_, mozL10n) {
return {
init: init,
PanelView: PanelView,
+ DoNotDisturbView: DoNotDisturbView,
PanelRouter: PanelRouter
};
})(_, document.mozL10n);
diff --git a/browser/components/loop/content/shared/css/panel.css b/browser/components/loop/content/shared/css/panel.css
index 7960692c81ce..c99d09840b35 100644
--- a/browser/components/loop/content/shared/css/panel.css
+++ b/browser/components/loop/content/shared/css/panel.css
@@ -49,12 +49,17 @@
margin: 0 0 1em 0;
}
-.share .action input {
+.share .action p.dnd {
+ margin-top: 1em;
+}
+
+.share .action input[type="text"],
+.share .action input[type="url"] {
border: 1px solid #ccc; /* Overriding background style for a text input (see
below) resets its borders to a weird beveled style;
defining a default 1px border solves the issue. */
font-size: .9em;
- width: 60%;
+ width: 65%;
padding: .5em;
}
@@ -73,10 +78,6 @@
/* Specific cases */
-.share.generate-url .action {
- text-align: center;
-}
-
.panel #messages .alert {
margin-bottom: 0;
}
diff --git a/browser/components/loop/test/desktop-local/panel_test.js b/browser/components/loop/test/desktop-local/panel_test.js
index ccba5a729cfd..f167b1d56ab3 100644
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -35,7 +35,8 @@ describe("loop.panel", function() {
errorL10n: sandbox.spy()
};
- window.navigator.mozLoop = {
+ navigator.mozLoop = {
+ doNotDisturb: true,
get serverUrl() {
return "http://example.com";
},
@@ -46,11 +47,11 @@ describe("loop.panel", function() {
return "en-US";
}
};
- document.mozL10n.initialize(window.navigator.mozLoop);
+ document.mozL10n.initialize(navigator.mozLoop);
});
afterEach(function() {
- delete window.navigator.mozLoop;
+ delete navigator.mozLoop;
$("#fixtures").empty();
sandbox.restore();
});
@@ -157,6 +158,51 @@ describe("loop.panel", function() {
});
});
+ describe("loop.panel.DoNotDisturbView", function() {
+ var view;
+
+ beforeEach(function() {
+ $("#fixtures").append('');
+ view = new loop.panel.DoNotDisturbView({el: $("#dnd-view")});
+ });
+
+ describe("#toggle", function() {
+ beforeEach(function() {
+ navigator.mozLoop.doNotDisturb = false;
+ });
+
+ it("should toggle the value of mozLoop.doNotDisturb", function() {
+ view.toggle();
+
+ expect(navigator.mozLoop.doNotDisturb).eql(true);
+ });
+
+ it("should update the DnD checkbox value", function() {
+ view.toggle();
+
+ expect(view.$("input").is(":checked")).eql(true);
+ });
+ });
+
+ describe("render", function() {
+ it("should check the dnd checkbox when dnd is enabled", function() {
+ navigator.mozLoop.doNotDisturb = false;
+
+ view.render();
+
+ expect(view.$("input").is(":checked")).eql(false);
+ });
+
+ it("should uncheck the dnd checkbox when dnd is disabled", function() {
+ navigator.mozLoop.doNotDisturb = true;
+
+ view.render();
+
+ expect(view.$("input").is(":checked")).eql(true);
+ });
+ });
+ });
+
describe("loop.panel.PanelView", function() {
beforeEach(function() {
$("#fixtures").append('');
@@ -265,5 +311,17 @@ describe("loop.panel", function() {
it("should do set the enabled state if there is text");
});
});
+
+ describe("#render", function() {
+ it("should render a DoNotDisturbView", function() {
+ var renderDnD = sandbox.stub(loop.panel.DoNotDisturbView.prototype,
+ "render");
+ var view = new loop.panel.PanelView({notifier: notifier});
+
+ view.render();
+
+ sinon.assert.calledOnce(renderDnD);
+ });
+ });
});
});
diff --git a/browser/components/loop/test/xpcshell/test_loopservice_dnd.js b/browser/components/loop/test/xpcshell/test_loopservice_dnd.js
new file mode 100644
index 000000000000..bd2f426bd05c
--- /dev/null
+++ b/browser/components/loop/test/xpcshell/test_loopservice_dnd.js
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService",
+ "resource:///modules/loop/MozLoopService.jsm");
+
+do_register_cleanup(function() {
+ Services.prefs.clearUserPref("loop.do_not_disturb");
+});
+
+function test_get_do_not_disturb() {
+ Services.prefs.setBoolPref("loop.do_not_disturb", false);
+
+ do_check_false(MozLoopService.doNotDisturb);
+
+ Services.prefs.setBoolPref("loop.do_not_disturb", true);
+
+ do_check_true(MozLoopService.doNotDisturb);
+}
+
+function test_set_do_not_disturb() {
+ Services.prefs.setBoolPref("loop.do_not_disturb", false);
+
+ MozLoopService.doNotDisturb = true;
+
+ do_check_true(Services.prefs.getBoolPref("loop.do_not_disturb"));
+}
+
+function run_test()
+{
+ test_get_do_not_disturb();
+ test_set_do_not_disturb();
+}
diff --git a/browser/components/loop/test/xpcshell/xpcshell.ini b/browser/components/loop/test/xpcshell/xpcshell.ini
index d784e770ad88..96259ea0170c 100644
--- a/browser/components/loop/test/xpcshell/xpcshell.ini
+++ b/browser/components/loop/test/xpcshell/xpcshell.ini
@@ -3,6 +3,7 @@ head = head.js
tail =
firefox-appdir = browser
+[test_loopservice_dnd.js]
[test_loopservice_expiry.js]
[test_loopservice_initialize.js]
[test_loopservice_locales.js]
diff --git a/browser/locales/en-US/chrome/browser/loop/loop.properties b/browser/locales/en-US/chrome/browser/loop/loop.properties
index 4aaf7fbe2858..492f38d4bb0f 100644
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -10,3 +10,4 @@ peer_ended_conversation=Your peer ended the conversation.
stop=Stop
call_has_ended=Your call has ended.
close_window=Close this window
+do_not_disturb=Do not disturb