From 8d2ae42e988740b4e6fe95530c49587a4b6d58d6 Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Wed, 22 Sep 2021 10:22:42 +0200 Subject: [PATCH 1/3] WIP SAVEPOINT --- src/StatusQ/Components/StatusChatList.qml | 81 +++++++++++++++---- .../StatusChatListAndCategories.qml | 13 ++- .../Components/StatusChatListCategory.qml | 3 + 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/StatusQ/Components/StatusChatList.qml b/src/StatusQ/Components/StatusChatList.qml index 8fe20149..d95a3ff9 100644 --- a/src/StatusQ/Components/StatusChatList.qml +++ b/src/StatusQ/Components/StatusChatList.qml @@ -11,9 +11,11 @@ import StatusQ.Controls 0.1 Column { id: statusChatList - spacing: 4 + spacing: 0 width: 288 + property string uuid: Utils.uuid() + property string categoryId: "" property string selectedChatId: "" property alias chatListItems: delegateModel @@ -29,7 +31,7 @@ Column { signal chatItemSelected(string id) signal chatItemUnmuted(string id) - signal chatItemReordered(string id, int from, int to) + signal chatItemReordered(string categoryId, string id, int from, int to) onPopupMenuChanged: { if (!!popupMenu) { @@ -43,7 +45,17 @@ Column { delegate: Item { id: draggable width: statusChatListItem.width - height: statusChatListItem.height + /* height: dragSensor.active ? 0 : statusChatListItem.height + 4 */ + height: { + if (dropArea.containsDrag) { + if (dropArea.drag.source.chatListItem.chatId == statusChatListItem.chatId) { + return statusChatListItem.height + 4 + } + return (statusChatListItem.height + 4 ) * 2 + } else { + return statusChatListItem.height + 4 + } + } property alias chatListItem: statusChatListItem @@ -57,7 +69,12 @@ Column { MouseArea { id: dragSensor - anchors.fill: parent + anchors.topMargin: 2 + anchors.bottomMargin: 2 + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right cursorShape: active ? Qt.ClosedHandCursor : Qt.PointingHandCursor hoverEnabled: true pressAndHoldInterval: 150 @@ -75,12 +92,17 @@ Column { startY = mouseY startX = mouseX } + + onActiveChanged: { + if (!active) { + draggable.height = statusChatListItem.height + 4 + } + } onPressAndHold: active = true onReleased: { - if (active) { - statusChatList.chatItemReordered(statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.originalOrder) - } active = false + statusChatList.chatItemReordered(statusChatListItem.newCategoryId, statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.newOrder) + /* console.log("RELEASING! ", statusChatListItem.originalOrder, draggedListItemLoader.item.newPosition) */ } onMouseYChanged: { if ((Math.abs(startY - mouseY) > 1) && pressed) { @@ -97,8 +119,24 @@ Column { id: statusChatListItem + property string chatListId: statusChatList.uuid property string profileImage: "" + property var newOrder: model.position + property var newCategoryId: model.categoryId + anchors.centerIn: parent + anchors.verticalCenterOffset: { + if (dropArea.containsDrag) { + return dropArea.drag.y <= dropArea.height/2 ? + (statusChatListItem.height+4) / 2 : + -(statusChatListItem.height+4) / 2 + } + return 0 + } + /* Behavior on anchors.verticalCenterOffset { */ + /* enabled: dropArea.containsDrag */ + /* NumberAnimation { duration: 100 } */ + /* } */ opacity: dragSensor.active ? 0.0 : 1.0 Component.onCompleted: { if (typeof statusChatList.profileImageFn === "function") { @@ -159,12 +197,17 @@ Column { DropArea { id: dropArea - width: dragSensor.active ? 0 : parent.width - height: dragSensor.active ? 0 : parent.height - keys: ["chat-item-category-" + statusChatListItem.categoryId] + width: parent.width + height: parent.height + /* keys: ["chat-item-category-" + statusChatListItem.categoryId] */ + keys: ["chat-item"] onEntered: reorderDelay.start() - onDropped: statusChatList.chatItemReordered(statusChatListItem.chatId, drag.source.originalOrder, statusChatListItem.DelegateModel.itemsIndex) + onExited: { + if (drag.source.chatListItem.chatId == statusChatListItem.chatId) { + draggable.height = 0 + } + } Timer { id: reorderDelay @@ -172,8 +215,16 @@ Column { repeat: false onTriggered: { if (dropArea.containsDrag) { - dropArea.drag.source.chatListItem.originalOrder = statusChatListItem.originalOrder - delegateModel.items.move(dropArea.drag.source.DelegateModel.itemsIndex, draggable.DelegateModel.itemsIndex) + let newOrder = statusChatListItem.originalOrder + /* if (dropArea.drag.source.chatListItem.categoryId !== statusChatListItem.categoryId) { */ + /* if (dropArea.drag.y <= dropArea.height/2) { */ + /* if (newOrder > 0) { */ + /* newOrder = newOrder - 1 */ + /* } */ + /* } */ + /* } */ + dropArea.drag.source.chatListItem.newOrder = newOrder + dropArea.drag.source.chatListItem.newCategoryId = statusChatListItem.categoryId } } } @@ -183,13 +234,15 @@ Column { id: draggedListItemLoader active: dragSensor.active sourceComponent: StatusChatListItem { + property string chatListId: draggable.chatListItem.chatListId property var globalPosition: Utils.getAbsolutePosition(draggable) parent: QC.Overlay.overlay sensor.cursorShape: dragSensor.cursorShape Drag.active: dragSensor.active Drag.hotSpot.x: width / 2 Drag.hotSpot.y: height / 2 - Drag.keys: ["chat-item-category-" + categoryId] + /* Drag.keys: ["chat-item-category-" + categoryId] */ + Drag.keys: ["chat-item"] Drag.source: draggable Component.onCompleted: { diff --git a/src/StatusQ/Components/StatusChatListAndCategories.qml b/src/StatusQ/Components/StatusChatListAndCategories.qml index 2411fe09..e1685d72 100644 --- a/src/StatusQ/Components/StatusChatListAndCategories.qml +++ b/src/StatusQ/Components/StatusChatListAndCategories.qml @@ -142,7 +142,7 @@ Item { chatList.selectedChatId: statusChatListAndCategories.selectedChatId chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id) chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id) - chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.categoryId, id, from, to) + chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to) chatList.draggableItems: statusChatListAndCategories.draggableItems popupMenu: statusChatListAndCategories.categoryPopupMenu @@ -155,7 +155,9 @@ Item { height: draggable.chatListCategory.dragActive ? 0 : parent.height keys: ["chat-category"] - onEntered: reorderDelay.start() + onEntered: { + reorderDelay.start() + } onDropped: statusChatListAndCategories.chatListCategoryReordered(statusChatListCategory.categoryId, drag.source.originalOrder, statusChatListCategory.DelegateModel.itemsIndex) Timer { @@ -169,6 +171,13 @@ Item { } } } + + Rectangle { + color: "red" + opacity: 0.1 + anchors.fill: parent + visible: dropArea.containsDrag + } } Loader { diff --git a/src/StatusQ/Components/StatusChatListCategory.qml b/src/StatusQ/Components/StatusChatListCategory.qml index 806136de..ffbcdc40 100644 --- a/src/StatusQ/Components/StatusChatListCategory.qml +++ b/src/StatusQ/Components/StatusChatListCategory.qml @@ -1,5 +1,6 @@ import QtQuick 2.13 +import StatusQ.Core.Utils 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 @@ -8,6 +9,7 @@ Column { spacing: 0 opacity: dragged ? 0.5 : 1 + property string uuid: Utils.uuid() objectName: "chatListCategory" property int originalOrder: -1 @@ -64,6 +66,7 @@ Column { StatusChatList { id: statusChatList + uuid: statusChatListCategory.uuid anchors.horizontalCenter: parent.horizontalCenter visible: statusChatListCategory.opened categoryId: statusChatListCategory.categoryId From 5a5c611fd193c8815736df235727ab6215c0f05b Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Wed, 22 Sep 2021 14:24:21 +0200 Subject: [PATCH 2/3] WIP SAVEPOINT --- src/StatusQ/Components/StatusChatList.qml | 21 +++++++++++-------- .../StatusChatListAndCategories.qml | 7 ------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/StatusQ/Components/StatusChatList.qml b/src/StatusQ/Components/StatusChatList.qml index d95a3ff9..b6cd807a 100644 --- a/src/StatusQ/Components/StatusChatList.qml +++ b/src/StatusQ/Components/StatusChatList.qml @@ -100,8 +100,10 @@ Column { } onPressAndHold: active = true onReleased: { + if (active) { + statusChatList.chatItemReordered(statusChatListItem.newCategoryId, statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.newOrder) + } active = false - statusChatList.chatItemReordered(statusChatListItem.newCategoryId, statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.newOrder) /* console.log("RELEASING! ", statusChatListItem.originalOrder, draggedListItemLoader.item.newPosition) */ } onMouseYChanged: { @@ -125,6 +127,7 @@ Column { property var newCategoryId: model.categoryId anchors.centerIn: parent + /* anchors.horizontalCenter: parent.horizontalCenter */ anchors.verticalCenterOffset: { if (dropArea.containsDrag) { return dropArea.drag.y <= dropArea.height/2 ? @@ -146,7 +149,7 @@ Column { originalOrder: model.position chatId: model.chatId || model.id categoryId: model.categoryId || "" - name: !!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name + name: (!!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name) + " POSITION: " + statusChatListItem.newOrder type: model.chatType muted: !!model.muted hasUnreadMessages: !!model.hasUnreadMessages || model.unviewedMessagesCount > 0 @@ -216,13 +219,13 @@ Column { onTriggered: { if (dropArea.containsDrag) { let newOrder = statusChatListItem.originalOrder - /* if (dropArea.drag.source.chatListItem.categoryId !== statusChatListItem.categoryId) { */ - /* if (dropArea.drag.y <= dropArea.height/2) { */ - /* if (newOrder > 0) { */ - /* newOrder = newOrder - 1 */ - /* } */ - /* } */ - /* } */ + if (dropArea.drag.source.chatListItem.categoryId !== statusChatListItem.categoryId) { + if (dropArea.drag.y <= dropArea.height/2) { + if (newOrder > 0) { + newOrder = newOrder - 1 + } + } + } dropArea.drag.source.chatListItem.newOrder = newOrder dropArea.drag.source.chatListItem.newCategoryId = statusChatListItem.categoryId } diff --git a/src/StatusQ/Components/StatusChatListAndCategories.qml b/src/StatusQ/Components/StatusChatListAndCategories.qml index e1685d72..531a70fb 100644 --- a/src/StatusQ/Components/StatusChatListAndCategories.qml +++ b/src/StatusQ/Components/StatusChatListAndCategories.qml @@ -171,13 +171,6 @@ Item { } } } - - Rectangle { - color: "red" - opacity: 0.1 - anchors.fill: parent - visible: dropArea.containsDrag - } } Loader { From 146346a862a97b1deb5e7c13dccf1ba3ccaa9be0 Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Thu, 23 Sep 2021 13:35:13 +0200 Subject: [PATCH 3/3] WIP SAVEPOINT --- src/StatusQ/Components/StatusChatList.qml | 417 +++++++++--------- .../StatusChatListAndCategories.qml | 9 +- .../StatusChatListDropIndicator.qml | 11 + src/StatusQ/Components/qmldir | 1 + statusq.qrc | 1 + 5 files changed, 234 insertions(+), 205 deletions(-) create mode 100644 src/StatusQ/Components/StatusChatListDropIndicator.qml diff --git a/src/StatusQ/Components/StatusChatList.qml b/src/StatusQ/Components/StatusChatList.qml index b6cd807a..29e28740 100644 --- a/src/StatusQ/Components/StatusChatList.qml +++ b/src/StatusQ/Components/StatusChatList.qml @@ -18,7 +18,7 @@ Column { property string categoryId: "" property string selectedChatId: "" - property alias chatListItems: delegateModel + property alias chatListItems: statusChatListItems property bool draggableItems: false property alias statusChatListItems: statusChatListItems @@ -39,245 +39,254 @@ Column { } } - DelegateModel { - id: delegateModel - - delegate: Item { - id: draggable - width: statusChatListItem.width - /* height: dragSensor.active ? 0 : statusChatListItem.height + 4 */ - height: { - if (dropArea.containsDrag) { - if (dropArea.drag.source.chatListItem.chatId == statusChatListItem.chatId) { - return statusChatListItem.height + 4 + Column { + id: statusChatListItemsWrapper + width: parent.width + spacing: 4 + onImplicitHeightChanged: { + // For some reason, the binding on emptyListDropAreaLoaoder.active alone doesn't work. + // We have to explicitly reassign it here. + emptyListDropAreaLoader.active = implicitHeight == 0 + } + + Repeater { + id: statusChatListItems + delegate: Item { + id: draggable + width: statusChatListItem.width + height: statusChatListItem.height + + property alias chatListItem: statusChatListItem + + visible: { + if (!!statusChatList.filterFn) { + return statusChatList.filterFn(model, statusChatList.categoryId) } - return (statusChatListItem.height + 4 ) * 2 - } else { - return statusChatListItem.height + 4 + return true } - } - property alias chatListItem: statusChatListItem + MouseArea { + id: dragSensor - visible: { - if (!!statusChatList.filterFn) { - return statusChatList.filterFn(model, statusChatList.categoryId) - } - return true - } + anchors.fill: parent + cursorShape: active ? Qt.ClosedHandCursor : Qt.PointingHandCursor + hoverEnabled: true + pressAndHoldInterval: 150 + enabled: statusChatList.draggableItems - MouseArea { - id: dragSensor - - anchors.topMargin: 2 - anchors.bottomMargin: 2 - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - cursorShape: active ? Qt.ClosedHandCursor : Qt.PointingHandCursor - hoverEnabled: true - pressAndHoldInterval: 150 - enabled: statusChatList.draggableItems - - property bool active: false - property real startY: 0 - property real startX: 0 - - drag.target: draggedListItemLoader.item - drag.threshold: 0.1 - drag.filterChildren: true - - onPressed: { - startY = mouseY - startX = mouseX - } + property bool active: false + property real startY: 0 + property real startX: 0 - onActiveChanged: { - if (!active) { - draggable.height = statusChatListItem.height + 4 + drag.target: draggedListItemLoader.item + drag.threshold: 0.1 + drag.filterChildren: true + + onPressed: { + startY = mouseY + startX = mouseX } - } - onPressAndHold: active = true - onReleased: { - if (active) { - statusChatList.chatItemReordered(statusChatListItem.newCategoryId, statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.newOrder) + + onPressAndHold: active = true + onReleased: { + if (active && (statusChatListItem.originalOder !== statusChatListItem.newOrder || + statusChatListItem.categoryId !== statusChatListItem.newCategoryId)) { + statusChatList.chatItemReordered( + statusChatListItem.newCategoryId, + statusChatListItem.chatId, + statusChatListItem.originalOrder, + statusChatListItem.newOrder + ) + } + active = false } - active = false - /* console.log("RELEASING! ", statusChatListItem.originalOrder, draggedListItemLoader.item.newPosition) */ - } - onMouseYChanged: { - if ((Math.abs(startY - mouseY) > 1) && pressed) { - active = true + onMouseYChanged: { + if ((Math.abs(startY - mouseY) > 1) && pressed) { + active = true + } } - } - onMouseXChanged: { - if ((Math.abs(startX - mouseX) > 1) && pressed) { - active = true + onMouseXChanged: { + if ((Math.abs(startX - mouseX) > 1) && pressed) { + active = true + } } - } - StatusChatListItem { + StatusChatListItem { - id: statusChatListItem + id: statusChatListItem - property string chatListId: statusChatList.uuid - property string profileImage: "" - property var newOrder: model.position - property var newCategoryId: model.categoryId + property string chatListId: statusChatList.uuid + property string profileImage: "" + property var newOrder: model.position + property var newCategoryId: model.categoryId - anchors.centerIn: parent - /* anchors.horizontalCenter: parent.horizontalCenter */ - anchors.verticalCenterOffset: { - if (dropArea.containsDrag) { - return dropArea.drag.y <= dropArea.height/2 ? - (statusChatListItem.height+4) / 2 : - -(statusChatListItem.height+4) / 2 - } - return 0 - } - /* Behavior on anchors.verticalCenterOffset { */ - /* enabled: dropArea.containsDrag */ - /* NumberAnimation { duration: 100 } */ - /* } */ - opacity: dragSensor.active ? 0.0 : 1.0 - Component.onCompleted: { - if (typeof statusChatList.profileImageFn === "function") { - profileImage = statusChatList.profileImageFn(model.chatId || model.id) || "" + anchors.centerIn: parent + opacity: dragSensor.active ? 0.3 : 1.0 + Component.onCompleted: { + if (typeof statusChatList.profileImageFn === "function") { + profileImage = statusChatList.profileImageFn(model.chatId || model.id) || "" + } } - } - originalOrder: model.position - chatId: model.chatId || model.id - categoryId: model.categoryId || "" - name: (!!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name) + " POSITION: " + statusChatListItem.newOrder - type: model.chatType - muted: !!model.muted - hasUnreadMessages: !!model.hasUnreadMessages || model.unviewedMessagesCount > 0 - hasMention: model.mentionsCount > 0 - badge.value: model.chatType === StatusChatListItem.Type.OneToOneChat ? - model.unviewedMessagesCount || 0 : - model.mentionsCount || 0 - selected: (model.chatId || model.id) === statusChatList.selectedChatId - - icon.color: model.color || "" - image.isIdenticon: !!!profileImage && !!!model.identityImage && !!model.identicon - image.source: profileImage || model.identityImage || model.identicon || "" - - sensor.cursorShape: dragSensor.cursorShape - onClicked: { - if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) { - statusChatListItem.highlighted = true - - let originalOpenHandler = popupMenuSlot.item.openHandler - let originalCloseHandler = popupMenuSlot.item.closeHandler - - popupMenuSlot.item.openHandler = function () { - if (!!originalOpenHandler) { - originalOpenHandler((model.chatId || model.id)) + originalOrder: model.position + chatId: model.chatId || model.id + categoryId: model.categoryId || "" + /* name: (!!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name) + " POSITION: " + statusChatListItem.newOrder */ + name: (!!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name) + type: model.chatType + muted: !!model.muted + hasUnreadMessages: !!model.hasUnreadMessages || model.unviewedMessagesCount > 0 + hasMention: model.mentionsCount > 0 + badge.value: model.chatType === StatusChatListItem.Type.OneToOneChat ? + model.unviewedMessagesCount || 0 : + model.mentionsCount || 0 + selected: (model.chatId || model.id) === statusChatList.selectedChatId + + icon.color: model.color || "" + image.isIdenticon: !!!profileImage && !!!model.identityImage && !!model.identicon + image.source: profileImage || model.identityImage || model.identicon || "" + + sensor.cursorShape: dragSensor.cursorShape + onClicked: { + if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) { + statusChatListItem.highlighted = true + + let originalOpenHandler = popupMenuSlot.item.openHandler + let originalCloseHandler = popupMenuSlot.item.closeHandler + + popupMenuSlot.item.openHandler = function () { + if (!!originalOpenHandler) { + originalOpenHandler((model.chatId || model.id)) + } } - } - popupMenuSlot.item.closeHandler = function () { - if (statusChatListItem) { - statusChatListItem.highlighted = false - } - if (!!originalCloseHandler) { - originalCloseHandler() + popupMenuSlot.item.closeHandler = function () { + if (statusChatListItem) { + statusChatListItem.highlighted = false + } + if (!!originalCloseHandler) { + originalCloseHandler() + } } - } - popupMenuSlot.item.popup(mouse.x + 4, statusChatListItem.y + mouse.y + 6) - popupMenuSlot.item.openHandler = originalOpenHandler - return - } - if (!statusChatListItem.selected) { - statusChatList.chatItemSelected(model.chatId || model.id) + popupMenuSlot.item.popup(mouse.x + 4, statusChatListItem.y + mouse.y + 6) + popupMenuSlot.item.openHandler = originalOpenHandler + return + } + if (!statusChatListItem.selected) { + statusChatList.chatItemSelected(model.chatId || model.id) + } } - } - onUnmute: statusChatList.chatItemUnmuted(model.chatId || model.id) - } - } - - DropArea { - id: dropArea - width: parent.width - height: parent.height - /* keys: ["chat-item-category-" + statusChatListItem.categoryId] */ - keys: ["chat-item"] + onUnmute: statusChatList.chatItemUnmuted(model.chatId || model.id) - onEntered: reorderDelay.start() - onExited: { - if (drag.source.chatListItem.chatId == statusChatListItem.chatId) { - draggable.height = 0 + StatusChatListDropIndicator { + anchors.bottom: parent.bottom + anchors.bottomMargin: -2 + visible: dropArea.containsDrag + } } } - - Timer { - id: reorderDelay - interval: 100 - repeat: false - onTriggered: { - if (dropArea.containsDrag) { - let newOrder = statusChatListItem.originalOrder - if (dropArea.drag.source.chatListItem.categoryId !== statusChatListItem.categoryId) { - if (dropArea.drag.y <= dropArea.height/2) { - if (newOrder > 0) { - newOrder = newOrder - 1 - } + DropArea { + id: dropArea + width: parent.width + height: parent.height + keys: ["chat-item"] + + onEntered: reorderDelay.start() + + Timer { + id: reorderDelay + interval: 100 + repeat: false + onTriggered: { + if (dropArea.containsDrag) { + let newOrder = statusChatListItem.originalOrder + + if (dropArea.drag.source.chatListItem.originalOrder > statusChatListItem.originalOrder) { + newOrder = newOrder + 1 } + dropArea.drag.source.chatListItem.newOrder = newOrder + dropArea.drag.source.chatListItem.newCategoryId = statusChatListItem.categoryId } - dropArea.drag.source.chatListItem.newOrder = newOrder - dropArea.drag.source.chatListItem.newCategoryId = statusChatListItem.categoryId } } } - } - - Loader { - id: draggedListItemLoader - active: dragSensor.active - sourceComponent: StatusChatListItem { - property string chatListId: draggable.chatListItem.chatListId - property var globalPosition: Utils.getAbsolutePosition(draggable) - parent: QC.Overlay.overlay - sensor.cursorShape: dragSensor.cursorShape - Drag.active: dragSensor.active - Drag.hotSpot.x: width / 2 - Drag.hotSpot.y: height / 2 - /* Drag.keys: ["chat-item-category-" + categoryId] */ - Drag.keys: ["chat-item"] - Drag.source: draggable - - Component.onCompleted: { - x = globalPosition.x - y = globalPosition.y + Loader { + id: draggedListItemLoader + active: dragSensor.active + sourceComponent: StatusChatListItem { + property string chatListId: draggable.chatListItem.chatListId + property var globalPosition: Utils.getAbsolutePosition(draggable) + parent: QC.Overlay.overlay + sensor.cursorShape: dragSensor.cursorShape + Drag.active: dragSensor.active + Drag.hotSpot.x: width / 2 + Drag.hotSpot.y: height / 2 + Drag.keys: ["chat-item"] + Drag.source: draggable + + Component.onCompleted: { + x = globalPosition.x + y = globalPosition.y + } + chatId: draggable.chatListItem.chatId + categoryId: draggable.chatListItem.categoryId + name: draggable.chatListItem.name + type: draggable.chatListItem.type + muted: draggable.chatListItem.muted + dragged: true + hasUnreadMessages: draggable.chatListItem.hasUnreadMessages + hasMention: draggable.chatListItem.hasMention + badge.value: draggable.chatListItem.badge.value + selected: draggable.chatListItem.selected + + icon.color: draggable.chatListItem.icon.color + image.isIdenticon: draggable.chatListItem.image.isIdenticon + image.source: draggable.chatListItem.image.source } - chatId: draggable.chatListItem.chatId - categoryId: draggable.chatListItem.categoryId - name: draggable.chatListItem.name - type: draggable.chatListItem.type - muted: draggable.chatListItem.muted - dragged: true - hasUnreadMessages: draggable.chatListItem.hasUnreadMessages - hasMention: draggable.chatListItem.hasMention - badge.value: draggable.chatListItem.badge.value - selected: draggable.chatListItem.selected - - icon.color: draggable.chatListItem.icon.color - image.isIdenticon: draggable.chatListItem.image.isIdenticon - image.source: draggable.chatListItem.image.source } } } } - Repeater { - id: statusChatListItems - model: delegateModel - } - Loader { id: popupMenuSlot active: !!statusChatList.popupMenu } + + Loader { + id: emptyListDropAreaLoader + active: statusChatListItemsWrapper.implicitHeight == 0 + width: parent.width + height: active ? 8 : 0 + sourceComponent: Item { + width: statusChatList.width + height: 8 + + StatusChatListDropIndicator { + visible: emptyListDropArea.containsDrag + opacity: 0.5 + anchors.bottom: statusChatList.categoryId == "" ? parent.bottom : undefined + anchors.top: statusChatList.categoryId !== "" ? parent.top : undefined + } + + DropArea { + id: emptyListDropArea + anchors.fill: parent + visible: parent.visible + keys: ["chat-item"] + onEntered: reorderDelay2.start() + Timer { + id: reorderDelay2 + interval: 100 + repeat: false + onTriggered: { + if (emptyListDropArea.containsDrag) { + emptyListDropArea.drag.source.chatListItem.newOrder = 0 + emptyListDropArea.drag.source.chatListItem.newCategoryId = statusChatList.categoryId + } + } + } + } + } + } } diff --git a/src/StatusQ/Components/StatusChatListAndCategories.qml b/src/StatusQ/Components/StatusChatListAndCategories.qml index 531a70fb..b2086549 100644 --- a/src/StatusQ/Components/StatusChatListAndCategories.qml +++ b/src/StatusQ/Components/StatusChatListAndCategories.qml @@ -142,7 +142,14 @@ Item { chatList.selectedChatId: statusChatListAndCategories.selectedChatId chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id) chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id) - chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to) + chatList.onChatItemReordered: { + console.log("REORDERING CHAT ITEM:") + console.log("FROM CATEGORY: ", model.categoryId) + console.log("TO: ", categoryId) + console.log("FROM POSITION: ", from) + console.log("TO POSITION: ", to) + statusChatListAndCategories.chatItemReordered(categoryId, id, from, to) + } chatList.draggableItems: statusChatListAndCategories.draggableItems popupMenu: statusChatListAndCategories.categoryPopupMenu diff --git a/src/StatusQ/Components/StatusChatListDropIndicator.qml b/src/StatusQ/Components/StatusChatListDropIndicator.qml new file mode 100644 index 00000000..84b31aee --- /dev/null +++ b/src/StatusQ/Components/StatusChatListDropIndicator.qml @@ -0,0 +1,11 @@ +import QtQuick 2.13 +import StatusQ.Core.Theme 0.1 + +Rectangle { + id: root + implicitWidth: 288 + height: 4 + color: Theme.palette.successColor1 + radius: 2 +} + diff --git a/src/StatusQ/Components/qmldir b/src/StatusQ/Components/qmldir index 78e2b203..1354b19e 100644 --- a/src/StatusQ/Components/qmldir +++ b/src/StatusQ/Components/qmldir @@ -3,6 +3,7 @@ module StatusQ.Components StatusBadge 0.1 StatusBadge.qml StatusChatInfoToolBar 0.1 StatusChatInfoToolBar.qml StatusChatList 0.1 StatusChatList.qml +StatusChatListDropIndicator 0.1 StatusChatListDropIndicator.qml StatusChatListItem 0.1 StatusChatListItem.qml StatusChatListCategory 0.1 StatusChatListCategory.qml StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml diff --git a/statusq.qrc b/statusq.qrc index 01a6b987..358056ee 100644 --- a/statusq.qrc +++ b/statusq.qrc @@ -249,6 +249,7 @@ src/StatusQ/Controls/StatusBaseInput.qml src/StatusQ/Controls/StatusChatListCategoryItemButton.qml src/StatusQ/Components/StatusChatList.qml + src/StatusQ/Components/StatusChatListDropIndicator.qml src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml src/StatusQ/Popups/statusModal/StatusModalFooter.qml src/StatusQ/Popups/statusModal/StatusModalHeader.qml