Bug 1171940: move the context display into the chat area inside the Hello conversation window. r=Standard8

This commit is contained in:
Mike de Boer 2015-07-03 19:00:22 +02:00
parent 6c168f83cd
commit 06878cbdf4
11 changed files with 84 additions and 63 deletions

View File

@ -808,7 +808,8 @@ loop.roomViews = (function(mozL10n) {
React.createElement(sharedViews.chat.TextChatView, {
dispatcher: this.props.dispatcher,
showAlways: false,
showRoomName: false})
showRoomName: false,
useDesktopPaths: true})
)
);
}

View File

@ -808,7 +808,8 @@ loop.roomViews = (function(mozL10n) {
<sharedViews.chat.TextChatView
dispatcher={this.props.dispatcher}
showAlways={false}
showRoomName={false} />
showRoomName={false}
useDesktopPaths={true} />
</div>
);
}

View File

@ -100,12 +100,29 @@ loop.store.TextChatStore = (function() {
sentTimestamp: messageData.sentTimestamp,
receivedTimestamp: messageData.receivedTimestamp
};
var newList = this._storeState.messageList.concat(message);
var newList = [].concat(this._storeState.messageList);
var isContext = message.contentType === CHAT_CONTENT_TYPES.CONTEXT;
if (isContext) {
var contextUpdated = false;
for (var i = 0, l = newList.length; i < l; ++i) {
// Replace the current context message with the provided update.
if (newList[i].contentType === CHAT_CONTENT_TYPES.CONTEXT) {
newList[i] = message;
contextUpdated = true;
break;
}
}
if (!contextUpdated) {
newList.push(message);
}
} else {
newList.push(message);
}
this.setStoreState({ messageList: newList });
// Notify MozLoopService if appropriate that a message has been appended
// and it should therefore check if we need a different sized window or not.
if (type != CHAT_MESSAGE_TYPES.SPECIAL) {
if (message.contentType != CHAT_CONTENT_TYPES.ROOM_NAME) {
window.dispatchEvent(new CustomEvent("LoopChatMessageAppended"));
}
},

View File

@ -68,7 +68,8 @@ loop.shared.views.chat = (function(mozL10n) {
mixins: [React.addons.PureRenderMixin],
propTypes: {
message: React.PropTypes.string.isRequired
message: React.PropTypes.string.isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
render: function() {
@ -97,7 +98,8 @@ loop.shared.views.chat = (function(mozL10n) {
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
messageList: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
messageList: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
getInitialState: function() {
@ -157,7 +159,12 @@ loop.shared.views.chat = (function(mozL10n) {
if (entry.type === CHAT_MESSAGE_TYPES.SPECIAL) {
switch (entry.contentType) {
case CHAT_CONTENT_TYPES.ROOM_NAME:
return React.createElement(TextChatRoomName, {key: i, message: entry.message});
return (
React.createElement(TextChatRoomName, {
key: i,
message: entry.message,
useDesktopPaths: this.props.useDesktopPaths})
);
case CHAT_CONTENT_TYPES.CONTEXT:
return (
React.createElement("div", {className: "context-url-view-wrapper", key: i},
@ -168,7 +175,7 @@ loop.shared.views.chat = (function(mozL10n) {
showContextTitle: true,
thumbnail: entry.extraData.thumbnail,
url: entry.extraData.location,
useDesktopPaths: false})
useDesktopPaths: this.props.useDesktopPaths})
)
);
default:
@ -334,11 +341,8 @@ loop.shared.views.chat = (function(mozL10n) {
* as a field for entering new messages.
*
* @property {loop.Dispatcher} dispatcher
* @property {Boolean} showAlways If false, the view will not be rendered
* if text chat is not enabled and the
* message list is empty.
* @property {Boolean} showRoomName Set to true to show the room name special
* list item.
* @property {Boolean} showRoomName Set to true to show the room name
* special list item.
*/
var TextChatView = React.createClass({displayName: "TextChatView",
mixins: [
@ -348,8 +352,8 @@ loop.shared.views.chat = (function(mozL10n) {
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
showAlways: React.PropTypes.bool.isRequired,
showRoomName: React.PropTypes.bool.isRequired
showRoomName: React.PropTypes.bool.isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
getInitialState: function() {
@ -366,14 +370,14 @@ loop.shared.views.chat = (function(mozL10n) {
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL;
});
} else {
// XXX Desktop should be showing the initial context here (bug 1171940).
messageList = this.state.messageList.filter(function(item) {
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL;
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL ||
item.contentType !== CHAT_CONTENT_TYPES.ROOM_NAME;
});
hasNonSpecialMessages = !!messageList.length;
}
if (!this.props.showAlways && !this.state.textChatEnabled && !messageList.length) {
if (!this.state.textChatEnabled && !messageList.length) {
return null;
}
@ -386,7 +390,8 @@ loop.shared.views.chat = (function(mozL10n) {
React.createElement("div", {className: textChatViewClasses},
React.createElement(TextChatEntriesView, {
dispatcher: this.props.dispatcher,
messageList: messageList}),
messageList: messageList,
useDesktopPaths: this.props.useDesktopPaths}),
React.createElement(TextChatInputView, {
dispatcher: this.props.dispatcher,
showPlaceholder: !hasNonSpecialMessages,

View File

@ -68,7 +68,8 @@ loop.shared.views.chat = (function(mozL10n) {
mixins: [React.addons.PureRenderMixin],
propTypes: {
message: React.PropTypes.string.isRequired
message: React.PropTypes.string.isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
render: function() {
@ -97,7 +98,8 @@ loop.shared.views.chat = (function(mozL10n) {
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
messageList: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
messageList: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
getInitialState: function() {
@ -157,7 +159,12 @@ loop.shared.views.chat = (function(mozL10n) {
if (entry.type === CHAT_MESSAGE_TYPES.SPECIAL) {
switch (entry.contentType) {
case CHAT_CONTENT_TYPES.ROOM_NAME:
return <TextChatRoomName key={i} message={entry.message}/>;
return (
<TextChatRoomName
key={i}
message={entry.message}
useDesktopPaths={this.props.useDesktopPaths} />
);
case CHAT_CONTENT_TYPES.CONTEXT:
return (
<div className="context-url-view-wrapper" key={i}>
@ -168,7 +175,7 @@ loop.shared.views.chat = (function(mozL10n) {
showContextTitle={true}
thumbnail={entry.extraData.thumbnail}
url={entry.extraData.location}
useDesktopPaths={false} />
useDesktopPaths={this.props.useDesktopPaths} />
</div>
);
default:
@ -334,11 +341,8 @@ loop.shared.views.chat = (function(mozL10n) {
* as a field for entering new messages.
*
* @property {loop.Dispatcher} dispatcher
* @property {Boolean} showAlways If false, the view will not be rendered
* if text chat is not enabled and the
* message list is empty.
* @property {Boolean} showRoomName Set to true to show the room name special
* list item.
* @property {Boolean} showRoomName Set to true to show the room name
* special list item.
*/
var TextChatView = React.createClass({
mixins: [
@ -348,8 +352,8 @@ loop.shared.views.chat = (function(mozL10n) {
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
showAlways: React.PropTypes.bool.isRequired,
showRoomName: React.PropTypes.bool.isRequired
showRoomName: React.PropTypes.bool.isRequired,
useDesktopPaths: React.PropTypes.bool.isRequired
},
getInitialState: function() {
@ -366,14 +370,14 @@ loop.shared.views.chat = (function(mozL10n) {
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL;
});
} else {
// XXX Desktop should be showing the initial context here (bug 1171940).
messageList = this.state.messageList.filter(function(item) {
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL;
return item.type !== CHAT_MESSAGE_TYPES.SPECIAL ||
item.contentType !== CHAT_CONTENT_TYPES.ROOM_NAME;
});
hasNonSpecialMessages = !!messageList.length;
}
if (!this.props.showAlways && !this.state.textChatEnabled && !messageList.length) {
if (!this.state.textChatEnabled && !messageList.length) {
return null;
}
@ -386,7 +390,8 @@ loop.shared.views.chat = (function(mozL10n) {
<div className={textChatViewClasses}>
<TextChatEntriesView
dispatcher={this.props.dispatcher}
messageList={messageList} />
messageList={messageList}
useDesktopPaths={this.props.useDesktopPaths} />
<TextChatInputView
dispatcher={this.props.dispatcher}
showPlaceholder={!hasNonSpecialMessages}

View File

@ -890,7 +890,10 @@ let MozLoopServiceInternal = {
// When the chat box or messages are shown, resize the panel or window
// to be slightly higher to accomodate them.
let customSize = kSizeMap[ev.type];
if (customSize) {
let currSize = chatbox.getAttribute("customSize");
// If the size is already at the requested one or at the maximum size
// already, don't do anything. Especially don't make it shrink.
if (customSize && currSize != customSize && currSize != "loopChatMessageAppended") {
chatbox.setAttribute("customSize", customSize);
chatbox.parentNode.setAttribute("customSize", customSize);
}

View File

@ -464,7 +464,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
React.createElement(sharedViews.chat.TextChatView, {
dispatcher: this.props.dispatcher,
showAlways: true,
showRoomName: true}),
showRoomName: true,
useDesktopPaths: false}),
React.createElement("div", {className: "local"},
React.createElement(sharedViews.MediaView, {displayAvatar: this.state.videoMuted,
isLoading: this._shouldRenderLocalLoading(),

View File

@ -464,7 +464,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
<sharedViews.chat.TextChatView
dispatcher={this.props.dispatcher}
showAlways={true}
showRoomName={true} />
showRoomName={true}
useDesktopPaths={false} />
<div className="local">
<sharedViews.MediaView displayAvatar={this.state.videoMuted}
isLoading={this._shouldRenderLocalLoading()}

View File

@ -249,7 +249,8 @@ describe("loop.shared.views.TextChatView", function () {
function mountTestComponent(extraProps) {
var props = _.extend({
dispatcher: dispatcher
dispatcher: dispatcher,
useDesktopPaths: false
}, extraProps);
return TestUtils.renderIntoDocument(
React.createElement(loop.shared.views.chat.TextChatView, props));
@ -288,30 +289,16 @@ describe("loop.shared.views.TextChatView", function () {
.to.eql(2);
});
it("should not display anything if no messages and text chat not enabled and showAlways is false", function() {
it("should display the view if no messages and text chat not enabled", function() {
store.setStoreState({ textChatEnabled: false });
view = mountTestComponent({
showAlways: false
});
expect(view.getDOMNode()).eql(null);
});
it("should display the view if no messages and text chat not enabled and showAlways is true", function() {
store.setStoreState({ textChatEnabled: false });
view = mountTestComponent({
showAlways: true
});
view = mountTestComponent();
expect(view.getDOMNode()).not.eql(null);
});
it("should display the view if text chat is enabled", function() {
view = mountTestComponent({
showAlways: true
});
view = mountTestComponent();
expect(view.getDOMNode()).not.eql(null);
});

View File

@ -1243,8 +1243,8 @@
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(TextChatView, {dispatcher: dispatcher,
showAlways: false,
showRoomName: false})
showRoomName: false,
useDesktopPaths: false})
)
),
@ -1257,8 +1257,8 @@
React.createElement("div", {className: "media-wrapper"},
React.createElement(TextChatView, {
dispatcher: dispatcher,
showAlways: true,
showRoomName: true})
showRoomName: true,
useDesktopPaths: false})
)
)
)

View File

@ -1243,8 +1243,8 @@
width={298}>
<div className="fx-embedded">
<TextChatView dispatcher={dispatcher}
showAlways={false}
showRoomName={false} />
showRoomName={false}
useDesktopPaths={false} />
</div>
</FramedExample>
@ -1257,8 +1257,8 @@
<div className="media-wrapper">
<TextChatView
dispatcher={dispatcher}
showAlways={true}
showRoomName={true} />
showRoomName={true}
useDesktopPaths={false} />
</div>
</div>
</FramedExample>