refactor out the sections of the RoomList into RoomSubLists. Start wiring up tags
This commit is contained in:
parent
8b9b268ec0
commit
7fe7af6026
9 changed files with 295 additions and 102 deletions
|
@ -34,6 +34,10 @@ limitations under the License.
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_callView {
|
||||
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_RoomList {
|
||||
-webkit-box-ordinal-group: 1;
|
||||
-moz-box-ordinal-group: 1;
|
||||
|
|
|
@ -18,27 +18,9 @@ limitations under the License.
|
|||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.mx_RoomList_invites,
|
||||
.mx_RoomList_recents {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomList_expandButton {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.mx_RoomList h2 {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
|
32
src/skins/vector/css/organisms/RoomSubList.css
Normal file
32
src/skins/vector/css/organisms/RoomSubList.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomSubList {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_label {
|
||||
text-transform: uppercase;
|
||||
color: #3d3b39;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
|
@ -30,6 +30,7 @@ skin['atoms.LogoutButton'] = require('./views/atoms/LogoutButton');
|
|||
skin['atoms.MemberAvatar'] = require('./views/atoms/MemberAvatar');
|
||||
skin['atoms.MessageTimestamp'] = require('./views/atoms/MessageTimestamp');
|
||||
skin['atoms.RoomAvatar'] = require('./views/atoms/RoomAvatar');
|
||||
skin['atoms.Spinner'] = require('./views/atoms/Spinner');
|
||||
skin['atoms.create_room.CreateRoomButton'] = require('./views/atoms/create_room/CreateRoomButton');
|
||||
skin['atoms.create_room.Presets'] = require('./views/atoms/create_room/Presets');
|
||||
skin['atoms.create_room.RoomAlias'] = require('./views/atoms/create_room/RoomAlias');
|
||||
|
@ -80,9 +81,11 @@ skin['organisms.QuestionDialog'] = require('./views/organisms/QuestionDialog');
|
|||
skin['organisms.RightPanel'] = require('./views/organisms/RightPanel');
|
||||
skin['organisms.RoomDirectory'] = require('./views/organisms/RoomDirectory');
|
||||
skin['organisms.RoomList'] = require('./views/organisms/RoomList');
|
||||
skin['organisms.RoomSubList'] = require('./views/organisms/RoomSubList');
|
||||
skin['organisms.RoomView'] = require('./views/organisms/RoomView');
|
||||
skin['organisms.UserSettings'] = require('./views/organisms/UserSettings');
|
||||
skin['organisms.ViewSource'] = require('./views/organisms/ViewSource');
|
||||
skin['pages.CompatibilityPage'] = require('./views/pages/CompatibilityPage');
|
||||
skin['pages.MatrixChat'] = require('./views/pages/MatrixChat');
|
||||
skin['templates.Login'] = require('./views/templates/Login');
|
||||
skin['templates.Register'] = require('./views/templates/Register');
|
||||
|
|
|
@ -20,9 +20,51 @@ var React = require('react');
|
|||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'LeftPanel',
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showCallElement: null,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
this._recheckCallElement(newProps.selectedRoom);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
dis.unregister(this.dispatcherRef);
|
||||
},
|
||||
|
||||
onAction: function(payload) {
|
||||
switch (payload.action) {
|
||||
// listen for call state changes to prod the render method, which
|
||||
// may hide the global CallView if the call it is tracking is dead
|
||||
case 'call_state':
|
||||
this._recheckCallElement(this.props.selectedRoom);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_recheckCallElement: function(selectedRoomId) {
|
||||
// if we aren't viewing a room with an ongoing call, but there is an
|
||||
// active call, show the call element - we need to do this to make
|
||||
// audio/video not crap out
|
||||
var activeCall = CallHandler.getAnyActiveCall();
|
||||
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
|
||||
var showCall = (activeCall && !callForRoom);
|
||||
this.setState({
|
||||
showCallElement: showCall
|
||||
});
|
||||
},
|
||||
|
||||
onHideClick: function() {
|
||||
dis.dispatch({
|
||||
action: 'hide_left_panel',
|
||||
|
@ -44,10 +86,17 @@ module.exports = React.createClass({
|
|||
// collapseButton = <img className="mx_LeftPanel_hideButton" onClick={ this.onHideClick } src="img/hide.png" width="12" height="20" alt="<"/>
|
||||
}
|
||||
|
||||
var callPreview;
|
||||
if (this.state.showCallElement) {
|
||||
var CallView = sdk.getComponent('molecules.voip.CallView');
|
||||
callPreview = <CallView className="mx_LeftPanel_callView"/>
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className={classes}>
|
||||
{ collapseButton }
|
||||
<IncomingCallBox />
|
||||
{ callPreview }
|
||||
<RoomList selectedRoom={this.props.selectedRoom} collapsed={this.props.collapsed}/>
|
||||
<BottomLeftMenu collapsed={this.props.collapsed}/>
|
||||
</aside>
|
||||
|
|
|
@ -33,46 +33,57 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var CallView = sdk.getComponent('molecules.voip.CallView');
|
||||
var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget');
|
||||
|
||||
var callElement;
|
||||
if (this.state.show_call_element) {
|
||||
callElement = <CallView className="mx_MatrixChat_callView"/>
|
||||
}
|
||||
|
||||
var expandButton = this.props.collapsed ?
|
||||
<img className="mx_RoomList_expandButton" onClick={ this.onShowClick } src="img/menu.png" width="20" alt=">"/> :
|
||||
null;
|
||||
|
||||
var invitesLabel = this.props.collapsed ? null : "Invites";
|
||||
var recentsLabel = this.props.collapsed ? null : "Recent";
|
||||
|
||||
var invites;
|
||||
if (this.state.inviteList.length) {
|
||||
invites = <div>
|
||||
<h2 className="mx_RoomList_invitesLabel">{ invitesLabel }</h2>
|
||||
<div className="mx_RoomList_invites">
|
||||
{this.makeRoomTiles(this.state.inviteList, true)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
var RoomSubList = sdk.getComponent('organisms.RoomSubList');
|
||||
|
||||
return (
|
||||
<div className="mx_RoomList" onScroll={this._repositionTooltip}>
|
||||
{ expandButton }
|
||||
{ callElement }
|
||||
{ invites }
|
||||
<h2 className="mx_RoomList_favouritesLabel">Favourites</h2>
|
||||
<RoomDropTarget text="Drop here to favourite"/>
|
||||
|
||||
<h2 className="mx_RoomList_recentsLabel">{ recentsLabel }</h2>
|
||||
<div className="mx_RoomList_recents">
|
||||
{this.makeRoomTiles(this.state.roomList, false)}
|
||||
</div>
|
||||
<RoomSubList list={ this.state.lists['invites'] }
|
||||
label="Invites"
|
||||
editable={ false }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
|
||||
<h2 className="mx_RoomList_archiveLabel">Archive</h2>
|
||||
<RoomDropTarget text="Drop here to archive"/>
|
||||
<RoomSubList list={ this.state.lists['favourites'] }
|
||||
label="Favourites"
|
||||
tagname="favourites"
|
||||
editable={ true }
|
||||
order="manual"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['recents'] }
|
||||
label="Recents"
|
||||
editable={ true }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['lurking'] }
|
||||
label="Others"
|
||||
tagname="secondary"
|
||||
editable={ true }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['archived'] }
|
||||
label="Historical"
|
||||
editable={ false }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
124
src/skins/vector/views/organisms/RoomSubList.js
Normal file
124
src/skins/vector/views/organisms/RoomSubList.js
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var sdk = require('matrix-react-sdk')
|
||||
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomSubList',
|
||||
|
||||
propTypes: {
|
||||
list: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||
label: React.PropTypes.string.isRequired,
|
||||
tagname: React.PropTypes.string,
|
||||
editable: React.PropTypes.bool,
|
||||
order: React.PropTypes.string.isRequired,
|
||||
selectedRoom: React.PropTypes.string.isRequired,
|
||||
activityMap: React.PropTypes.object.isRequired,
|
||||
collapsed: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
sortedList: [],
|
||||
};
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.sortList(this.props.list, this.props.order);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
// order the room list appropriately before we re-render
|
||||
this.sortList(newProps.list, newProps.order);
|
||||
},
|
||||
|
||||
tsOfNewestEvent: function(room) {
|
||||
if (room.timeline.length) {
|
||||
return room.timeline[room.timeline.length - 1].getTs();
|
||||
}
|
||||
else {
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: factor the comparators back out into a generic comparator
|
||||
// so that view_prev_room and view_next_room can do the right thing
|
||||
|
||||
recentsComparator: function(roomA, roomB) {
|
||||
return this.tsOfNewestEvent(roomB) - this.tsOfNewestEvent(roomA);
|
||||
},
|
||||
|
||||
manualComparator: function(roomA, roomB) {
|
||||
var a = roomA.tags[this.props.tagname].order;
|
||||
var b = roomB.tags[this.props.tagname].order;
|
||||
return a == b ? this.recentsComparator(roomA, roomB) : ( a > b ? 1 : -1);
|
||||
},
|
||||
|
||||
sortList: function(list, order) {
|
||||
var comparator;
|
||||
list = list || [];
|
||||
if (order === "manual") comparator = this.manualComparator;
|
||||
if (order === "recent") comparator = this.recentsComparator;
|
||||
|
||||
this.setState({ sortedList: list.sort(comparator) });
|
||||
},
|
||||
|
||||
makeRoomTiles: function() {
|
||||
var self = this;
|
||||
var RoomTile = sdk.getComponent("molecules.RoomTile");
|
||||
return this.state.sortedList.map(function(room) {
|
||||
var selected = room.roomId == self.props.selectedRoom;
|
||||
return (
|
||||
<RoomTile
|
||||
room={room}
|
||||
key={room.roomId}
|
||||
collapsed={self.props.collapsed}
|
||||
selected={selected}
|
||||
unread={self.props.activityMap[room.roomId] === 1}
|
||||
highlight={self.props.activityMap[room.roomId] === 2}
|
||||
isInvite={self.props.label === 'Invites'} />
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget');
|
||||
|
||||
var label = this.props.collapsed ? null : this.props.label;
|
||||
|
||||
if (this.state.sortedList.length > 0 || this.props.editable) {
|
||||
return (
|
||||
<div>
|
||||
<h2 className="mx_RoomSubList_label">{ this.props.label }</h2>
|
||||
<div className="mx_RoomSubList">
|
||||
{ this.makeRoomTiles() }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<div className="mx_RoomSubList">
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue