зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1097742 - Part 2 Standalone Rooms shouldn't join the room until after user media has been accepted. r=abr
This commit is contained in:
Родитель
140f453285
Коммит
1d978cc95f
|
@ -162,6 +162,12 @@ loop.shared.actions = (function() {
|
|||
getRemoteElementFunc: Function
|
||||
}),
|
||||
|
||||
/**
|
||||
* Used for notifying that local media has been obtained.
|
||||
*/
|
||||
GotMediaPermission: Action.define("gotMediaPermission", {
|
||||
}),
|
||||
|
||||
/**
|
||||
* Used for notifying that the media is now up for the call.
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,8 @@ loop.store.ActiveRoomStore = (function() {
|
|||
GATHER: "room-gather",
|
||||
// The store has got the room data
|
||||
READY: "room-ready",
|
||||
// Obtaining media from the user
|
||||
MEDIA_WAIT: "room-media-wait",
|
||||
// The room is known to be joined on the loop-server
|
||||
JOINED: "room-joined",
|
||||
// The room is connected to the sdk server.
|
||||
|
@ -127,6 +129,7 @@ loop.store.ActiveRoomStore = (function() {
|
|||
"roomFailure",
|
||||
"setupRoomInfo",
|
||||
"updateRoomInfo",
|
||||
"gotMediaPermission",
|
||||
"joinRoom",
|
||||
"joinedRoom",
|
||||
"connectedToSdkServers",
|
||||
|
@ -260,6 +263,14 @@ loop.store.ActiveRoomStore = (function() {
|
|||
this.setStoreState({failureReason: undefined});
|
||||
}
|
||||
|
||||
this.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles the action that signifies when media permission has been
|
||||
* granted and starts joining the room.
|
||||
*/
|
||||
gotMediaPermission: function() {
|
||||
this._mozLoop.rooms.join(this._storeState.roomToken,
|
||||
function(error, responseData) {
|
||||
if (error) {
|
||||
|
|
|
@ -207,6 +207,9 @@ loop.OTSdkDriver = (function() {
|
|||
_onPublishComplete: function(event) {
|
||||
event.preventDefault();
|
||||
this._publisherReady = true;
|
||||
|
||||
this.dispatcher.dispatch(new sharedActions.GotMediaPermission());
|
||||
|
||||
this._maybePublishLocalStream();
|
||||
},
|
||||
|
||||
|
|
|
@ -68,6 +68,16 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
)
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.MEDIA_WAIT: {
|
||||
var msg = mozL10n.get("call_progress_getting_media_description",
|
||||
{clientShortname: mozL10n.get("clientShortname2")});
|
||||
// XXX Bug 1047040 will add images to help prompt the user.
|
||||
return (
|
||||
React.DOM.p({className: "prompt-media-message"},
|
||||
msg
|
||||
)
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.JOINED:
|
||||
case ROOM_STATES.SESSION_CONNECTED: {
|
||||
return (
|
||||
|
@ -211,7 +221,31 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Used to update the video container whenever the orientation or size of the
|
||||
* display area changes.
|
||||
*/
|
||||
updateVideoContainer: function() {
|
||||
var localStreamParent = this._getElement('.local .OT_publisher');
|
||||
var remoteStreamParent = this._getElement('.remote .OT_subscriber');
|
||||
if (localStreamParent) {
|
||||
localStreamParent.style.width = "100%";
|
||||
}
|
||||
if (remoteStreamParent) {
|
||||
remoteStreamParent.style.height = "100%";
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
/**
|
||||
* OT inserts inline styles into the markup. Using a listener for
|
||||
* resize events helps us trigger a full width/height on the element
|
||||
* so that they update to the correct dimensions.
|
||||
* XXX: this should be factored as a mixin, bug 1104930
|
||||
*/
|
||||
window.addEventListener('orientationchange', this.updateVideoContainer);
|
||||
window.addEventListener('resize', this.updateVideoContainer);
|
||||
|
||||
// Adding a class to the document body element from here to ease styling it.
|
||||
document.body.classList.add("is-standalone-room");
|
||||
},
|
||||
|
@ -228,14 +262,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
* @param {Object} nextState Next state object.
|
||||
*/
|
||||
componentWillUpdate: function(nextProps, nextState) {
|
||||
if (this.state.roomState !== ROOM_STATES.JOINED &&
|
||||
nextState.roomState === ROOM_STATES.JOINED) {
|
||||
if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
|
||||
nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||
publisherConfig: this._getPublisherConfig(),
|
||||
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
||||
getRemoteElementFunc: this._getElement.bind(this, ".remote")
|
||||
}));
|
||||
}
|
||||
|
||||
if (this.state.roomState !== ROOM_STATES.JOINED &&
|
||||
nextState.roomState === ROOM_STATES.JOINED) {
|
||||
// This forces the video size to update - creating the publisher
|
||||
// first, and then connecting to the session doesn't seem to set the
|
||||
// initial size correctly.
|
||||
this.updateVideoContainer();
|
||||
}
|
||||
},
|
||||
|
||||
joinRoom: function() {
|
||||
|
|
|
@ -68,6 +68,16 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
</button>
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.MEDIA_WAIT: {
|
||||
var msg = mozL10n.get("call_progress_getting_media_description",
|
||||
{clientShortname: mozL10n.get("clientShortname2")});
|
||||
// XXX Bug 1047040 will add images to help prompt the user.
|
||||
return (
|
||||
<p className="prompt-media-message">
|
||||
{msg}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.JOINED:
|
||||
case ROOM_STATES.SESSION_CONNECTED: {
|
||||
return (
|
||||
|
@ -211,7 +221,31 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Used to update the video container whenever the orientation or size of the
|
||||
* display area changes.
|
||||
*/
|
||||
updateVideoContainer: function() {
|
||||
var localStreamParent = this._getElement('.local .OT_publisher');
|
||||
var remoteStreamParent = this._getElement('.remote .OT_subscriber');
|
||||
if (localStreamParent) {
|
||||
localStreamParent.style.width = "100%";
|
||||
}
|
||||
if (remoteStreamParent) {
|
||||
remoteStreamParent.style.height = "100%";
|
||||
}
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
/**
|
||||
* OT inserts inline styles into the markup. Using a listener for
|
||||
* resize events helps us trigger a full width/height on the element
|
||||
* so that they update to the correct dimensions.
|
||||
* XXX: this should be factored as a mixin, bug 1104930
|
||||
*/
|
||||
window.addEventListener('orientationchange', this.updateVideoContainer);
|
||||
window.addEventListener('resize', this.updateVideoContainer);
|
||||
|
||||
// Adding a class to the document body element from here to ease styling it.
|
||||
document.body.classList.add("is-standalone-room");
|
||||
},
|
||||
|
@ -228,14 +262,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
* @param {Object} nextState Next state object.
|
||||
*/
|
||||
componentWillUpdate: function(nextProps, nextState) {
|
||||
if (this.state.roomState !== ROOM_STATES.JOINED &&
|
||||
nextState.roomState === ROOM_STATES.JOINED) {
|
||||
if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
|
||||
nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||
publisherConfig: this._getPublisherConfig(),
|
||||
getLocalElementFunc: this._getElement.bind(this, ".local"),
|
||||
getRemoteElementFunc: this._getElement.bind(this, ".remote")
|
||||
}));
|
||||
}
|
||||
|
||||
if (this.state.roomState !== ROOM_STATES.JOINED &&
|
||||
nextState.roomState === ROOM_STATES.JOINED) {
|
||||
// This forces the video size to update - creating the publisher
|
||||
// first, and then connecting to the session doesn't seem to set the
|
||||
// initial size correctly.
|
||||
this.updateVideoContainer();
|
||||
}
|
||||
},
|
||||
|
||||
joinRoom: function() {
|
||||
|
|
|
@ -284,10 +284,6 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
});
|
||||
|
||||
describe("#joinRoom", function() {
|
||||
beforeEach(function() {
|
||||
store.setStoreState({roomToken: "tokenFake"});
|
||||
});
|
||||
|
||||
it("should reset failureReason", function() {
|
||||
store.setStoreState({failureReason: "Test"});
|
||||
|
||||
|
@ -296,9 +292,23 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
expect(store.getStoreState().failureReason).eql(undefined);
|
||||
});
|
||||
|
||||
it("should call rooms.join on mozLoop", function() {
|
||||
it("should set the state to MEDIA_WAIT", function() {
|
||||
store.setStoreState({roomState: ROOM_STATES.READY});
|
||||
|
||||
store.joinRoom();
|
||||
|
||||
expect(store.getStoreState().roomState).eql(ROOM_STATES.MEDIA_WAIT);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#gotMediaPermission", function() {
|
||||
beforeEach(function() {
|
||||
store.setStoreState({roomToken: "tokenFake"});
|
||||
});
|
||||
|
||||
it("should call rooms.join on mozLoop", function() {
|
||||
store.gotMediaPermission();
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.rooms.join);
|
||||
sinon.assert.calledWith(fakeMozLoop.rooms.join, "tokenFake");
|
||||
});
|
||||
|
@ -313,7 +323,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
|
||||
fakeMozLoop.rooms.join.callsArgWith(1, null, responseData);
|
||||
|
||||
store.joinRoom();
|
||||
store.gotMediaPermission();
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWith(dispatcher.dispatch,
|
||||
|
@ -325,7 +335,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
|
||||
fakeMozLoop.rooms.join.callsArgWith(1, fakeError);
|
||||
|
||||
store.joinRoom();
|
||||
store.gotMediaPermission();
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWith(dispatcher.dispatch,
|
||||
|
|
|
@ -295,6 +295,14 @@ describe("loop.OTSdkDriver", function () {
|
|||
|
||||
sinon.assert.calledOnce(session.publish);
|
||||
});
|
||||
|
||||
it("should dispatch a GotMediaPermission action", function() {
|
||||
publisher.trigger("accessAllowed", fakeEvent);
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.GotMediaPermission());
|
||||
});
|
||||
});
|
||||
|
||||
describe("accessDenied", function() {
|
||||
|
|
|
@ -53,27 +53,49 @@ describe("loop.standaloneRoomViews", function() {
|
|||
}
|
||||
|
||||
describe("#componentWillUpdate", function() {
|
||||
it("should dispatch a `SetupStreamElements` action on room joined",
|
||||
function() {
|
||||
it("should dispatch a `SetupStreamElements` action when the MEDIA_WAIT state " +
|
||||
"is entered", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
|
||||
var view = mountTestComponent();
|
||||
|
||||
sinon.assert.notCalled(dispatch);
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.JOINED});
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
|
||||
|
||||
expectActionDispatched(view);
|
||||
});
|
||||
|
||||
it("should dispatch a `SetupStreamElements` action on room rejoined",
|
||||
function() {
|
||||
it("should dispatch a `SetupStreamElements` action on MEDIA_WAIT state is " +
|
||||
"re-entered", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.ENDED});
|
||||
var view = mountTestComponent();
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.JOINED});
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
|
||||
|
||||
expectActionDispatched(view);
|
||||
});
|
||||
|
||||
it("should updateVideoContainer when the JOINED state is entered", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
|
||||
|
||||
var view = mountTestComponent();
|
||||
|
||||
sandbox.stub(view, "updateVideoContainer");
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.JOINED});
|
||||
|
||||
sinon.assert.calledOnce(view.updateVideoContainer);
|
||||
});
|
||||
|
||||
it("should updateVideoContainer when the JOINED state is re-entered", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.ENDED});
|
||||
|
||||
var view = mountTestComponent();
|
||||
|
||||
sandbox.stub(view, "updateVideoContainer");
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.JOINED});
|
||||
|
||||
sinon.assert.calledOnce(view.updateVideoContainer);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#publishStream", function() {
|
||||
|
@ -143,6 +165,16 @@ describe("loop.standaloneRoomViews", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Prompt media message", function() {
|
||||
it("should display a prompt for user media on MEDIA_WAIT",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".prompt-media-message"))
|
||||
.not.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Full room message", function() {
|
||||
it("should display a full room message on FULL",
|
||||
function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче