зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1074686 - Part 3 Revamped view architecture for Desktop Loop rooms. r=Standard8
This commit is contained in:
Родитель
3baff77d36
Коммит
d384c380c8
|
@ -18,7 +18,7 @@ loop.conversation = (function(mozL10n) {
|
|||
|
||||
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
|
||||
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
|
||||
var DesktopRoomControllerView = loop.roomViews.DesktopRoomControllerView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
|
||||
var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
|
||||
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
|
||||
|
@ -584,8 +584,7 @@ loop.conversation = (function(mozL10n) {
|
|||
));
|
||||
}
|
||||
case "room": {
|
||||
return (DesktopRoomControllerView({
|
||||
mozLoop: navigator.mozLoop,
|
||||
return (DesktopRoomConversationView({
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
));
|
||||
|
|
|
@ -18,7 +18,7 @@ loop.conversation = (function(mozL10n) {
|
|||
|
||||
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
|
||||
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
|
||||
var DesktopRoomControllerView = loop.roomViews.DesktopRoomControllerView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
|
||||
var IncomingCallView = React.createClass({
|
||||
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
|
||||
|
@ -584,8 +584,7 @@ loop.conversation = (function(mozL10n) {
|
|||
/>);
|
||||
}
|
||||
case "room": {
|
||||
return (<DesktopRoomControllerView
|
||||
mozLoop={navigator.mozLoop}
|
||||
return (<DesktopRoomConversationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>);
|
||||
|
|
|
@ -41,7 +41,11 @@ loop.roomViews = (function(mozL10n) {
|
|||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
var storeState = this.props.roomStore.getStoreState("activeRoom");
|
||||
return _.extend(storeState, {
|
||||
// Used by the UI showcase.
|
||||
roomState: this.props.roomState || storeState.roomState
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,25 +76,22 @@ loop.roomViews = (function(mozL10n) {
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
React.DOM.div({className: "room-invitation-overlay"},
|
||||
React.DOM.form({onSubmit: this.handleFormSubmit},
|
||||
React.DOM.input({type: "text", ref: "roomName",
|
||||
placeholder: mozL10n.get("rooms_name_this_room_label")})
|
||||
),
|
||||
React.DOM.p(null, mozL10n.get("invite_header_text")),
|
||||
React.DOM.div({className: "btn-group call-action-group"},
|
||||
React.DOM.button({className: "btn btn-info btn-email",
|
||||
onClick: this.handleEmailButtonClick},
|
||||
mozL10n.get("share_button2")
|
||||
),
|
||||
React.DOM.button({className: "btn btn-info btn-copy",
|
||||
onClick: this.handleCopyButtonClick},
|
||||
mozL10n.get("copy_url_button2")
|
||||
)
|
||||
)
|
||||
React.DOM.div({className: "room-invitation-overlay"},
|
||||
React.DOM.form({onSubmit: this.handleFormSubmit},
|
||||
React.DOM.input({type: "text", ref: "roomName",
|
||||
placeholder: mozL10n.get("rooms_name_this_room_label")})
|
||||
),
|
||||
DesktopRoomConversationView({roomStore: this.props.roomStore})
|
||||
React.DOM.p(null, mozL10n.get("invite_header_text")),
|
||||
React.DOM.div({className: "btn-group call-action-group"},
|
||||
React.DOM.button({className: "btn btn-info btn-email",
|
||||
onClick: this.handleEmailButtonClick},
|
||||
mozL10n.get("share_button2")
|
||||
),
|
||||
React.DOM.button({className: "btn btn-info btn-copy",
|
||||
onClick: this.handleCopyButtonClick},
|
||||
mozL10n.get("copy_url_button2")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -100,13 +101,12 @@ loop.roomViews = (function(mozL10n) {
|
|||
* Desktop room conversation view.
|
||||
*/
|
||||
var DesktopRoomConversationView = React.createClass({displayName: 'DesktopRoomConversationView',
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
video: React.PropTypes.object,
|
||||
audio: React.PropTypes.object,
|
||||
displayInvitation: React.PropTypes.bool
|
||||
audio: React.PropTypes.object
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -116,89 +116,61 @@ loop.roomViews = (function(mozL10n) {
|
|||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
React.DOM.div({className: "video-layout-wrapper"},
|
||||
React.DOM.div({className: "conversation room-conversation"},
|
||||
React.DOM.div({className: "media nested"},
|
||||
React.DOM.div({className: "video_wrapper remote_wrapper"},
|
||||
React.DOM.div({className: "video_inner remote"})
|
||||
),
|
||||
React.DOM.div({className: localStreamClasses})
|
||||
),
|
||||
sharedViews.ConversationToolbar({
|
||||
video: this.props.video,
|
||||
audio: this.props.audio,
|
||||
publishStream: noop,
|
||||
hangup: noop})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room controller view.
|
||||
*/
|
||||
var DesktopRoomControllerView = React.createClass({displayName: 'DesktopRoomControllerView',
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
closeWindow: function() {
|
||||
window.close();
|
||||
},
|
||||
|
||||
_renderRoomView: function(roomState) {
|
||||
switch (roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return loop.conversation.GenericFailureView({
|
||||
cancelCall: this.closeWindow}
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.INIT:
|
||||
case ROOM_STATES.GATHER:
|
||||
case ROOM_STATES.READY:
|
||||
case ROOM_STATES.JOINED: {
|
||||
return DesktopRoomInvitationView({
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
);
|
||||
}
|
||||
// XXX needs bug 1074686/1074702
|
||||
case ROOM_STATES.HAS_PARTICIPANTS: {
|
||||
return DesktopRoomConversationView({
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
);
|
||||
}
|
||||
_renderInvitationOverlay: function() {
|
||||
if (this.state.roomState !== ROOM_STATES.HAS_PARTICIPANTS) {
|
||||
return DesktopRoomInvitationView({
|
||||
roomStore: this.props.roomStore,
|
||||
dispatcher: this.props.dispatcher}
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.roomName) {
|
||||
this.setTitle(this.state.roomName);
|
||||
}
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
this._renderRoomView(this.state.roomState)
|
||||
)
|
||||
);
|
||||
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
|
||||
switch(this.state.roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return loop.conversation.GenericFailureView({
|
||||
cancelCall: this.closeWindow}
|
||||
);
|
||||
}
|
||||
default: {
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
this._renderInvitationOverlay(),
|
||||
React.DOM.div({className: "video-layout-wrapper"},
|
||||
React.DOM.div({className: "conversation room-conversation"},
|
||||
React.DOM.div({className: "media nested"},
|
||||
React.DOM.div({className: "video_wrapper remote_wrapper"},
|
||||
React.DOM.div({className: "video_inner remote"})
|
||||
),
|
||||
React.DOM.div({className: localStreamClasses})
|
||||
),
|
||||
sharedViews.ConversationToolbar({
|
||||
video: this.props.video,
|
||||
audio: this.props.audio,
|
||||
publishStream: noop,
|
||||
hangup: noop})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
ActiveRoomStoreMixin: ActiveRoomStoreMixin,
|
||||
DesktopRoomControllerView: DesktopRoomControllerView,
|
||||
DesktopRoomConversationView: DesktopRoomConversationView,
|
||||
DesktopRoomInvitationView: DesktopRoomInvitationView
|
||||
};
|
||||
|
|
|
@ -41,7 +41,11 @@ loop.roomViews = (function(mozL10n) {
|
|||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
var storeState = this.props.roomStore.getStoreState("activeRoom");
|
||||
return _.extend(storeState, {
|
||||
// Used by the UI showcase.
|
||||
roomState: this.props.roomState || storeState.roomState
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,25 +76,22 @@ loop.roomViews = (function(mozL10n) {
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<div className="room-invitation-overlay">
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<input type="text" ref="roomName"
|
||||
placeholder={mozL10n.get("rooms_name_this_room_label")} />
|
||||
</form>
|
||||
<p>{mozL10n.get("invite_header_text")}</p>
|
||||
<div className="btn-group call-action-group">
|
||||
<button className="btn btn-info btn-email"
|
||||
onClick={this.handleEmailButtonClick}>
|
||||
{mozL10n.get("share_button2")}
|
||||
</button>
|
||||
<button className="btn btn-info btn-copy"
|
||||
onClick={this.handleCopyButtonClick}>
|
||||
{mozL10n.get("copy_url_button2")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="room-invitation-overlay">
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<input type="text" ref="roomName"
|
||||
placeholder={mozL10n.get("rooms_name_this_room_label")} />
|
||||
</form>
|
||||
<p>{mozL10n.get("invite_header_text")}</p>
|
||||
<div className="btn-group call-action-group">
|
||||
<button className="btn btn-info btn-email"
|
||||
onClick={this.handleEmailButtonClick}>
|
||||
{mozL10n.get("share_button2")}
|
||||
</button>
|
||||
<button className="btn btn-info btn-copy"
|
||||
onClick={this.handleCopyButtonClick}>
|
||||
{mozL10n.get("copy_url_button2")}
|
||||
</button>
|
||||
</div>
|
||||
<DesktopRoomConversationView roomStore={this.props.roomStore} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -100,13 +101,12 @@ loop.roomViews = (function(mozL10n) {
|
|||
* Desktop room conversation view.
|
||||
*/
|
||||
var DesktopRoomConversationView = React.createClass({
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
video: React.PropTypes.object,
|
||||
audio: React.PropTypes.object,
|
||||
displayInvitation: React.PropTypes.bool
|
||||
audio: React.PropTypes.object
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -116,89 +116,61 @@ loop.roomViews = (function(mozL10n) {
|
|||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<div className="video-layout-wrapper">
|
||||
<div className="conversation room-conversation">
|
||||
<div className="media nested">
|
||||
<div className="video_wrapper remote_wrapper">
|
||||
<div className="video_inner remote"></div>
|
||||
</div>
|
||||
<div className={localStreamClasses}></div>
|
||||
</div>
|
||||
<sharedViews.ConversationToolbar
|
||||
video={this.props.video}
|
||||
audio={this.props.audio}
|
||||
publishStream={noop}
|
||||
hangup={noop} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room controller view.
|
||||
*/
|
||||
var DesktopRoomControllerView = React.createClass({
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
closeWindow: function() {
|
||||
window.close();
|
||||
},
|
||||
|
||||
_renderRoomView: function(roomState) {
|
||||
switch (roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return <loop.conversation.GenericFailureView
|
||||
cancelCall={this.closeWindow}
|
||||
/>;
|
||||
}
|
||||
case ROOM_STATES.INIT:
|
||||
case ROOM_STATES.GATHER:
|
||||
case ROOM_STATES.READY:
|
||||
case ROOM_STATES.JOINED: {
|
||||
return <DesktopRoomInvitationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>;
|
||||
}
|
||||
// XXX needs bug 1074686/1074702
|
||||
case ROOM_STATES.HAS_PARTICIPANTS: {
|
||||
return <DesktopRoomConversationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>;
|
||||
}
|
||||
_renderInvitationOverlay: function() {
|
||||
if (this.state.roomState !== ROOM_STATES.HAS_PARTICIPANTS) {
|
||||
return <DesktopRoomInvitationView
|
||||
roomStore={this.props.roomStore}
|
||||
dispatcher={this.props.dispatcher}
|
||||
/>;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.roomName) {
|
||||
this.setTitle(this.state.roomName);
|
||||
}
|
||||
return (
|
||||
<div className="room-conversation-wrapper">{
|
||||
this._renderRoomView(this.state.roomState)
|
||||
}</div>
|
||||
);
|
||||
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
|
||||
switch(this.state.roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return <loop.conversation.GenericFailureView
|
||||
cancelCall={this.closeWindow}
|
||||
/>;
|
||||
}
|
||||
default: {
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
{this._renderInvitationOverlay()}
|
||||
<div className="video-layout-wrapper">
|
||||
<div className="conversation room-conversation">
|
||||
<div className="media nested">
|
||||
<div className="video_wrapper remote_wrapper">
|
||||
<div className="video_inner remote"></div>
|
||||
</div>
|
||||
<div className={localStreamClasses}></div>
|
||||
</div>
|
||||
<sharedViews.ConversationToolbar
|
||||
video={this.props.video}
|
||||
audio={this.props.audio}
|
||||
publishStream={noop}
|
||||
hangup={noop} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
ActiveRoomStoreMixin: ActiveRoomStoreMixin,
|
||||
DesktopRoomControllerView: DesktopRoomControllerView,
|
||||
DesktopRoomConversationView: DesktopRoomConversationView,
|
||||
DesktopRoomInvitationView: DesktopRoomInvitationView
|
||||
};
|
||||
|
|
|
@ -214,7 +214,7 @@ describe("loop.conversation", function() {
|
|||
ccView = mountTestComponent();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(ccView,
|
||||
loop.roomViews.DesktopRoomControllerView);
|
||||
loop.roomViews.DesktopRoomConversationView);
|
||||
});
|
||||
|
||||
it("should display the GenericFailureView for failures", function() {
|
||||
|
|
|
@ -81,13 +81,13 @@ describe("loop.roomViews", function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe("DesktopRoomControllerView", function() {
|
||||
describe("DesktopRoomConversationView", function() {
|
||||
var view;
|
||||
|
||||
function mountTestComponent() {
|
||||
return TestUtils.renderIntoDocument(
|
||||
new loop.roomViews.DesktopRoomControllerView({
|
||||
mozLoop: {},
|
||||
new loop.roomViews.DesktopRoomConversationView({
|
||||
dispatcher: dispatcher,
|
||||
roomStore: roomStore
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
var DesktopPendingConversationView = loop.conversationViews.PendingConversationView;
|
||||
var CallFailedView = loop.conversationViews.CallFailedView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
var DesktopRoomInvitationView = loop.roomViews.DesktopRoomInvitationView;
|
||||
|
||||
// 2. Standalone webapp
|
||||
var HomeView = loop.webapp.HomeView;
|
||||
|
@ -39,6 +38,9 @@
|
|||
var ConversationView = loop.shared.views.ConversationView;
|
||||
var FeedbackView = loop.shared.views.FeedbackView;
|
||||
|
||||
// Room constants
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
|
||||
// Local helpers
|
||||
function returnTrue() {
|
||||
return true;
|
||||
|
@ -533,20 +535,24 @@
|
|||
)
|
||||
),
|
||||
|
||||
Section({name: "DesktopRoomInvitationView"},
|
||||
Example({summary: "Desktop room invitation", dashed: "true",
|
||||
Section({name: "DesktopRoomConversationView"},
|
||||
Example({summary: "Desktop room conversation (invitation)", dashed: "true",
|
||||
style: {width: "260px", height: "265px"}},
|
||||
React.DOM.div({className: "fx-embedded"},
|
||||
DesktopRoomInvitationView({roomStore: roomStore})
|
||||
DesktopRoomConversationView({
|
||||
roomStore: roomStore,
|
||||
dispatcher: dispatcher,
|
||||
roomState: ROOM_STATES.INIT})
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
|
||||
Section({name: "DesktopRoomConversationView"},
|
||||
Example({summary: "Desktop room conversation", dashed: "true",
|
||||
style: {width: "260px", height: "265px"}},
|
||||
React.DOM.div({className: "fx-embedded"},
|
||||
DesktopRoomConversationView({roomStore: roomStore})
|
||||
DesktopRoomConversationView({
|
||||
roomStore: roomStore,
|
||||
dispatcher: dispatcher,
|
||||
roomState: ROOM_STATES.HAS_PARTICIPANTS})
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
var DesktopPendingConversationView = loop.conversationViews.PendingConversationView;
|
||||
var CallFailedView = loop.conversationViews.CallFailedView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
var DesktopRoomInvitationView = loop.roomViews.DesktopRoomInvitationView;
|
||||
|
||||
// 2. Standalone webapp
|
||||
var HomeView = loop.webapp.HomeView;
|
||||
|
@ -39,6 +38,9 @@
|
|||
var ConversationView = loop.shared.views.ConversationView;
|
||||
var FeedbackView = loop.shared.views.FeedbackView;
|
||||
|
||||
// Room constants
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
|
||||
// Local helpers
|
||||
function returnTrue() {
|
||||
return true;
|
||||
|
@ -533,20 +535,24 @@
|
|||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="DesktopRoomInvitationView">
|
||||
<Example summary="Desktop room invitation" dashed="true"
|
||||
<Section name="DesktopRoomConversationView">
|
||||
<Example summary="Desktop room conversation (invitation)" dashed="true"
|
||||
style={{width: "260px", height: "265px"}}>
|
||||
<div className="fx-embedded">
|
||||
<DesktopRoomInvitationView roomStore={roomStore} />
|
||||
<DesktopRoomConversationView
|
||||
roomStore={roomStore}
|
||||
dispatcher={dispatcher}
|
||||
roomState={ROOM_STATES.INIT} />
|
||||
</div>
|
||||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="DesktopRoomConversationView">
|
||||
<Example summary="Desktop room conversation" dashed="true"
|
||||
style={{width: "260px", height: "265px"}}>
|
||||
<div className="fx-embedded">
|
||||
<DesktopRoomConversationView roomStore={roomStore} />
|
||||
<DesktopRoomConversationView
|
||||
roomStore={roomStore}
|
||||
dispatcher={dispatcher}
|
||||
roomState={ROOM_STATES.HAS_PARTICIPANTS} />
|
||||
</div>
|
||||
</Example>
|
||||
</Section>
|
||||
|
|
Загрузка…
Ссылка в новой задаче