actually manage manual ordering; support arbitrary tags; bug fixes
This commit is contained in:
parent
8842147ec3
commit
c884c5fc33
4 changed files with 135 additions and 38 deletions
|
@ -351,7 +351,7 @@ module.exports = {
|
|||
upload: undefined
|
||||
});
|
||||
}).done(undefined, function() {
|
||||
// display error message
|
||||
// TODO: display error message
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -38,54 +38,71 @@ module.exports = React.createClass({
|
|||
null;
|
||||
|
||||
var RoomSubList = sdk.getComponent('organisms.RoomSubList');
|
||||
var self = this;
|
||||
|
||||
return (
|
||||
<div className="mx_RoomList" onScroll={this._repositionTooltip}>
|
||||
<div className="mx_RoomList" onScroll={self._repositionTooltip}>
|
||||
{ expandButton }
|
||||
|
||||
<RoomSubList list={ this.state.lists['invites'] }
|
||||
<RoomSubList list={ self.state.lists['invites'] }
|
||||
label="Invites"
|
||||
editable={ false }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['favourites'] }
|
||||
<RoomSubList list={ self.state.lists['favourite'] }
|
||||
label="Favourites"
|
||||
tagname="favourites"
|
||||
tagName="favourite"
|
||||
verb="favourite"
|
||||
editable={ true }
|
||||
order="manual"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['recents'] }
|
||||
label="Recents"
|
||||
<RoomSubList list={ self.state.lists['recents'] }
|
||||
label="Conversations"
|
||||
editable={ true }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['hidden'] }
|
||||
label="Hidden"
|
||||
tagname="hidden"
|
||||
verb="hide"
|
||||
<RoomSubList list={ self.state.lists['lowpriority'] }
|
||||
label="Low priority"
|
||||
tagName="lowpriority"
|
||||
verb="deprioritize"
|
||||
editable={ true }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
|
||||
<RoomSubList list={ this.state.lists['archived'] }
|
||||
{ Object.keys(self.state.lists).map(function(tagName) {
|
||||
if (!tagName.match(/^(invites|favourite|recents|lowpriority|archived)$/)) {
|
||||
return <RoomSubList list={ self.state.lists[tagName] }
|
||||
key={ tagName }
|
||||
label={ tagName }
|
||||
tagName={ tagName }
|
||||
verb={ "tag as " + tagName }
|
||||
editable={ true }
|
||||
order="manual"
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
|
||||
}
|
||||
}) }
|
||||
|
||||
<RoomSubList list={ self.state.lists['archived'] }
|
||||
label="Historical"
|
||||
editable={ false }
|
||||
order="recent"
|
||||
activityMap={ this.state.activityMap }
|
||||
selectedRoom={ this.props.selectedRoom }
|
||||
collapsed={ this.props.collapsed } />
|
||||
activityMap={ self.state.activityMap }
|
||||
selectedRoom={ self.props.selectedRoom }
|
||||
collapsed={ self.props.collapsed } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
||||
|
@ -152,6 +153,49 @@ var RoomSubList = React.createClass({
|
|||
});
|
||||
},
|
||||
|
||||
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;
|
||||
var RoomTile = sdk.getComponent("molecules.RoomTile");
|
||||
|
|
Loading…
Reference in a new issue