From c884c5fc33bd85610e076c9ced216051b993d2c8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 6 Nov 2015 20:54:07 +0100 Subject: [PATCH] actually manage manual ordering; support arbitrary tags; bug fixes --- src/controllers/organisms/RoomView.js | 2 +- src/skins/vector/views/molecules/RoomTile.js | 50 ++++++++++++-- src/skins/vector/views/organisms/RoomList.js | 69 ++++++++++++------- .../vector/views/organisms/RoomSubList.js | 52 ++++++++++++-- 4 files changed, 135 insertions(+), 38 deletions(-) diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js index f5a8d28f26..28b15a261e 100644 --- a/src/controllers/organisms/RoomView.js +++ b/src/controllers/organisms/RoomView.js @@ -351,7 +351,7 @@ module.exports = { upload: undefined }); }).done(undefined, function() { - // display error message + // TODO: display error message }); }, diff --git a/src/skins/vector/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js index ad198694e2..5be7ac4c57 100644 --- a/src/skins/vector/views/molecules/RoomTile.js +++ b/src/skins/vector/views/molecules/RoomTile.js @@ -56,16 +56,50 @@ var roomTileSource = { console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop()); - if (!monitor.didDrop() || !item.targetList.props.editable) { + if (monitor.didDrop() && item.targetList.props.editable) { + // if we moved lists, remove the old tag + if (item.targetList !== item.originalList) { + // commented out attempts to set a spinner on our target component as component is actually + // the original source component being dragged, not our target. To fix we just need to + // move all of this to endDrop in the target instead. FIXME later. + + //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 }); + MatrixClientPeg.get().deleteRoomTag(item.room.roomId, item.originalList.props.tagName).finally(function() { + //component.state.set({ spinner: component.state.spinner-- }); + }).fail(function(err) { + var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); + Modal.createDialog(ErrorDialog, { + title: "Failed to remove tag " + item.originalList.props.tagName + " from room", + description: err.toString() + }); + }); + } + + var newOrder= {}; + if (item.targetList.props.order === 'manual') { + newOrder['order' = item.targetList.calcManualOrderTagData(item.room); + } + + // if we moved lists or the ordering changed, add the new tag + if (item.targetList.props.tagName && item.targetList !== item.originalList || newOrder) { + //component.state.set({ spinner: component.state.spinner ? component.state.spinner++ : 1 }); + MatrixClientPeg.get().setRoomTag(item.room.roomId, item.targetList.props.tagName, newOrder).finally(function() { + //component.state.set({ spinner: component.state.spinner-- }); + }).fail(function(err) { + var ErrorDialog = sdk.getComponent("organisms.ErrorDialog"); + Modal.createDialog(ErrorDialog, { + title: "Failed to add tag " + item.targetList.props.tagName + " to room", + description: err.toString() + }); + }); + } + } + else { + // cancel the drop and reset our original position props.roomSubList.moveRoomTile(item.room, item.originalIndex); if (item.targetList && item.targetList !== item.originalList) { item.targetList.removeRoomTile(item.room); } - return; - } - else { - // When dropped on a compatible target, actually set the right tags for the new ordering - // persistNewOrder(item.room, dropResult.listId); } } }; @@ -88,6 +122,8 @@ var roomTileTarget = { item.targetList = props.roomSubList; } + if (!item.targetList.props.editable) return; + if (item.targetList.props.order === 'manual') { if (item.room.roomId !== props.room.roomId) { var roomTile = props.roomSubList.findRoomTile(props.room); @@ -146,7 +182,7 @@ var RoomTile = React.createClass({ var name; if (this.props.isInvite) { - name = this.props.room.getMember(MatrixClientPeg.get().credentials.userId).events.member.getSender(); + name = this.props.room.getMember(myUserId).events.member.getSender(); } else { name = this.props.room.name; diff --git a/src/skins/vector/views/organisms/RoomList.js b/src/skins/vector/views/organisms/RoomList.js index 2e46c42fbc..98b1da5419 100644 --- a/src/skins/vector/views/organisms/RoomList.js +++ b/src/skins/vector/views/organisms/RoomList.js @@ -38,54 +38,71 @@ module.exports = React.createClass({ null; var RoomSubList = sdk.getComponent('organisms.RoomSubList'); + var self = this; return ( -
+
{ expandButton } - + activityMap={ self.state.activityMap } + selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } /> - + activityMap={ self.state.activityMap } + selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } /> - + activityMap={ self.state.activityMap } + selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } /> - + activityMap={ self.state.activityMap } + selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } /> - + + } + }) } + + + activityMap={ self.state.activityMap } + selectedRoom={ self.props.selectedRoom } + collapsed={ self.props.collapsed } />
); } diff --git a/src/skins/vector/views/organisms/RoomSubList.js b/src/skins/vector/views/organisms/RoomSubList.js index b5655e3739..27cfb2ae52 100644 --- a/src/skins/vector/views/organisms/RoomSubList.js +++ b/src/skins/vector/views/organisms/RoomSubList.js @@ -48,7 +48,7 @@ var RoomSubList = React.createClass({ propTypes: { list: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, label: React.PropTypes.string.isRequired, - tagname: React.PropTypes.string, + tagName: React.PropTypes.string, editable: React.PropTypes.bool, order: React.PropTypes.string.isRequired, selectedRoom: React.PropTypes.string.isRequired, @@ -88,8 +88,9 @@ var RoomSubList = React.createClass({ }, manualComparator: function(roomA, roomB) { - var a = roomA.tags[this.props.tagname].order; - var b = roomB.tags[this.props.tagname].order; + if (!roomA.tags[this.props.tagName] || !roomB.tags[this.props.tagName]) return 0; + 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); }, @@ -150,7 +151,50 @@ var RoomSubList = React.createClass({ room: room, index: index, }); - }, + }, + + calcManualOrderTagData: function(room) { + var index = this.state.sortedList.indexOf(room); + + // we sort rooms by the lexicographic ordering of the 'order' metadata on their tags. + // for convenience, we calculate this for now a floating point number between 0.0 and 1.0. + + var orderA = 0.0; // by default we're next to the beginning of the list + if (index > 0) { + var prevTag = this.state.sortedList[index - 1].tags[this.props.tagName]; + if (!prevTag) { + console.error("Previous room in sublist is not tagged to be in this list. This should never happen.") + } + else if (prevTag.order === undefined) { + console.error("Previous room in sublist has no ordering metadata. This should never happen."); + } + else { + orderA = prevTag.order; + } + } + + var orderB = 1.0; // by default we're next to the end of the list too + if (index < this.state.sortedList.length - 1) { + var nextTag = this.state.sortedList[index + 1].tags[this.props.tagName]; + if (!nextTag) { + console.error("Next room in sublist is not tagged to be in this list. This should never happen.") + } + else if (nextTag.order === undefined) { + console.error("Next room in sublist has no ordering metadata. This should never happen."); + } + else { + orderB = nextTag.order; + } + } + + var order = (orderA + orderB) / 2.0; + if (order === orderA || order === orderB) { + console.error("Cannot describe new list position. This should be incredibly unlikely."); + // TODO: renumber the list + } + + return order; + }, makeRoomTiles: function() { var self = this;