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
This commit is contained in:
parent
4577551873
commit
7bca27455f
|
@ -157,16 +157,12 @@ Rectangle {
|
||||||
|
|
||||||
StatusAppTwoPanelLayout {
|
StatusAppTwoPanelLayout {
|
||||||
|
|
||||||
leftPanel: Item {
|
leftPanel: StatusChatListAndCategories {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
StatusChatList {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 64
|
anchors.topMargin: 64
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
|
chatList.model: demoChatListItems
|
||||||
selectedChatId: "0"
|
selectedChatId: "0"
|
||||||
chatListItems.model: demoChatListItems
|
|
||||||
onChatItemSelected: selectedChatId = id
|
onChatItemSelected: selectedChatId = id
|
||||||
onChatItemUnmuted: {
|
onChatItemUnmuted: {
|
||||||
for (var i = 0; i < demoChatListItems.count; i++) {
|
for (var i = 0; i < demoChatListItems.count; i++) {
|
||||||
|
@ -177,7 +173,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rightPanel: Item {
|
rightPanel: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -233,10 +228,16 @@ Rectangle {
|
||||||
|
|
||||||
StatusAppTwoPanelLayout {
|
StatusAppTwoPanelLayout {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
leftPanel: Item {
|
leftPanel: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
StatusChatInfoToolBar {
|
StatusChatInfoToolBar {
|
||||||
|
id: statusChatInfoToolBar
|
||||||
|
anchors.top: parent.top
|
||||||
|
|
||||||
chatInfoButton.title: "Cryptokitties"
|
chatInfoButton.title: "Cryptokitties"
|
||||||
chatInfoButton.subTitle: "128 Members"
|
chatInfoButton.subTitle: "128 Members"
|
||||||
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||||
|
@ -265,41 +266,22 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
StatusChatListAndCategories {
|
||||||
anchors.top: parent.top
|
anchors.top: statusChatInfoToolBar.bottom
|
||||||
anchors.topMargin: 64
|
anchors.topMargin: 8
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.bottom: parent.bottom
|
||||||
spacing: 4
|
width: parent.width
|
||||||
|
|
||||||
StatusChatList {
|
chatList.model: demoCommunityChatListItems
|
||||||
id: statusChatList
|
categoryList.model: demoCommunityCategoryItems
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
chatListItems.model: demoCommunityChatListItems
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusChatListCategory {
|
showCategoryActionButtons: true
|
||||||
name: "Public"
|
onChatItemSelected: selectedChatId = id
|
||||||
showActionButtons: true
|
|
||||||
chatList.chatListItems.model: demoCommunityChatListItems
|
|
||||||
chatList.selectedChatId: "0"
|
|
||||||
chatList.onChatItemSelected: chatList.selectedChatId = id
|
|
||||||
popupMenu: categoryPopupCmp
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusChatListCategory {
|
categoryPopupMenu: StatusPopupMenu {
|
||||||
name: "Development"
|
|
||||||
|
|
||||||
showActionButtons: true
|
property string categoryId
|
||||||
chatList.chatListItems.model: demoCommunityChatListItems
|
|
||||||
chatList.onChatItemSelected: chatList.selectedChatId = id
|
|
||||||
popupMenu: categoryPopupCmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: categoryPopupCmp
|
|
||||||
|
|
||||||
StatusPopupMenu {
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: "Mute Category"
|
text: "Mute Category"
|
||||||
icon.name: "notification"
|
icon.name: "notification"
|
||||||
|
@ -323,8 +305,29 @@ Rectangle {
|
||||||
type: StatusMenuItem.Type.Danger
|
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 {
|
rightPanel: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
@ -413,6 +416,7 @@ Rectangle {
|
||||||
hasMention: false
|
hasMention: false
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
iconColor: "orange"
|
iconColor: "orange"
|
||||||
|
categoryId: "public"
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
chatId: "2"
|
chatId: "2"
|
||||||
|
@ -423,6 +427,30 @@ Rectangle {
|
||||||
hasMention: false
|
hasMention: false
|
||||||
unreadMessagesCount: 0
|
unreadMessagesCount: 0
|
||||||
iconColor: "orange"
|
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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ StatusChatList 0.1 StatusChatList.qml
|
||||||
StatusChatListItem 0.1 StatusChatListItem.qml
|
StatusChatListItem 0.1 StatusChatListItem.qml
|
||||||
StatusChatListCategory 0.1 StatusChatListCategory.qml
|
StatusChatListCategory 0.1 StatusChatListCategory.qml
|
||||||
StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml
|
StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml
|
||||||
|
StatusChatListAndCategories 0.1 StatusChatListAndCategories.qml
|
||||||
StatusChatToolBar 0.1 StatusChatToolBar.qml
|
StatusChatToolBar 0.1 StatusChatToolBar.qml
|
||||||
StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml
|
StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml
|
||||||
StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
|
StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<file>src/StatusQ/Popups/StatusMenuItem.qml</file>
|
<file>src/StatusQ/Popups/StatusMenuItem.qml</file>
|
||||||
<file>src/StatusQ/Components/qmldir</file>
|
<file>src/StatusQ/Components/qmldir</file>
|
||||||
<file>src/StatusQ/Components/StatusChatListItem.qml</file>
|
<file>src/StatusQ/Components/StatusChatListItem.qml</file>
|
||||||
|
<file>src/StatusQ/Components/StatusChatListAndCategories.qml</file>
|
||||||
<file>src/StatusQ/Components/StatusChatInfoToolBar.qml</file>
|
<file>src/StatusQ/Components/StatusChatInfoToolBar.qml</file>
|
||||||
<file>src/StatusQ/Components/StatusNavigationListItem.qml</file>
|
<file>src/StatusQ/Components/StatusNavigationListItem.qml</file>
|
||||||
<file>src/StatusQ/Components/StatusChatToolBar.qml</file>
|
<file>src/StatusQ/Components/StatusChatToolBar.qml</file>
|
||||||
|
|
Loading…
Reference in New Issue