зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1209078
- Part 2. If a user attempts to open their own room within Firefox when the room is already open, provide a message to inform the user. r=mikedeboer
This commit is contained in:
Родитель
218567ce2a
Коммит
85a8eff79d
|
@ -623,12 +623,18 @@ loop.store.ActiveRoomStore = (function() {
|
|||
// previously. We should add better user feedback here.
|
||||
console.error("Firefox didn't handle room it said it could.");
|
||||
} else {
|
||||
this.dispatcher.dispatch(new sharedActions.JoinedRoom({
|
||||
apiKey: "",
|
||||
sessionToken: "",
|
||||
sessionId: "",
|
||||
expires: 0
|
||||
}));
|
||||
if (e.detail.message.alreadyOpen) {
|
||||
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
|
||||
reason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
|
||||
}));
|
||||
} else {
|
||||
this.dispatcher.dispatch(new sharedActions.JoinedRoom({
|
||||
apiKey: "",
|
||||
sessionToken: "",
|
||||
sessionId: "",
|
||||
expires: 0
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1064,6 +1070,15 @@ loop.store.ActiveRoomStore = (function() {
|
|||
* will skip the leave message.
|
||||
*/
|
||||
_leaveRoom: function(nextState, failedJoinRequest) {
|
||||
if (this._storeState.standalone && this._storeState.userAgentHandlesRoom) {
|
||||
// If the user agent is handling the room, all we need to do is advance
|
||||
// to the next state.
|
||||
this.setStoreState({
|
||||
roomState: nextState
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (loop.standaloneMedia) {
|
||||
loop.standaloneMedia.multiplexGum.reset();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
|
|||
var FAILURE_DETAILS = {
|
||||
MEDIA_DENIED: "reason-media-denied",
|
||||
NO_MEDIA: "reason-no-media",
|
||||
ROOM_ALREADY_OPEN: "reason-room-already-open",
|
||||
UNABLE_TO_PUBLISH_MEDIA: "unable-to-publish-media",
|
||||
USER_UNAVAILABLE: "reason-user-unavailable",
|
||||
COULD_NOT_CONNECT: "reason-could-not-connect",
|
||||
|
|
|
@ -184,6 +184,14 @@ html[dir="rtl"] .rooms-footer .footer-logo {
|
|||
margin: 2rem auto;
|
||||
}
|
||||
|
||||
.handle-user-agent-view > .info-panel > .failure {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
/* Add padding to match the height of the button. */
|
||||
padding: 1.15rem 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.handle-user-agent-view > .info-panel > button {
|
||||
width: 80%;
|
||||
height: 4rem;
|
||||
|
|
|
@ -125,12 +125,19 @@ loop.store.StandaloneMetricsStore = (function() {
|
|||
* @param {sharedActions.ConnectionFailure} actionData
|
||||
*/
|
||||
connectionFailure: function(actionData) {
|
||||
if (actionData.reason === FAILURE_DETAILS.MEDIA_DENIED) {
|
||||
this._storeEvent(METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"Media denied");
|
||||
} else if (actionData.reason === FAILURE_DETAILS.NO_MEDIA) {
|
||||
this._storeEvent(METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"No media");
|
||||
switch(actionData.reason) {
|
||||
case FAILURE_DETAILS.MEDIA_DENIED:
|
||||
this._storeEvent(METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"Media denied");
|
||||
break;
|
||||
case FAILURE_DETAILS.NO_MEDIA:
|
||||
this._storeEvent(METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"No media");
|
||||
break;
|
||||
case FAILURE_DETAILS.ROOM_ALREADY_OPEN:
|
||||
this._storeEvent(METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"Room already open");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
this.props.dispatcher.dispatch(new sharedActions.JoinRoom());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
_renderJoinButton: function() {
|
||||
var buttonMessage = this.state.roomState === ROOM_STATES.JOINED ?
|
||||
mozL10n.get("rooms_room_joined_own_conversation_label") :
|
||||
mozL10n.get("rooms_room_join_label");
|
||||
|
@ -86,6 +86,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
disabled: this.state.roomState === ROOM_STATES.JOINED
|
||||
});
|
||||
|
||||
return (
|
||||
React.createElement("button", {
|
||||
className: buttonClasses,
|
||||
onClick: this.handleJoinButton},
|
||||
buttonMessage
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
_renderFailureText: function() {
|
||||
return (
|
||||
React.createElement("p", {className: "failure"}, mozL10n.get("rooms_already_joined") )
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// The extra scroller div here is for providing a scroll view for shorter
|
||||
// screens, as the common.css specifies overflow:hidden for the body which
|
||||
// we need in some places.
|
||||
|
@ -96,11 +112,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
React.createElement("p", {className: "loop-logo-text", title: mozL10n.get("clientShortname2") }),
|
||||
React.createElement("p", {className: "roomName"}, this.state.roomName),
|
||||
React.createElement("p", {className: "loop-logo"}),
|
||||
React.createElement("button", {
|
||||
className: buttonClasses,
|
||||
onClick: this.handleJoinButton},
|
||||
buttonMessage
|
||||
)
|
||||
|
||||
this.state.failureReason ?
|
||||
this._renderFailureText() :
|
||||
this._renderJoinButton()
|
||||
|
||||
),
|
||||
React.createElement(ToSView, {
|
||||
dispatcher: this.props.dispatcher}),
|
||||
|
|
|
@ -75,7 +75,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
this.props.dispatcher.dispatch(new sharedActions.JoinRoom());
|
||||
},
|
||||
|
||||
render: function() {
|
||||
_renderJoinButton: function() {
|
||||
var buttonMessage = this.state.roomState === ROOM_STATES.JOINED ?
|
||||
mozL10n.get("rooms_room_joined_own_conversation_label") :
|
||||
mozL10n.get("rooms_room_join_label");
|
||||
|
@ -86,6 +86,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
disabled: this.state.roomState === ROOM_STATES.JOINED
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
className={buttonClasses}
|
||||
onClick={this.handleJoinButton}>
|
||||
{buttonMessage}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
|
||||
_renderFailureText: function() {
|
||||
return (
|
||||
<p className="failure">{ mozL10n.get("rooms_already_joined") }</p>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// The extra scroller div here is for providing a scroll view for shorter
|
||||
// screens, as the common.css specifies overflow:hidden for the body which
|
||||
// we need in some places.
|
||||
|
@ -96,11 +112,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
<p className="loop-logo-text" title={ mozL10n.get("clientShortname2") }></p>
|
||||
<p className="roomName">{ this.state.roomName }</p>
|
||||
<p className="loop-logo" />
|
||||
<button
|
||||
className={buttonClasses}
|
||||
onClick={this.handleJoinButton}>
|
||||
{buttonMessage}
|
||||
</button>
|
||||
{
|
||||
this.state.failureReason ?
|
||||
this._renderFailureText() :
|
||||
this._renderJoinButton()
|
||||
}
|
||||
</div>
|
||||
<ToSView
|
||||
dispatcher={this.props.dispatcher} />
|
||||
|
|
|
@ -69,6 +69,7 @@ rooms_room_full_call_to_action_label=Learn more about {{clientShortname}} »
|
|||
rooms_room_joined_label=Someone has joined the conversation!
|
||||
rooms_room_join_label=Join the conversation
|
||||
rooms_room_joined_own_conversation_label=Enjoy your conversation
|
||||
rooms_already_joined=You're already in this conversation.
|
||||
rooms_display_name_guest=Guest
|
||||
rooms_unavailable_notification_message=Sorry, you cannot join this conversation. The link may be expired or invalid.
|
||||
rooms_media_denied_message=We could not get access to your microphone or camera. Please reload the page to try again.
|
||||
|
|
|
@ -873,7 +873,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Firefox Handles Room", function() {
|
||||
describe("User Agent Handles Room", function() {
|
||||
var channelListener;
|
||||
|
||||
beforeEach(function() {
|
||||
|
@ -951,7 +951,8 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
detail: {
|
||||
id: "loop-link-clicker",
|
||||
message: {
|
||||
response: true
|
||||
response: true,
|
||||
alreadyOpen: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -965,6 +966,28 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
expires: 0
|
||||
}));
|
||||
});
|
||||
|
||||
it("should dispatch a ConnectionFailure action if the room was already opened", function() {
|
||||
// Start the join.
|
||||
store.joinRoom();
|
||||
|
||||
// Pretend Firefox calls back.
|
||||
channelListener({
|
||||
detail: {
|
||||
id: "loop-link-clicker",
|
||||
message: {
|
||||
response: true,
|
||||
alreadyOpen: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sinon.assert.called(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.ConnectionFailure({
|
||||
reason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1257,6 +1280,29 @@ describe("loop.store.ActiveRoomStore", function () {
|
|||
|
||||
expect(store.getStoreState().roomState).eql(ROOM_STATES.FAILED);
|
||||
});
|
||||
|
||||
it("should set the state to `FAILED` if the user agent is handling the room", function() {
|
||||
store.setStoreState({
|
||||
standalone: true,
|
||||
userAgentHandlesRoom: true
|
||||
});
|
||||
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
expect(store.getStoreState().roomState).eql(ROOM_STATES.FAILED);
|
||||
});
|
||||
|
||||
it("should not do any other cleanup if the user agent is handling the room", function() {
|
||||
store.setStoreState({
|
||||
standalone: true,
|
||||
userAgentHandlesRoom: true
|
||||
});
|
||||
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
sinon.assert.notCalled(fakeMultiplexGum.reset);
|
||||
sinon.assert.notCalled(fakeSdkDriver.disconnectSession);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setMute", function() {
|
||||
|
|
|
@ -77,6 +77,17 @@ describe("loop.store.StandaloneMetricsStore", function() {
|
|||
"No media");
|
||||
});
|
||||
|
||||
it("should log an event on connection failure if the room was already open", function() {
|
||||
store.connectionFailure(new sharedActions.ConnectionFailure({
|
||||
reason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(window.ga);
|
||||
sinon.assert.calledWithExactly(window.ga,
|
||||
"send", "event", METRICS_GA_CATEGORY.general, METRICS_GA_ACTIONS.failed,
|
||||
"Room already open");
|
||||
});
|
||||
|
||||
it("should log an event on GotMediaPermission", function() {
|
||||
store.gotMediaPermission();
|
||||
|
||||
|
|
|
@ -183,6 +183,28 @@ describe("loop.standaloneRoomViews", function() {
|
|||
|
||||
expect(button.classList.contains("disabled")).eql(true);
|
||||
});
|
||||
|
||||
it("should not display a join button if there is a failure reason", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
var button = view.getDOMNode().querySelector(".info-panel > button");
|
||||
|
||||
expect(button).eql(null);
|
||||
});
|
||||
|
||||
it("should display a room already joined message if opening failed", function() {
|
||||
activeRoomStore.setStoreState({
|
||||
failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
|
||||
});
|
||||
|
||||
view = mountTestComponent();
|
||||
var text = view.getDOMNode().querySelector(".failure");
|
||||
|
||||
expect(text.textContent).eql("rooms_already_joined");
|
||||
});
|
||||
});
|
||||
|
||||
describe("StandaloneRoomHeader", function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче