mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1213851 - Display only active room when user enters room [r=Mardak]
This commit is contained in:
parent
2325f694ea
commit
b8555d522b
@ -254,15 +254,13 @@ body {
|
||||
/* See .room-entry-context-item for the margin/size reductions.
|
||||
* An extra 40px to make space for the call button and chevron. */
|
||||
width: calc(100% - 1rem - 56px);
|
||||
|
||||
}
|
||||
|
||||
.room-list > .room-entry.room-active > h2 {
|
||||
.room-list > .room-entry.room-active:not(.room-opened) > h2 {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.room-list > .room-entry:hover {
|
||||
.room-list > .room-entry:not(.room-opened):hover {
|
||||
background: #dbf7ff;
|
||||
}
|
||||
|
||||
@ -417,7 +415,7 @@ html[dir="rtl"] .room-entry-context-actions > .dropdown-menu {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.room-entry:hover .room-entry-context-item {
|
||||
.room-entry:not(.room-opened):hover .room-entry-context-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -362,10 +362,14 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
/**
|
||||
* Room list entry.
|
||||
*
|
||||
* Active Room means there are participants in the room.
|
||||
* Opened Room means the user is in the room.
|
||||
*/
|
||||
var RoomEntry = React.createClass({displayName: "RoomEntry",
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
isOpenedRoom: React.PropTypes.bool.isRequired,
|
||||
mozLoop: React.PropTypes.object.isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
},
|
||||
@ -418,7 +422,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
render: function() {
|
||||
var roomClasses = React.addons.classSet({
|
||||
"room-entry": true,
|
||||
"room-active": this._isActive()
|
||||
"room-active": this._isActive(),
|
||||
"room-opened": this.props.isOpenedRoom
|
||||
});
|
||||
|
||||
var roomTitle = this.props.room.decryptedContext.roomName ||
|
||||
@ -427,8 +432,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: roomClasses,
|
||||
onClick: this.handleClickEntry,
|
||||
onMouseLeave: this._handleMouseOut,
|
||||
onClick: this.props.isOpenedRoom ? null : this.handleClickEntry,
|
||||
onMouseLeave: this.props.isOpenedRoom ? null : this._handleMouseOut,
|
||||
ref: "roomEntry"},
|
||||
React.createElement("h2", null,
|
||||
roomTitle
|
||||
@ -436,15 +441,17 @@ loop.panel = (function(_, mozL10n) {
|
||||
React.createElement(RoomEntryContextItem, {
|
||||
mozLoop: this.props.mozLoop,
|
||||
roomUrls: this.props.room.decryptedContext.urls}),
|
||||
React.createElement(RoomEntryContextButtons, {
|
||||
dispatcher: this.props.dispatcher,
|
||||
eventPosY: this.state.eventPosY,
|
||||
handleClickEntry: this.handleClickEntry,
|
||||
handleContextChevronClick: this.handleContextChevronClick,
|
||||
ref: "contextActions",
|
||||
room: this.props.room,
|
||||
showMenu: this.state.showMenu,
|
||||
toggleDropdownMenu: this.toggleDropdownMenu})
|
||||
this.props.isOpenedRoom ? null :
|
||||
React.createElement(RoomEntryContextButtons, {
|
||||
dispatcher: this.props.dispatcher,
|
||||
eventPosY: this.state.eventPosY,
|
||||
handleClickEntry: this.handleClickEntry,
|
||||
handleContextChevronClick: this.handleContextChevronClick,
|
||||
ref: "contextActions",
|
||||
room: this.props.room,
|
||||
showMenu: this.state.showMenu,
|
||||
toggleDropdownMenu: this.toggleDropdownMenu})
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -719,12 +726,20 @@ loop.panel = (function(_, mozL10n) {
|
||||
return (
|
||||
React.createElement("div", {className: "rooms"},
|
||||
this._renderNewRoomButton(),
|
||||
React.createElement("h1", null, mozL10n.get("rooms_list_recent_conversations")),
|
||||
React.createElement("h1", null, mozL10n.get(this.state.openedRoom === null ?
|
||||
"rooms_list_recently_browsed" :
|
||||
"rooms_list_currently_browsing")),
|
||||
React.createElement("div", {className: "room-list"},
|
||||
this.state.rooms.map(function(room, i) {
|
||||
if (this.state.openedRoom !== null &&
|
||||
room.roomToken !== this.state.openedRoom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
React.createElement(RoomEntry, {
|
||||
dispatcher: this.props.dispatcher,
|
||||
isOpenedRoom: room.roomToken === this.state.openedRoom,
|
||||
key: room.roomToken,
|
||||
mozLoop: this.props.mozLoop,
|
||||
room: room})
|
||||
@ -927,8 +942,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
clearOnDocumentHidden: true,
|
||||
notifications: this.props.notifications}),
|
||||
React.createElement(RoomList, {dispatcher: this.props.dispatcher,
|
||||
mozLoop: this.props.mozLoop,
|
||||
store: this.props.roomStore}),
|
||||
mozLoop: this.props.mozLoop,
|
||||
store: this.props.roomStore}),
|
||||
React.createElement("div", {className: "footer"},
|
||||
React.createElement("div", {className: "user-details"},
|
||||
React.createElement(AccountLink, {fxAEnabled: this.props.mozLoop.fxAEnabled,
|
||||
|
@ -362,10 +362,14 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
/**
|
||||
* Room list entry.
|
||||
*
|
||||
* Active Room means there are participants in the room.
|
||||
* Opened Room means the user is in the room.
|
||||
*/
|
||||
var RoomEntry = React.createClass({
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
isOpenedRoom: React.PropTypes.bool.isRequired,
|
||||
mozLoop: React.PropTypes.object.isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
},
|
||||
@ -418,7 +422,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
render: function() {
|
||||
var roomClasses = React.addons.classSet({
|
||||
"room-entry": true,
|
||||
"room-active": this._isActive()
|
||||
"room-active": this._isActive(),
|
||||
"room-opened": this.props.isOpenedRoom
|
||||
});
|
||||
|
||||
var roomTitle = this.props.room.decryptedContext.roomName ||
|
||||
@ -427,8 +432,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
|
||||
return (
|
||||
<div className={roomClasses}
|
||||
onClick={this.handleClickEntry}
|
||||
onMouseLeave={this._handleMouseOut}
|
||||
onClick={this.props.isOpenedRoom ? null : this.handleClickEntry}
|
||||
onMouseLeave={this.props.isOpenedRoom ? null : this._handleMouseOut}
|
||||
ref="roomEntry">
|
||||
<h2>
|
||||
{roomTitle}
|
||||
@ -436,15 +441,17 @@ loop.panel = (function(_, mozL10n) {
|
||||
<RoomEntryContextItem
|
||||
mozLoop={this.props.mozLoop}
|
||||
roomUrls={this.props.room.decryptedContext.urls} />
|
||||
<RoomEntryContextButtons
|
||||
dispatcher={this.props.dispatcher}
|
||||
eventPosY={this.state.eventPosY}
|
||||
handleClickEntry={this.handleClickEntry}
|
||||
handleContextChevronClick={this.handleContextChevronClick}
|
||||
ref="contextActions"
|
||||
room={this.props.room}
|
||||
showMenu={this.state.showMenu}
|
||||
toggleDropdownMenu={this.toggleDropdownMenu} />
|
||||
{this.props.isOpenedRoom ? null :
|
||||
<RoomEntryContextButtons
|
||||
dispatcher={this.props.dispatcher}
|
||||
eventPosY={this.state.eventPosY}
|
||||
handleClickEntry={this.handleClickEntry}
|
||||
handleContextChevronClick={this.handleContextChevronClick}
|
||||
ref="contextActions"
|
||||
room={this.props.room}
|
||||
showMenu={this.state.showMenu}
|
||||
toggleDropdownMenu={this.toggleDropdownMenu} />
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -719,12 +726,20 @@ loop.panel = (function(_, mozL10n) {
|
||||
return (
|
||||
<div className="rooms">
|
||||
{this._renderNewRoomButton()}
|
||||
<h1>{mozL10n.get("rooms_list_recent_conversations")}</h1>
|
||||
<h1>{mozL10n.get(this.state.openedRoom === null ?
|
||||
"rooms_list_recently_browsed" :
|
||||
"rooms_list_currently_browsing")}</h1>
|
||||
<div className="room-list">{
|
||||
this.state.rooms.map(function(room, i) {
|
||||
if (this.state.openedRoom !== null &&
|
||||
room.roomToken !== this.state.openedRoom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RoomEntry
|
||||
dispatcher={this.props.dispatcher}
|
||||
isOpenedRoom={room.roomToken === this.state.openedRoom}
|
||||
key={room.roomToken}
|
||||
mozLoop={this.props.mozLoop}
|
||||
room={room} />
|
||||
@ -927,8 +942,8 @@ loop.panel = (function(_, mozL10n) {
|
||||
clearOnDocumentHidden={true}
|
||||
notifications={this.props.notifications} />
|
||||
<RoomList dispatcher={this.props.dispatcher}
|
||||
mozLoop={this.props.mozLoop}
|
||||
store={this.props.roomStore} />
|
||||
mozLoop={this.props.mozLoop}
|
||||
store={this.props.roomStore} />
|
||||
<div className="footer">
|
||||
<div className="user-details">
|
||||
<AccountLink fxAEnabled={this.props.mozLoop.fxAEnabled}
|
||||
|
@ -13,6 +13,7 @@ describe("loop.panel", function() {
|
||||
var sandbox, notifications;
|
||||
var fakeXHR, fakeWindow, fakeMozLoop, fakeEvent;
|
||||
var requests = [];
|
||||
var roomData, roomData2, roomList, roomName;
|
||||
var mozL10nGetSpy;
|
||||
|
||||
beforeEach(function() {
|
||||
@ -73,6 +74,45 @@ describe("loop.panel", function() {
|
||||
userProfile: null
|
||||
};
|
||||
|
||||
roomName = "First Room Name";
|
||||
roomData = {
|
||||
roomToken: "QzBbvGmIZWU",
|
||||
roomUrl: "http://sample/QzBbvGmIZWU",
|
||||
decryptedContext: {
|
||||
roomName: roomName
|
||||
},
|
||||
maxSize: 2,
|
||||
participants: [{
|
||||
displayName: "Alexis",
|
||||
account: "alexis@example.com",
|
||||
roomConnectionId: "2a1787a6-4a73-43b5-ae3e-906ec1e763cb"
|
||||
}, {
|
||||
displayName: "Adam",
|
||||
roomConnectionId: "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"
|
||||
}],
|
||||
ctime: 1405517418
|
||||
};
|
||||
|
||||
roomData2 = {
|
||||
roomToken: "QzBbvlmIZWU",
|
||||
roomUrl: "http://sample/QzBbvlmIZWU",
|
||||
decryptedContext: {
|
||||
roomName: "Second Room Name"
|
||||
},
|
||||
maxSize: 2,
|
||||
participants: [{
|
||||
displayName: "Bill",
|
||||
account: "bill@example.com",
|
||||
roomConnectionId: "2a1737a6-4a73-43b5-ae3e-906ec1e763cb"
|
||||
}, {
|
||||
displayName: "Bob",
|
||||
roomConnectionId: "781f212b-f1ea-4ce1-9105-7cfc36fb4ec7"
|
||||
}],
|
||||
ctime: 1405517417
|
||||
};
|
||||
|
||||
roomList = [new loop.store.Room(roomData), new loop.store.Room(roomData2)];
|
||||
|
||||
document.mozL10n.initialize(navigator.mozLoop);
|
||||
sandbox.stub(document.mozL10n, "get").returns("Fake title");
|
||||
});
|
||||
@ -538,25 +578,10 @@ describe("loop.panel", function() {
|
||||
});
|
||||
|
||||
describe("loop.panel.RoomEntry", function() {
|
||||
var dispatcher, roomData;
|
||||
var dispatcher;
|
||||
|
||||
beforeEach(function() {
|
||||
dispatcher = new loop.Dispatcher();
|
||||
roomData = {
|
||||
roomToken: "QzBbvGmIZWU",
|
||||
roomUrl: "http://sample/QzBbvGmIZWU",
|
||||
decryptedContext: {
|
||||
roomName: "Second Room Name"
|
||||
},
|
||||
maxSize: 2,
|
||||
participants: [
|
||||
{ displayName: "Alexis", account: "alexis@example.com",
|
||||
roomConnectionId: "2a1787a6-4a73-43b5-ae3e-906ec1e763cb" },
|
||||
{ displayName: "Adam",
|
||||
roomConnectionId: "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7" }
|
||||
],
|
||||
ctime: 1405517418
|
||||
};
|
||||
});
|
||||
|
||||
function mountRoomEntry(props) {
|
||||
@ -576,7 +601,10 @@ describe("loop.panel", function() {
|
||||
// the actions we are triggering.
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
view = mountRoomEntry({ room: new loop.store.Room(roomData) });
|
||||
view = mountRoomEntry({
|
||||
isOpenedRoom: false,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
});
|
||||
|
||||
// XXX Current version of React cannot use TestUtils.Simulate, please
|
||||
@ -618,6 +646,7 @@ describe("loop.panel", function() {
|
||||
|
||||
roomEntry = mountRoomEntry({
|
||||
deleteRoom: sandbox.stub(),
|
||||
isOpenedRoom: false,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
});
|
||||
@ -648,6 +677,18 @@ describe("loop.panel", function() {
|
||||
|
||||
sinon.assert.calledOnce(fakeWindow.close);
|
||||
});
|
||||
|
||||
it("should not dispatch an OpenRoom action when button is clicked if room is already opened", function() {
|
||||
roomEntry = mountRoomEntry({
|
||||
deleteRoom: sandbox.stub(),
|
||||
isOpenedRoom: true,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
|
||||
TestUtils.Simulate.click(roomEntry.refs.roomEntry.getDOMNode());
|
||||
|
||||
sinon.assert.notCalled(dispatcher.dispatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -656,6 +697,7 @@ describe("loop.panel", function() {
|
||||
|
||||
function mountEntryForContext() {
|
||||
return mountRoomEntry({
|
||||
isOpenedRoom: false,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
}
|
||||
@ -716,6 +758,7 @@ describe("loop.panel", function() {
|
||||
|
||||
roomEntry = mountRoomEntry({
|
||||
dispatcher: dispatcher,
|
||||
isOpenedRoom: false,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
roomEntryNode = roomEntry.getDOMNode();
|
||||
@ -727,6 +770,7 @@ describe("loop.panel", function() {
|
||||
it("should update room name", function() {
|
||||
var roomEntry = mountRoomEntry({
|
||||
dispatcher: dispatcher,
|
||||
isOpenedRoom: false,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
var updatedRoom = new loop.store.Room(_.extend({}, roomData, {
|
||||
@ -808,7 +852,7 @@ describe("loop.panel", function() {
|
||||
});
|
||||
|
||||
describe("loop.panel.RoomList", function() {
|
||||
var roomStore, dispatcher, fakeEmail, dispatch, roomData;
|
||||
var roomStore, dispatcher, fakeEmail, dispatch;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeEmail = "fakeEmail@example.com";
|
||||
@ -817,6 +861,7 @@ describe("loop.panel", function() {
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
roomStore.setStoreState({
|
||||
openedRoom: null,
|
||||
pendingCreation: false,
|
||||
pendingInitialRetrieval: false,
|
||||
rooms: [],
|
||||
@ -824,24 +869,6 @@ describe("loop.panel", function() {
|
||||
});
|
||||
|
||||
dispatch = sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
roomData = {
|
||||
roomToken: "QzBbvGmIZWU",
|
||||
roomUrl: "http://sample/QzBbvGmIZWU",
|
||||
decryptedContext: {
|
||||
roomName: "Second Room Name"
|
||||
},
|
||||
maxSize: 2,
|
||||
participants: [{
|
||||
displayName: "Alexis",
|
||||
account: "alexis@example.com",
|
||||
roomConnectionId: "2a1787a6-4a73-43b5-ae3e-906ec1e763cb"
|
||||
}, {
|
||||
displayName: "Adam",
|
||||
roomConnectionId: "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"
|
||||
}],
|
||||
ctime: 1405517418
|
||||
};
|
||||
});
|
||||
|
||||
function createTestComponent() {
|
||||
@ -896,6 +923,27 @@ describe("loop.panel", function() {
|
||||
|
||||
expect(view.getDOMNode().querySelectorAll(".room-list-loading").length).to.eql(1);
|
||||
});
|
||||
|
||||
it("should show multiple rooms in list with no opened room", function() {
|
||||
roomStore.setStoreState({ rooms: roomList });
|
||||
|
||||
var view = createTestComponent();
|
||||
|
||||
var node = view.getDOMNode();
|
||||
expect(node.querySelectorAll(".room-opened").length).to.eql(0);
|
||||
expect(node.querySelectorAll(".room-entry").length).to.eql(2);
|
||||
});
|
||||
|
||||
it("should only show the opened room you're in when you're in a room", function() {
|
||||
roomStore.setStoreState({ rooms: roomList, openedRoom: roomList[0].roomToken });
|
||||
|
||||
var view = createTestComponent();
|
||||
|
||||
var node = view.getDOMNode();
|
||||
expect(node.querySelectorAll(".room-opened").length).to.eql(1);
|
||||
expect(node.querySelectorAll(".room-entry").length).to.eql(1);
|
||||
expect(node.querySelectorAll(".room-opened h2")[0].textContent).to.equal(roomName);
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.panel.NewRoomView", function() {
|
||||
@ -1074,7 +1122,7 @@ describe("loop.panel", function() {
|
||||
});
|
||||
|
||||
describe("RoomEntryContextButtons", function() {
|
||||
var view, dispatcher, roomData;
|
||||
var view, dispatcher;
|
||||
|
||||
function createTestComponent(extraProps) {
|
||||
var props = _.extend({
|
||||
@ -1091,24 +1139,6 @@ describe("loop.panel", function() {
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
roomData = {
|
||||
roomToken: "QzBbvGmIZWU",
|
||||
roomUrl: "http://sample/QzBbvGmIZWU",
|
||||
decryptedContext: {
|
||||
roomName: "Second Room Name"
|
||||
},
|
||||
maxSize: 2,
|
||||
participants: [{
|
||||
displayName: "Alexis",
|
||||
account: "alexis@example.com",
|
||||
roomConnectionId: "2a1787a6-4a73-43b5-ae3e-906ec1e763cb"
|
||||
}, {
|
||||
displayName: "Adam",
|
||||
roomConnectionId: "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"
|
||||
}],
|
||||
ctime: 1405517418
|
||||
};
|
||||
|
||||
dispatcher = new loop.Dispatcher();
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
|
@ -183,9 +183,12 @@ tour_label=Tour
|
||||
## will be replaced by a number. For example "Conversation 1" or "Conversation 12".
|
||||
rooms_default_room_name_template=Conversation {{conversationLabel}}
|
||||
rooms_leave_button_label=Leave
|
||||
## LOCALIZATION NOTE (rooms_list_recent_conversations): String is in all caps
|
||||
## LOCALIZATION NOTE (rooms_list_recently_browsed): String is in all caps
|
||||
## for emphasis reasons, it is a heading. Proceed as appropriate for locale.
|
||||
rooms_list_recent_conversations=RECENT CONVERSATIONS
|
||||
rooms_list_recently_browsed=RECENTLY BROWSED
|
||||
## LOCALIZATION NOTE (rooms_list_currently_browsing): String is in all caps
|
||||
## for emphasis reasons, it is a heading. Proceed as appropriate for locale.
|
||||
rooms_list_currently_browsing=CURRENTLY BROWSING
|
||||
rooms_change_failed_label=Conversation cannot be updated
|
||||
rooms_panel_title=Choose a conversation or start a new one
|
||||
rooms_room_full_label=There are already two people in this conversation.
|
||||
|
Loading…
Reference in New Issue
Block a user