feat(StatusChatList): Add drag and drop support of list items
This implements drag and drop capabilities of chat items within a `StatusChatList`. The commit introduces a `DelegateModal` to visually reorder chat items when they're being dragged and dropped onto a `DropArea`. To persist the new order of chat items, various signals have been introduced to chat list related components: ```qml StatusChatList { onChatItemReordered: function (id, from, to) { // ... } } StatusChatListAndCategories { onChatItemReordered: function (categoryId, chatId, from, to) { // ... } } ``` There's no such API on the `StatusChatListCategory` type because that one already exposes its underlying `StatusChatList` via `chatList`, which makes the signal available. Dragging and dropping chat items is disabled by default and needs to be turned on using the `draggableItems` property: ```qml StatusChatList { draggableItems: true ... } ```
This commit is contained in:
parent
67031ad5b1
commit
85ee81cfa3
|
@ -467,6 +467,7 @@ Rectangle {
|
||||||
width: leftPanel.width
|
width: leftPanel.width
|
||||||
height: implicitHeight > (leftPanel.height - 64) ? implicitHeight + 8 : leftPanel.height - 64
|
height: implicitHeight > (leftPanel.height - 64) ? implicitHeight + 8 : leftPanel.height - 64
|
||||||
|
|
||||||
|
draggableItems: true
|
||||||
chatList.model: models.demoCommunityChatListItems
|
chatList.model: models.demoCommunityChatListItems
|
||||||
categoryList.model: models.demoCommunityCategoryItems
|
categoryList.model: models.demoCommunityCategoryItems
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ QtObject {
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
mentionsCount: 0
|
mentionsCount: 0
|
||||||
color: "blue"
|
color: "blue"
|
||||||
|
position: 0
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "1"
|
chatId: "1"
|
||||||
|
@ -22,6 +23,7 @@ QtObject {
|
||||||
color: "red"
|
color: "red"
|
||||||
unreadMessagesCount: 1
|
unreadMessagesCount: 1
|
||||||
mentionsCount: 1
|
mentionsCount: 1
|
||||||
|
position: 1
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "2"
|
chatId: "2"
|
||||||
|
@ -32,6 +34,7 @@ QtObject {
|
||||||
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
|
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
|
||||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
|
position: 2
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "3"
|
chatId: "3"
|
||||||
|
@ -40,6 +43,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
muted: false
|
muted: false
|
||||||
color: "purple"
|
color: "purple"
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
|
position: 3
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "4"
|
chatId: "4"
|
||||||
|
@ -48,6 +52,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
muted: true
|
muted: true
|
||||||
color: "Orange"
|
color: "Orange"
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
|
position: 4
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "5"
|
chatId: "5"
|
||||||
|
@ -56,6 +61,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
muted: false
|
muted: false
|
||||||
color: "green"
|
color: "green"
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
|
position: 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +74,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
muted: false
|
muted: false
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
color: "orange"
|
color: "orange"
|
||||||
|
position: 0
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "1"
|
chatId: "1"
|
||||||
|
@ -77,6 +84,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
color: "orange"
|
color: "orange"
|
||||||
categoryId: "public"
|
categoryId: "public"
|
||||||
|
position: 0
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "2"
|
chatId: "2"
|
||||||
|
@ -86,6 +94,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
color: "orange"
|
color: "orange"
|
||||||
categoryId: "public"
|
categoryId: "public"
|
||||||
|
position: 1
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "3"
|
chatId: "3"
|
||||||
|
@ -95,6 +104,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
color: "orange"
|
color: "orange"
|
||||||
categoryId: "dev"
|
categoryId: "dev"
|
||||||
|
position: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
import QtQml.Models 2.14
|
||||||
|
import QtQuick.Controls 2.13 as QC
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
@ -13,7 +15,8 @@ Column {
|
||||||
|
|
||||||
property string categoryId: ""
|
property string categoryId: ""
|
||||||
property string selectedChatId: ""
|
property string selectedChatId: ""
|
||||||
property alias chatListItems: statusChatListItems
|
property alias chatListItems: delegateModel
|
||||||
|
property bool draggableItems: false
|
||||||
|
|
||||||
property Component popupMenu
|
property Component popupMenu
|
||||||
|
|
||||||
|
@ -23,6 +26,19 @@ Column {
|
||||||
|
|
||||||
signal chatItemSelected(string id)
|
signal chatItemSelected(string id)
|
||||||
signal chatItemUnmuted(string id)
|
signal chatItemUnmuted(string id)
|
||||||
|
signal chatItemReordered(string id, int from, int to)
|
||||||
|
|
||||||
|
function getAbsolutePosition(node) {
|
||||||
|
var returnPos = {};
|
||||||
|
returnPos.x = 0;
|
||||||
|
returnPos.y = 0;
|
||||||
|
if (node !== undefined && node !== null) {
|
||||||
|
var parentValue = getAbsolutePosition(node.parent);
|
||||||
|
returnPos.x = parentValue.x + node.x;
|
||||||
|
returnPos.y = parentValue.y + node.y;
|
||||||
|
}
|
||||||
|
return returnPos;
|
||||||
|
}
|
||||||
|
|
||||||
onPopupMenuChanged: {
|
onPopupMenuChanged: {
|
||||||
if (!!popupMenu) {
|
if (!!popupMenu) {
|
||||||
|
@ -30,75 +46,189 @@ Column {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
DelegateModel {
|
||||||
id: statusChatListItems
|
id: delegateModel
|
||||||
delegate: StatusChatListItem {
|
|
||||||
|
|
||||||
id: statusChatListItem
|
delegate: Item {
|
||||||
|
id: draggable
|
||||||
|
width: statusChatListItem.width
|
||||||
|
height: statusChatListItem.height
|
||||||
|
|
||||||
property string profileImage: ""
|
property alias chatListItem: statusChatListItem
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (typeof statusChatList.profileImageFn === "function") {
|
|
||||||
profileImage = statusChatList.profileImageFn(model.chatId || model.id) || ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chatId: model.chatId || model.id
|
|
||||||
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 || ""
|
|
||||||
|
|
||||||
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.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)
|
|
||||||
visible: {
|
visible: {
|
||||||
if (!!statusChatList.filterFn) {
|
if (!!statusChatList.filterFn) {
|
||||||
return statusChatList.filterFn(model, statusChatList.categoryId)
|
return statusChatList.filterFn(model, statusChatList.categoryId)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: dragSensor
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
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
|
||||||
|
}
|
||||||
|
onPressAndHold: active = true
|
||||||
|
onReleased: {
|
||||||
|
if (active) {
|
||||||
|
statusChatList.chatItemReordered(statusChatListItem.chatId, statusChatListItem.originalOrder, statusChatListItem.originalOrder)
|
||||||
|
}
|
||||||
|
active = false
|
||||||
|
}
|
||||||
|
onMouseYChanged: {
|
||||||
|
if ((Math.abs(startY - mouseY) > 1) && pressed) {
|
||||||
|
active = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMouseXChanged: {
|
||||||
|
if ((Math.abs(startX - mouseX) > 1) && pressed) {
|
||||||
|
active = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusChatListItem {
|
||||||
|
|
||||||
|
id: statusChatListItem
|
||||||
|
|
||||||
|
property string profileImage: ""
|
||||||
|
|
||||||
|
opacity: dragSensor.active ? 0.0 : 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
|
||||||
|
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.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: dragSensor.active ? 0 : parent.width
|
||||||
|
height: dragSensor.active ? 0 : parent.height
|
||||||
|
keys: ["chat-item-category-" + statusChatListItem.categoryId]
|
||||||
|
|
||||||
|
onEntered: reorderDelay.start()
|
||||||
|
onDropped: statusChatList.chatItemReordered(statusChatListItem.chatId, drag.source.originalOrder, statusChatListItem.DelegateModel.itemsIndex)
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: reorderDelay
|
||||||
|
interval: 100
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
if (dropArea.containsDrag) {
|
||||||
|
dropArea.drag.source.chatListItem.originalOrder = statusChatListItem.originalOrder
|
||||||
|
delegateModel.items.move(dropArea.drag.source.DelegateModel.itemsIndex, draggable.DelegateModel.itemsIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: draggedListItemLoader
|
||||||
|
active: dragSensor.active
|
||||||
|
sourceComponent: StatusChatListItem {
|
||||||
|
property var globalPosition: statusChatList.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.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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: statusChatListItems
|
||||||
|
model: delegateModel
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: popupMenuSlot
|
id: popupMenuSlot
|
||||||
active: !!statusChatList.popupMenu
|
active: !!statusChatList.popupMenu
|
||||||
|
|
|
@ -16,6 +16,7 @@ Item {
|
||||||
property alias chatList: statusChatList.chatListItems
|
property alias chatList: statusChatList.chatListItems
|
||||||
property alias categoryList: statusChatListCategories
|
property alias categoryList: statusChatListCategories
|
||||||
property alias sensor: sensor
|
property alias sensor: sensor
|
||||||
|
property bool draggableItems: false
|
||||||
|
|
||||||
property Component categoryPopupMenu
|
property Component categoryPopupMenu
|
||||||
property Component chatListPopupMenu
|
property Component chatListPopupMenu
|
||||||
|
@ -23,6 +24,7 @@ Item {
|
||||||
|
|
||||||
signal chatItemSelected(string id)
|
signal chatItemSelected(string id)
|
||||||
signal chatItemUnmuted(string id)
|
signal chatItemUnmuted(string id)
|
||||||
|
signal chatItemReordered(string categoryId, string chatId, int from, int to)
|
||||||
signal categoryAddButtonClicked(string id)
|
signal categoryAddButtonClicked(string id)
|
||||||
|
|
||||||
onPopupMenuChanged: {
|
onPopupMenuChanged: {
|
||||||
|
@ -54,14 +56,17 @@ Item {
|
||||||
StatusChatList {
|
StatusChatList {
|
||||||
id: statusChatList
|
id: statusChatList
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: !!chatListItems.model && chatListItems.count > 0
|
visible: chatListItems.count > 0
|
||||||
selectedChatId: statusChatListAndCategories.selectedChatId
|
selectedChatId: statusChatListAndCategories.selectedChatId
|
||||||
onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
|
onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
|
||||||
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
||||||
|
onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to)
|
||||||
|
draggableItems: statusChatListAndCategories.draggableItems
|
||||||
filterFn: function (model) {
|
filterFn: function (model) {
|
||||||
return !!!model.categoryId
|
return !!!model.categoryId
|
||||||
}
|
}
|
||||||
popupMenu: statusChatListAndCategories.chatListPopupMenu
|
popupMenu: statusChatListAndCategories.chatListPopupMenu
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
@ -78,6 +83,8 @@ Item {
|
||||||
chatList.selectedChatId: statusChatListAndCategories.selectedChatId
|
chatList.selectedChatId: statusChatListAndCategories.selectedChatId
|
||||||
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
|
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
|
||||||
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
|
||||||
|
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.categoryId, id, from, to)
|
||||||
|
chatList.draggableItems: statusChatListAndCategories.draggableItems
|
||||||
|
|
||||||
popupMenu: statusChatListAndCategories.categoryPopupMenu
|
popupMenu: statusChatListAndCategories.categoryPopupMenu
|
||||||
chatListPopupMenu: statusChatListAndCategories.chatListPopupMenu
|
chatListPopupMenu: statusChatListAndCategories.chatListPopupMenu
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
import QtQml.Models 2.13
|
||||||
|
import QtQuick.Controls 2.13 as QC
|
||||||
|
import QtGraphicalEffects 1.13
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
|
@ -7,7 +11,10 @@ import StatusQ.Controls 0.1
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: statusChatListItem
|
id: statusChatListItem
|
||||||
|
|
||||||
|
objectName: "chatItem"
|
||||||
|
property int originalOrder: -1
|
||||||
property string chatId: ""
|
property string chatId: ""
|
||||||
|
property string categoryId: ""
|
||||||
property string name: ""
|
property string name: ""
|
||||||
property alias badge: statusBadge
|
property alias badge: statusBadge
|
||||||
property bool hasUnreadMessages: false
|
property bool hasUnreadMessages: false
|
||||||
|
@ -20,6 +27,8 @@ Rectangle {
|
||||||
property int type: StatusChatListItem.Type.PublicChat
|
property int type: StatusChatListItem.Type.PublicChat
|
||||||
property bool highlighted: false
|
property bool highlighted: false
|
||||||
property bool selected: false
|
property bool selected: false
|
||||||
|
property bool dragged: false
|
||||||
|
property alias sensor: sensor
|
||||||
|
|
||||||
signal clicked(var mouse)
|
signal clicked(var mouse)
|
||||||
signal unmute()
|
signal unmute()
|
||||||
|
@ -46,6 +55,8 @@ Rectangle {
|
||||||
return sensor.containsMouse || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
|
return sensor.containsMouse || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opacity: dragged ? 0.7 : 1
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: sensor
|
id: sensor
|
||||||
|
|
||||||
|
@ -63,7 +74,7 @@ Rectangle {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
sourceComponent: !!statusChatListItem.image.source.toString() ?
|
sourceComponent: !!statusChatListItem.image.source.toString() ?
|
||||||
statusRoundedImageCmp : statusLetterIdenticonCmp
|
statusRoundedImageCmp : statusLetterIdenticonCmp
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -89,8 +100,8 @@ Rectangle {
|
||||||
image.source: statusChatListItem.image.source
|
image.source: statusChatListItem.image.source
|
||||||
showLoadingIndicator: true
|
showLoadingIndicator: true
|
||||||
color: statusChatListItem.image.isIdenticon ?
|
color: statusChatListItem.image.isIdenticon ?
|
||||||
Theme.palette.statusRoundedImage.backgroundColor :
|
Theme.palette.statusRoundedImage.backgroundColor :
|
||||||
"transparent"
|
"transparent"
|
||||||
border.width: statusChatListItem.image.isIdenticon ? 1 : 0
|
border.width: statusChatListItem.image.isIdenticon ? 1 : 0
|
||||||
border.color: Theme.palette.directColor7
|
border.color: Theme.palette.directColor7
|
||||||
}
|
}
|
||||||
|
@ -115,26 +126,26 @@ Rectangle {
|
||||||
return 0.4
|
return 0.4
|
||||||
}
|
}
|
||||||
return statusChatListItem.hasMention ||
|
return statusChatListItem.hasMention ||
|
||||||
statusChatListItem.hasUnreadMessages ||
|
statusChatListItem.hasUnreadMessages ||
|
||||||
statusChatListItem.selected ||
|
statusChatListItem.selected ||
|
||||||
statusChatListItem.highlighted ||
|
statusChatListItem.highlighted ||
|
||||||
statusBadge.visible ||
|
statusBadge.visible ||
|
||||||
sensor.containsMouse ? 1.0 : 0.7
|
sensor.containsMouse ? 1.0 : 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
icon: {
|
icon: {
|
||||||
switch (statusChatListItem.type) {
|
switch (statusChatListItem.type) {
|
||||||
case StatusChatListItem.Type.PublicCat:
|
case StatusChatListItem.Type.PublicCat:
|
||||||
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
|
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
|
||||||
break;
|
break;
|
||||||
case StatusChatListItem.Type.GroupChat:
|
case StatusChatListItem.Type.GroupChat:
|
||||||
return Theme.palette.name == "light" ? "tiny/group" : "tiny/group-white"
|
return Theme.palette.name == "light" ? "tiny/group" : "tiny/group-white"
|
||||||
break;
|
break;
|
||||||
case StatusChatListItem.Type.CommunityChat:
|
case StatusChatListItem.Type.CommunityChat:
|
||||||
return Theme.palette.name == "light" ? "tiny/channel" : "tiny/channel-white"
|
return Theme.palette.name == "light" ? "tiny/channel" : "tiny/channel-white"
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
|
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,30 +155,30 @@ Rectangle {
|
||||||
anchors.left: statusIcon.visible ? statusIcon.right : identicon.right
|
anchors.left: statusIcon.visible ? statusIcon.right : identicon.right
|
||||||
anchors.leftMargin: statusIcon.visible ? 1 : 8
|
anchors.leftMargin: statusIcon.visible ? 1 : 8
|
||||||
anchors.right: mutedIcon.visible ? mutedIcon.left :
|
anchors.right: mutedIcon.visible ? mutedIcon.left :
|
||||||
statusBadge.visible ? statusBadge.left : parent.right
|
statusBadge.visible ? statusBadge.left : parent.right
|
||||||
anchors.rightMargin: 6
|
anchors.rightMargin: 6
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
text: statusChatListItem.type === StatusChatListItem.Type.PublicChat &&
|
text: (statusChatListItem.type === StatusChatListItem.Type.PublicChat &&
|
||||||
!statusChatListItem.name.startsWith("#") ?
|
!statusChatListItem.name.startsWith("#") ?
|
||||||
"#" + statusChatListItem.name :
|
"#" + statusChatListItem.name :
|
||||||
statusChatListItem.name
|
statusChatListItem.name)
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
color: {
|
color: {
|
||||||
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
|
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
|
||||||
return Theme.palette.directColor5
|
return Theme.palette.directColor5
|
||||||
}
|
}
|
||||||
return statusChatListItem.hasMention ||
|
return statusChatListItem.hasMention ||
|
||||||
statusChatListItem.hasUnreadMessages ||
|
statusChatListItem.hasUnreadMessages ||
|
||||||
statusChatListItem.selected ||
|
statusChatListItem.selected ||
|
||||||
statusChatListItem.highlighted ||
|
statusChatListItem.highlighted ||
|
||||||
sensor.containsMouse ||
|
sensor.containsMouse ||
|
||||||
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
|
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
|
||||||
}
|
}
|
||||||
font.weight: !statusChatListItem.muted &&
|
font.weight: !statusChatListItem.muted &&
|
||||||
(statusChatListItem.hasMention ||
|
(statusChatListItem.hasMention ||
|
||||||
statusChatListItem.hasUnreadMessages ||
|
statusChatListItem.hasUnreadMessages ||
|
||||||
statusBadge.visible) ? Font.Bold : Font.Medium
|
statusBadge.visible) ? Font.Bold : Font.Medium
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +218,5 @@ Rectangle {
|
||||||
border.color: color
|
border.color: color
|
||||||
visible: statusBadge.value > 0
|
visible: statusBadge.value > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue