From 209a20845597ed547e91f49e767d35aa0626a97e Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Tue, 15 Jun 2021 16:27:39 +0200 Subject: [PATCH] feat(Components): introduce `StatusChatListAndCategories` component This is a wrapping component that can be used to render community chat lists and categories. It takes care of rendering categories, the top chat list, as well as becominng scrollable in case the content outgrows the available space. Usage: ```qml import StatusQ.Components 0.1 StatusChatListAndCategories { chatList.model: ... // non-categorized chat items, pass all chat items here, the component will take care of filtering categorized items out categoryListModel: ... // available categories (need to have `id` and `name`) selectedChatId: ... showCategoryActionButtons: true // default `false` - useful when only admin users can create and mutate categories/channels onChatItemSelected: ... // `id` is available for selected chat id categoryPopupMenu: StatusPopupMenu { // optional popup menu for category items property string categoryId // define this property to have it hydrated with correct id and make it available inside menu items ... } popupMenu: StatusPopupMenu { ... } // optional popup menu for whole list, will be triggered with right-click } ``` Closes #133 --- ui/StatusQ/sandbox/DemoApp.qml | 118 +++++++++++------- .../StatusChatListAndCategories.qml | 88 +++++++++++++ ui/StatusQ/src/StatusQ/Components/qmldir | 1 + ui/StatusQ/statusq.qrc | 1 + 4 files changed, 163 insertions(+), 45 deletions(-) create mode 100644 ui/StatusQ/src/StatusQ/Components/StatusChatListAndCategories.qml diff --git a/ui/StatusQ/sandbox/DemoApp.qml b/ui/StatusQ/sandbox/DemoApp.qml index ed67c219c0..2f4cce4479 100644 --- a/ui/StatusQ/sandbox/DemoApp.qml +++ b/ui/StatusQ/sandbox/DemoApp.qml @@ -157,23 +157,18 @@ Rectangle { StatusAppTwoPanelLayout { - leftPanel: Item { + leftPanel: StatusChatListAndCategories { anchors.fill: parent + anchors.topMargin: 64 - StatusChatList { - anchors.top: parent.top - anchors.topMargin: 64 - anchors.horizontalCenter: parent.horizontalCenter - - selectedChatId: "0" - chatListItems.model: demoChatListItems - onChatItemSelected: selectedChatId = id - onChatItemUnmuted: { - for (var i = 0; i < demoChatListItems.count; i++) { - let item = demoChatListItems.get(i); - if (item.chatId === id) { - demoChatListItems.setProperty(i, "muted", false) - } + chatList.model: demoChatListItems + selectedChatId: "0" + onChatItemSelected: selectedChatId = id + onChatItemUnmuted: { + for (var i = 0; i < demoChatListItems.count; i++) { + let item = demoChatListItems.get(i); + if (item.chatId === id) { + demoChatListItems.setProperty(i, "muted", false) } } } @@ -233,10 +228,16 @@ Rectangle { StatusAppTwoPanelLayout { + + + leftPanel: Item { anchors.fill: parent StatusChatInfoToolBar { + id: statusChatInfoToolBar + anchors.top: parent.top + chatInfoButton.title: "Cryptokitties" chatInfoButton.subTitle: "128 Members" chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" @@ -265,41 +266,22 @@ Rectangle { } } - Column { - anchors.top: parent.top - anchors.topMargin: 64 - anchors.horizontalCenter: parent.horizontalCenter - spacing: 4 + StatusChatListAndCategories { + anchors.top: statusChatInfoToolBar.bottom + anchors.topMargin: 8 + anchors.bottom: parent.bottom + width: parent.width - StatusChatList { - id: statusChatList - anchors.horizontalCenter: parent.horizontalCenter - chatListItems.model: demoCommunityChatListItems - } + chatList.model: demoCommunityChatListItems + categoryList.model: demoCommunityCategoryItems - StatusChatListCategory { - name: "Public" - showActionButtons: true - chatList.chatListItems.model: demoCommunityChatListItems - chatList.selectedChatId: "0" - chatList.onChatItemSelected: chatList.selectedChatId = id - popupMenu: categoryPopupCmp - } + showCategoryActionButtons: true + onChatItemSelected: selectedChatId = id - StatusChatListCategory { - name: "Development" + categoryPopupMenu: StatusPopupMenu { - showActionButtons: true - chatList.chatListItems.model: demoCommunityChatListItems - chatList.onChatItemSelected: chatList.selectedChatId = id - popupMenu: categoryPopupCmp - } - } + property string categoryId - Component { - id: categoryPopupCmp - - StatusPopupMenu { StatusMenuItem { text: "Mute Category" icon.name: "notification" @@ -323,8 +305,29 @@ Rectangle { type: StatusMenuItem.Type.Danger } } + + + popupMenu: StatusPopupMenu { + StatusMenuItem { + text: "Create channel" + icon.name: "channel" + } + + StatusMenuItem { + text: "Create category" + icon.name: "channel-category" + } + + StatusMenuSeparator {} + + StatusMenuItem { + text: "Invite people" + icon.name: "share-ios" + } + } } } + rightPanel: Item { anchors.fill: parent @@ -413,6 +416,7 @@ Rectangle { hasMention: false unreadMessagesCount: 0 iconColor: "orange" + categoryId: "public" } ListElement { chatId: "2" @@ -423,6 +427,30 @@ Rectangle { hasMention: false unreadMessagesCount: 0 iconColor: "orange" + categoryId: "public" + } + ListElement { + chatId: "3" + name: "language-design" + chatType: StatusChatListItem.Type.CommunityChat + muted: false + hasUnreadMessages: false + hasMention: false + unreadMessagesCount: 0 + iconColor: "orange" + categoryId: "dev" + } + } + + ListModel { + id: demoCommunityCategoryItems + ListElement { + categoryId: "public" + name: "Public" + } + ListElement { + categoryId: "dev" + name: "Development" } } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusChatListAndCategories.qml b/ui/StatusQ/src/StatusQ/Components/StatusChatListAndCategories.qml new file mode 100644 index 0000000000..d0e18fa965 --- /dev/null +++ b/ui/StatusQ/src/StatusQ/Components/StatusChatListAndCategories.qml @@ -0,0 +1,88 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 + +import StatusQ.Components 0.1 +import StatusQ.Popups 0.1 + +ScrollView { + id: statusChatListAndCategories + + clip: true + contentHeight: chatListsAndCategories.height + 8 + + property string selectedChatId: "" + property bool showCategoryActionButtons: false + property alias chatList: statusChatList.chatListItems + property alias categoryList: statusChatListCategories + property alias sensor: sensor + + property Component categoryPopupMenu + property Component popupMenu + + signal chatItemSelected(string id) + signal chatItemUnmuted(string id) + signal categoryAddButtonClicked(string id) + + onPopupMenuChanged: { + if (!!popupMenu) { + popupMenuSlot.sourceComponent = popupMenu + } + } + + MouseArea { + id: sensor + anchors.top: parent.top + width: parent.width + height: statusChatListAndCategories.height + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.RightButton && !!statusChatListAndCategories.popupMenu) { + popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6) + return + } + } + + Column { + id: chatListsAndCategories + + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + spacing: 4 + + StatusChatList { + id: statusChatList + anchors.horizontalCenter: parent.horizontalCenter + visible: !!chatListItems.model && chatListItems.model.count > 0 + selectedChatId: statusChatListAndCategories.selectedChatId + onChatItemSelected: statusChatListAndCategories.chatItemSelected(id) + onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id) + filterFn: function (model) { + return !!!model.categoryId + } + } + + Repeater { + id: statusChatListCategories + visible: !!model && model.count > 0 + + delegate: StatusChatListCategory { + categoryId: model.categoryId + name: model.name + showActionButtons: statusChatListAndCategories.showCategoryActionButtons + addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.categoryId) + + chatList.chatListItems.model: statusChatListAndCategories.chatList.model + chatList.selectedChatId: statusChatListAndCategories.selectedChatId + chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id) + + popupMenu: statusChatListAndCategories.categoryPopupMenu + } + } + } + } + + Loader { + id: popupMenuSlot + active: !!statusChatListAndCategories.popupMenu + } +} diff --git a/ui/StatusQ/src/StatusQ/Components/qmldir b/ui/StatusQ/src/StatusQ/Components/qmldir index 82b0ce7d67..097ceae00b 100644 --- a/ui/StatusQ/src/StatusQ/Components/qmldir +++ b/ui/StatusQ/src/StatusQ/Components/qmldir @@ -6,6 +6,7 @@ StatusChatList 0.1 StatusChatList.qml StatusChatListItem 0.1 StatusChatListItem.qml StatusChatListCategory 0.1 StatusChatListCategory.qml StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml +StatusChatListAndCategories 0.1 StatusChatListAndCategories.qml StatusChatToolBar 0.1 StatusChatToolBar.qml StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml diff --git a/ui/StatusQ/statusq.qrc b/ui/StatusQ/statusq.qrc index 2c376731a4..4504e6f1ae 100644 --- a/ui/StatusQ/statusq.qrc +++ b/ui/StatusQ/statusq.qrc @@ -18,6 +18,7 @@ src/StatusQ/Popups/StatusMenuItem.qml src/StatusQ/Components/qmldir src/StatusQ/Components/StatusChatListItem.qml + src/StatusQ/Components/StatusChatListAndCategories.qml src/StatusQ/Components/StatusChatInfoToolBar.qml src/StatusQ/Components/StatusNavigationListItem.qml src/StatusQ/Components/StatusChatToolBar.qml