Skip to content

Commit 6d9817e

Browse files
committed
Merge pull request element-hq#342 from vector-im/matthew/orderable-roomlist
Implement reorderable rooms via room tagging.
2 parents c3385d5 + 23c93de commit 6d9817e

28 files changed

Lines changed: 862 additions & 165 deletions

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"q": "^1.4.1",
3535
"react": "^0.13.3",
3636
"react-loader": "^1.4.0",
37-
"sanitize-html": "^1.11.1"
37+
"react-dnd": "^1.1.8",
38+
"sanitize-html": "^1.0.0"
3839
},
3940
"devDependencies": {
4041
"babel": "^5.8.23",

src/controllers/organisms/RoomList.js

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,23 @@ var dis = require("matrix-react-sdk/lib/dispatcher");
2323

2424
var sdk = require('matrix-react-sdk');
2525
var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
26-
var CallHandler = require("matrix-react-sdk/lib/CallHandler");
2726

2827
var HIDE_CONFERENCE_CHANS = true;
2928

3029
module.exports = {
30+
getInitialState: function() {
31+
return {
32+
activityMap: null,
33+
lists: {},
34+
}
35+
},
36+
3137
componentWillMount: function() {
3238
var cli = MatrixClientPeg.get();
3339
cli.on("Room", this.onRoom);
3440
cli.on("Room.timeline", this.onRoomTimeline);
3541
cli.on("Room.name", this.onRoomName);
42+
cli.on("Room.tags", this.onRoomTags);
3643
cli.on("RoomState.events", this.onRoomStateEvents);
3744
cli.on("RoomMember.name", this.onRoomMemberName);
3845

@@ -47,11 +54,6 @@ module.exports = {
4754

4855
onAction: function(payload) {
4956
switch (payload.action) {
50-
// listen for call state changes to prod the render method, which
51-
// may hide the global CallView if the call it is tracking is dead
52-
case 'call_state':
53-
this._recheckCallElement(this.props.selectedRoom);
54-
break;
5557
case 'view_tooltip':
5658
this.tooltip = payload.tooltip;
5759
this._repositionTooltip();
@@ -72,7 +74,6 @@ module.exports = {
7274

7375
componentWillReceiveProps: function(newProps) {
7476
this.state.activityMap[newProps.selectedRoom] = undefined;
75-
this._recheckCallElement(newProps.selectedRoom);
7677
this.setState({
7778
activityMap: this.state.activityMap
7879
});
@@ -109,6 +110,10 @@ module.exports = {
109110
this.refreshRoomList();
110111
},
111112

113+
onRoomTags: function(event, room) {
114+
this.refreshRoomList();
115+
},
116+
112117
onRoomStateEvents: function(ev, state) {
113118
setTimeout(this.refreshRoomList, 0);
114119
},
@@ -117,26 +122,36 @@ module.exports = {
117122
setTimeout(this.refreshRoomList, 0);
118123
},
119124

120-
121125
refreshRoomList: function() {
126+
// TODO: rather than bluntly regenerating and re-sorting everything
127+
// every time we see any kind of room change from the JS SDK
128+
// we could do incremental updates on our copy of the state
129+
// based on the room which has actually changed. This would stop
130+
// us re-rendering all the sublists every time anything changes anywhere
131+
// in the state of the client.
122132
this.setState(this.getRoomLists());
123133
},
124134

125135
getRoomLists: function() {
126-
var s = {};
127-
var inviteList = [];
128-
s.roomList = RoomListSorter.mostRecentActivityFirst(
129-
MatrixClientPeg.get().getRooms().filter(function(room) {
130-
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
131-
132-
if (me && me.membership == "invite") {
133-
inviteList.push(room);
134-
return false;
135-
}
136+
var s = { lists: {} };
136137

138+
s.lists["m.invite"] = [];
139+
s.lists["m.favourite"] = [];
140+
s.lists["m.recent"] = [];
141+
s.lists["m.lowpriority"] = [];
142+
s.lists["m.archived"] = [];
143+
144+
MatrixClientPeg.get().getRooms().forEach(function(room) {
145+
var me = room.getMember(MatrixClientPeg.get().credentials.userId);
146+
147+
if (me && me.membership == "invite") {
148+
s.lists["m.invite"].push(room);
149+
}
150+
else {
137151
var shouldShowRoom = (
138152
me && (me.membership == "join")
139153
);
154+
140155
// hiding conf rooms only ever toggles shouldShowRoom to false
141156
if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
142157
// we want to hide the 1:1 conf<->user room and not the group chat
@@ -151,23 +166,28 @@ module.exports = {
151166
}
152167
}
153168
}
154-
return shouldShowRoom;
155-
})
156-
);
157-
s.inviteList = RoomListSorter.mostRecentActivityFirst(inviteList);
158-
return s;
159-
},
160169

161-
_recheckCallElement: function(selectedRoomId) {
162-
// if we aren't viewing a room with an ongoing call, but there is an
163-
// active call, show the call element - we need to do this to make
164-
// audio/video not crap out
165-
var activeCall = CallHandler.getAnyActiveCall();
166-
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
167-
var showCall = (activeCall && !callForRoom);
168-
this.setState({
169-
show_call_element: showCall
170+
if (shouldShowRoom) {
171+
var tagNames = Object.keys(room.tags);
172+
if (tagNames.length) {
173+
for (var i = 0; i < tagNames.length; i++) {
174+
var tagName = tagNames[i];
175+
s.lists[tagName] = s.lists[tagName] || [];
176+
s.lists[tagNames[i]].push(room);
177+
}
178+
}
179+
else {
180+
s.lists["m.recent"].push(room);
181+
}
182+
}
183+
}
170184
});
185+
186+
//console.log("calculated new roomLists; m.recent = " + s.lists["m.recent"]);
187+
188+
// we actually apply the sorting to this when receiving the prop in RoomSubLists.
189+
190+
return s;
171191
},
172192

173193
_repositionTooltip: function(e) {
@@ -176,23 +196,4 @@ module.exports = {
176196
this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.scrollTop) + "px";
177197
}
178198
},
179-
180-
makeRoomTiles: function(list, isInvite) {
181-
var self = this;
182-
var RoomTile = sdk.getComponent("molecules.RoomTile");
183-
return list.map(function(room) {
184-
var selected = room.roomId == self.props.selectedRoom;
185-
return (
186-
<RoomTile
187-
room={room}
188-
key={room.roomId}
189-
collapsed={self.props.collapsed}
190-
selected={selected}
191-
unread={self.state.activityMap[room.roomId] === 1}
192-
highlight={self.state.activityMap[room.roomId] === 2}
193-
isInvite={isInvite}
194-
/>
195-
);
196-
});
197-
}
198199
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright 2015 OpenMarket Ltd
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
.mx_Spinner {
18+
display: -webkit-flex;
19+
display: flex;
20+
-webkit-align-items: center;
21+
-webkit-justify-content: center;
22+
align-items: center;
23+
justify-content: center;
24+
height: 100%;
25+
}

src/skins/vector/css/hide.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
.mx_RoomDropTarget,
21
.mx_RoomSettings_encrypt,
32
.mx_CreateRoom_encrypt,
43
.mx_RightPanel_filebutton

src/skins/vector/css/molecules/EventTile.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ limitations under the License.
1818
max-width: 100%;
1919
clear: both;
2020
margin-top: 24px;
21-
margin-left: 56px;
21+
margin-left: 65px;
2222
}
2323

2424
.mx_EventTile_avatar {
2525
padding-left: 18px;
2626
padding-right: 12px;
27-
margin-left: -64px;
27+
margin-left: -73px;
2828
margin-top: -4px;
2929
float: left;
3030
}

src/skins/vector/css/molecules/MessageComposer.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ limitations under the License.
3232
.mx_MessageComposer .mx_MessageComposer_avatar {
3333
display: table-cell;
3434
padding-left: 10px;
35-
padding-right: 20px;
35+
padding-right: 28px;
3636
height: 70px;
3737
}
3838

src/skins/vector/css/molecules/RoomDropTarget.css

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,46 @@ limitations under the License.
1616

1717
.mx_RoomDropTarget {
1818
font-size: 14px;
19-
text-align: center;
20-
margin-left: 8px;
21-
margin-right: 8px;
22-
padding-top: 16px;
23-
padding-bottom: 16px;
24-
background-color: #fbfbfb;
25-
border: 1px dashed #d7d7d7;
26-
border-radius: 8px;
19+
margin-left: 10px;
20+
margin-right: 15px;
21+
padding-top: 5px;
22+
padding-bottom: 5px;
23+
border: 1px dashed #76cfa6;
24+
color: #454545;
25+
background-color: rgba(255,255,255,0.5);
26+
border-radius: 4px;
27+
}
28+
29+
.collapsed .mx_RoomDropTarget {
30+
margin-right: 10px;
31+
}
32+
33+
.mx_RoomDropTarget_placeholder {
34+
padding-top: 1px;
35+
padding-bottom: 1px;
36+
}
37+
38+
.mx_RoomDropTarget_avatar {
39+
background-color: #fff;
40+
border-radius: 24px;
41+
width: 24px;
42+
height: 24px;
43+
float: left;
44+
margin-left: 7px;
45+
margin-right: 7px;
46+
}
47+
48+
.mx_RoomDropTarget_label {
49+
position: relative;
50+
margin-top: 3px;
51+
line-height: 21px;
52+
z-index: 1;
53+
}
54+
55+
.collapsed .mx_RoomDropTarget_avatar {
56+
float: none;
57+
}
58+
59+
.collapsed .mx_RoomDropTarget_label {
60+
display: none;
2761
}

src/skins/vector/css/molecules/RoomHeader.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ limitations under the License.
3333
.mx_RoomHeader_leftRow {
3434
height: 48px;
3535
margin-top: 18px;
36+
margin-left: -2px;
3637

3738
-webkit-box-ordinal-group: 1;
3839
-moz-box-ordinal-group: 1;
@@ -103,7 +104,7 @@ limitations under the License.
103104
color: #454545;
104105
font-weight: 800;
105106
font-size: 24px;
106-
padding-left: 8px;
107+
padding-left: 19px;
107108
padding-right: 16px;
108109
text-overflow: ellipsis;
109110
}
@@ -153,7 +154,7 @@ limitations under the License.
153154
max-height: 38px;
154155
color: #454545;
155156
font-weight: 300;
156-
padding-left: 8px;
157+
padding-left: 19px;
157158
padding-right: 16px;
158159
overflow: hidden;
159160
text-overflow: ellipsis;

src/skins/vector/css/molecules/RoomTile.css

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ limitations under the License.
1616

1717
.mx_RoomTile {
1818
cursor: pointer;
19-
display: table-row;
19+
/* This fixes wrapping of long room names, but breaks drag & drop previews */
20+
/* display: table-row; */
2021
font-size: 14px;
2122
}
2223

2324
.mx_RoomTile_avatar {
2425
display: table-cell;
25-
background: #eaf5f0;
2626
padding-right: 8px;
2727
padding-top: 4px;
2828
padding-bottom: 2px;
@@ -39,17 +39,16 @@ limitations under the License.
3939

4040
.mx_RoomTile_name {
4141
display: table-cell;
42+
width: 100%;
4243
vertical-align: middle;
4344
overflow: hidden;
4445
text-overflow: ellipsis;
4546
padding-right: 16px;
46-
color: #454545;
47-
opacity: 0.8;
47+
color: rgba(69, 69, 69, 0.8);
4848
}
4949

5050
.mx_RoomTile_invite {
51-
opacity: 0.5;
52-
font-weight: normal;
51+
color: rgba(69, 69, 69, 0.5);
5352
}
5453

5554
.collapsed .mx_RoomTile_name {
@@ -106,15 +105,16 @@ limitations under the License.
106105

107106
.mx_RoomTile_unread,
108107
.mx_RoomTile_highlight,
109-
.mx_RoomTile_invited
108+
.mx_RoomTile_selected
110109
{
111110
font-weight: bold;
112111
}
113112

114-
.mx_RoomTile_selected {
113+
.mx_RoomTile_selected .mx_RoomTile_name {
114+
color: #76cfa6 ! important;
115115
}
116116

117-
.mx_RoomTile.mx_RoomTile_selected {
117+
.mx_RoomTile.mx_RoomTile_selected .mx_RoomTile_name {
118118
background: url('img/selected.png');
119119
background-repeat: no-repeat;
120120
background-position: right center;

src/skins/vector/css/molecules/RoomTooltip.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ limitations under the License.
2121
border-radius: 8px;
2222
background-color: #fff;
2323
z-index: 1000;
24-
margin-top: 6px;
2524
left: 64px;
2625
padding: 6px;
2726
}

0 commit comments

Comments
 (0)