diff --git a/src/skins/vector/css/molecules/RoomDropTarget.css b/src/skins/vector/css/molecules/RoomDropTarget.css
index 549fa609ec..5e3facc4e2 100644
--- a/src/skins/vector/css/molecules/RoomDropTarget.css
+++ b/src/skins/vector/css/molecules/RoomDropTarget.css
@@ -26,6 +26,11 @@ limitations under the License.
border-radius: 4px;
}
+.mx_RoomDropTarget_placeholder {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
.mx_RoomDropTarget_avatar {
background-color: #fff;
border-radius: 24px;
diff --git a/src/skins/vector/css/molecules/RoomTile.css b/src/skins/vector/css/molecules/RoomTile.css
index b62552252b..4bc71cb801 100644
--- a/src/skins/vector/css/molecules/RoomTile.css
+++ b/src/skins/vector/css/molecules/RoomTile.css
@@ -16,7 +16,8 @@ limitations under the License.
.mx_RoomTile {
cursor: pointer;
- display: table-row;
+ /* This fixes wrapping of long room names, but breaks drag & drop previews */
+ /* display: table-row; */
font-size: 14px;
}
@@ -38,6 +39,7 @@ limitations under the License.
.mx_RoomTile_name {
display: table-cell;
+ width: 100%;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
diff --git a/src/skins/vector/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
index c1a2a9548f..00d0546c90 100644
--- a/src/skins/vector/views/molecules/RoomDropTarget.js
+++ b/src/skins/vector/views/molecules/RoomDropTarget.js
@@ -22,13 +22,21 @@ module.exports = React.createClass({
displayName: 'RoomDropTarget',
render: function() {
- return (
-
-
-
- { this.props.label }
+ if (this.props.placeholder) {
+ return (
+
-
- );
+ );
+ }
+ else {
+ return (
+
+
+
+ { this.props.label }
+
+
+ );
+ }
}
});
diff --git a/src/skins/vector/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
index a8f646aeab..28e76a7034 100644
--- a/src/skins/vector/views/molecules/RoomTile.js
+++ b/src/skins/vector/views/molecules/RoomTile.js
@@ -43,10 +43,16 @@ var roomTileSource = {
originalList: props.roomSubList,
originalIndex: props.roomSubList.findRoomTile(props.room).index,
targetList: props.roomSubList, // at first target is same as original
+ lastTargetRoom: null,
+ lastYOffset: null,
+ lastYDelta: null,
};
console.log("roomTile beginDrag for " + item.room.roomId);
+ // doing this 'correctly' with state causes react-dnd to break seemingly due to the state transitions
+ props.room._dragging = true;
+
return item;
},
@@ -56,6 +62,11 @@ var roomTileSource = {
console.log("roomTile endDrag for " + item.room.roomId + " with didDrop=" + monitor.didDrop());
+ props.room._dragging = false;
+ if (monitor.didDrop()) {
+ monitor.getDropResult().component.forceUpdate(); // as we're not using state
+ }
+
if (monitor.didDrop() && item.targetList.props.editable) {
// if we moved lists, remove the old tag
if (item.targetList !== item.originalList) {
@@ -112,7 +123,8 @@ var roomTileTarget = {
hover: function(props, monitor) {
var item = monitor.getItem();
- //console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());
+ var off = monitor.getClientOffset();
+ // console.log("hovering on room " + props.room.roomId + ", isOver=" + monitor.isOver());
//console.log("item.targetList=" + item.targetList + ", roomSubList=" + props.roomSubList);
@@ -120,7 +132,7 @@ var roomTileTarget = {
if (item.targetList !== props.roomSubList) {
// we've switched target, so remove the tile from the previous target.
// n.b. the previous target might actually be the source list.
- console.log("switched target");
+ console.log("switched target sublist");
switchedTarget = true;
item.targetList.removeRoomTile(item.room);
item.targetList = props.roomSubList;
@@ -129,10 +141,35 @@ var roomTileTarget = {
if (!item.targetList.props.editable) return;
if (item.targetList.props.order === 'manual') {
- if (item.room.roomId !== props.room.roomId) {
+ if (item.room.roomId !== props.room.roomId && props.room !== item.lastTargetRoom) {
+ // find the offset of the target tile in the list.
var roomTile = props.roomSubList.findRoomTile(props.room);
+ // shuffle the list to add our tile to that position.
props.roomSubList.moveRoomTile(item.room, roomTile.index);
}
+
+ // stop us from flickering between our droptarget and the previous room.
+ // whenever the cursor changes direction we have to reset the flicker-damping.
+
+ var yDelta = off.y - item.lastYOffset;
+
+ if ((yDelta > 0 && item.lastYDelta < 0) ||
+ (yDelta < 0 && item.lastYDelta > 0))
+ {
+ // the cursor changed direction - forget our previous room
+ item.lastTargetRoom = null;
+ }
+ else {
+ // track the last room we were hovering over so we can stop
+ // bouncing back and forth if the droptarget is narrower than
+ // the other list items. The other way to do this would be
+ // to reduce the size of the hittarget on the list items, but
+ // can't see an easy way to do that.
+ item.lastTargetRoom = props.room;
+ }
+
+ if (yDelta) item.lastYDelta = yDelta;
+ item.lastYOffset = off.y;
}
else if (switchedTarget) {
if (!props.roomSubList.findRoomTile(item.room).room) {
@@ -175,6 +212,15 @@ var RoomTile = React.createClass({
},
render: function() {
+ // if (this.props.clientOffset) {
+ // //console.log("room " + this.props.room.roomId + " has dropTarget clientOffset " + this.props.clientOffset.x + "," + this.props.clientOffset.y);
+ // }
+
+ if (this.props.room._dragging) {
+ var RoomDropTarget = sdk.getComponent("molecules.RoomDropTarget");
+ return
;
+ }
+
var myUserId = MatrixClientPeg.get().credentials.userId;
var me = this.props.room.currentState.members[myUserId];
var classes = classNames({
@@ -247,11 +293,12 @@ var RoomTile = React.createClass({
// Export the wrapped version, inlining the 'collect' functions
// to more closely resemble the ES7
module.exports =
-DropTarget('RoomTile', roomTileTarget, function(connect) {
+DropTarget('RoomTile', roomTileTarget, function(connect, monitor) {
return {
// Call this function inside render()
// to let React DnD handle the drag events:
connectDropTarget: connect.dropTarget(),
+ isOver: monitor.isOver(),
}
})(
DragSource('RoomTile', roomTileSource, function(connect, monitor) {
diff --git a/src/skins/vector/views/organisms/RoomSubList.js b/src/skins/vector/views/organisms/RoomSubList.js
index b88bc3c70a..8dcccc733a 100644
--- a/src/skins/vector/views/organisms/RoomSubList.js
+++ b/src/skins/vector/views/organisms/RoomSubList.js
@@ -26,6 +26,11 @@ var roomListTarget = {
return true;
},
+ drop: function(props, monitor, component) {
+ console.log("dropped on sublist")
+ return { component: component };
+ },
+
hover: function(props, monitor, component) {
var item = monitor.getItem();
@@ -147,7 +152,7 @@ var RoomSubList = React.createClass({
findRoomTile: function(room) {
var index = this.state.sortedList.indexOf(room);
if (index >= 0) {
- //console.log("found: room: " + room + " with id " + room.roomId);
+ // console.log("found: room: " + room.roomId + " with index " + index);
}
else {
console.log("didn't find room");
@@ -210,14 +215,14 @@ var RoomSubList = React.createClass({
// XXX: is it evil to pass in self as a prop to RoomTile?
return (
+ room={ room }
+ roomSubList={ self }
+ 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' } />
);
});
},