Bug 1074666 - Part 3 Play a sound when a participant joined a room. Updated by pkerr,r=Standard8

This commit is contained in:
Mike de Boer 2014-11-17 13:28:59 +00:00
parent f40716ae6e
commit 2e498385b8
8 changed files with 97 additions and 7 deletions

View File

@ -11,7 +11,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
(function() {
LoopUI = {
get toolbarButton() {
delete this.toolbarButton;
@ -89,5 +88,23 @@ XPCOMUtils.defineLazyModuleGetter(this, "PanelFrame", "resource:///modules/Panel
}
this.toolbarButton.node.setAttribute("state", state);
},
/**
* Play a sound in this window IF there's no sound playing yet.
*
* @param {String} name Name of the sound, like 'ringtone' or 'room-joined'
*/
playSound: function(name) {
if (this.ActiveSound || MozLoopService.doNotDisturb) {
return;
}
this.activeSound = new window.Audio();
this.activeSound.src = `chrome://browser/content/loop/shared/sounds/${name}.ogg`;
this.activeSound.load();
this.activeSound.play();
this.activeSound.addEventListener("ended", () => this.activeSound = undefined, false);
},
};
})();

View File

@ -56,7 +56,11 @@ const extend = function(target, source) {
*/
const containsParticipant = function(room, participant) {
for (let user of room.participants) {
if (user.roomConnectionId == participant.roomConnectionId) {
// XXX until a bug 1100318 is implemented and deployed,
// we need to check the "id" field here as well - roomConnectionId is the
// official value for the interface.
if (user.roomConnectionId == participant.roomConnectionId &&
user.id == participant.id) {
return true;
}
}
@ -175,6 +179,10 @@ let LoopRoomsInternal = {
if (orig) {
checkForParticipantsUpdate(orig, room);
}
// Remove the `currSize` for posterity.
if ("currSize" in room) {
delete room.currSize;
}
this.rooms.set(room.roomToken, room);
// When a version is specified, all the data is already provided by this
// request.
@ -224,11 +232,6 @@ let LoopRoomsInternal = {
room.roomToken = roomToken;
checkForParticipantsUpdate(room, data);
extend(room, data);
// Remove the `currSize` for posterity.
if ("currSize" in room) {
delete room.currSize;
}
this.rooms.set(roomToken, room);
let eventName = !needsUpdate ? "update" : "add";

View File

@ -81,6 +81,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
"@mozilla.org/network/dns-service;1",
"nsIDNSService");
XPCOMUtils.defineLazyServiceGetter(this, "gWM",
"@mozilla.org/appshell/window-mediator;1",
"nsIWindowMediator");
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
XPCOMUtils.defineLazyGetter(this, "log", () => {
let ConsoleAPI = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).ConsoleAPI;
@ -1006,6 +1010,18 @@ this.MozLoopService = {
};
LoopRooms.on("add", onRoomsChange);
LoopRooms.on("update", onRoomsChange);
LoopRooms.on("joined", (e, roomToken, participant) => {
// Don't alert if we're in the doNotDisturb mode, or the participant
// is the owner - the content code deals with the rest of the sounds.
if (MozLoopServiceInternal.doNotDisturb || participant.owner) {
return;
}
let window = gWM.getMostRecentWindow("navigator:browser");
if (window) {
window.LoopUI.playSound("room-joined");
}
});
// If expiresTime is not in the future and the user hasn't
// previously authenticated then skip registration.

View File

@ -154,6 +154,10 @@ loop.shared.mixins = (function() {
* @param {String} name The filename to play (excluding the extension).
*/
play: function(name, options) {
if (this._isLoopDesktop() && rootObject.navigator.mozLoop.doNotDisturb) {
return;
}
options = options || {};
options.loop = options.loop || false;

View File

@ -86,6 +86,7 @@ browser.jar:
content/browser/loop/shared/sounds/connecting.ogg (content/shared/sounds/connecting.ogg)
content/browser/loop/shared/sounds/connected.ogg (content/shared/sounds/connected.ogg)
content/browser/loop/shared/sounds/terminated.ogg (content/shared/sounds/terminated.ogg)
content/browser/loop/shared/sounds/room-joined.ogg (content/shared/sounds/room-joined.ogg)
content/browser/loop/shared/sounds/failure.ogg (content/shared/sounds/failure.ogg)
# Partner SDK assets

View File

@ -917,6 +917,7 @@ describe("loop.conversation", function() {
pause: sinon.spy(),
removeAttribute: sinon.spy()
};
navigator.mozLoop.doNotDisturb = false;
sandbox.stub(window, "Audio").returns(fakeAudio);
view = TestUtils.renderIntoDocument(

View File

@ -166,4 +166,52 @@ describe("loop.shared.mixins", function() {
sinon.assert.calledOnce(onDocumentHiddenStub);
});
});
describe("loop.shared.mixins.AudioMixin", function() {
var view, fakeAudio, TestComp;
beforeEach(function() {
navigator.mozLoop = {
doNotDisturb: true,
getAudioBlob: sinon.spy(function(name, callback) {
callback(null, new Blob([new ArrayBuffer(10)], {type: 'audio/ogg'}));
})
};
fakeAudio = {
play: sinon.spy(),
pause: sinon.spy(),
removeAttribute: sinon.spy()
};
sandbox.stub(window, "Audio").returns(fakeAudio);
TestComp = React.createClass({
mixins: [loop.shared.mixins.AudioMixin],
componentDidMount: function() {
this.play("failure");
},
render: function() {
return React.DOM.div();
}
});
});
it("should not play a failure sound when doNotDisturb true", function() {
view = TestUtils.renderIntoDocument(TestComp());
sinon.assert.notCalled(navigator.mozLoop.getAudioBlob);
sinon.assert.notCalled(fakeAudio.play);
});
it("should play a failure sound, once", function() {
navigator.mozLoop.doNotDisturb = false;
view = TestUtils.renderIntoDocument(TestComp());
sinon.assert.calledOnce(navigator.mozLoop.getAudioBlob);
sinon.assert.calledWithExactly(navigator.mozLoop.getAudioBlob,
"failure", sinon.match.func);
sinon.assert.calledOnce(fakeAudio.play);
expect(fakeAudio.loop).to.equal(false);
});
});
});