UserListPanel made store-independent, Storybook page fully operable

Closes: #16717
This commit is contained in:
Michał Cieślak 2024-11-07 22:52:46 +01:00 committed by Michał
parent 74113cbbe1
commit 32c1d174ad
5 changed files with 287 additions and 179 deletions

View File

@ -153,7 +153,6 @@ SplitView {
{ text: "Trusted", value: Constants.trustStatus.trusted }, { text: "Trusted", value: Constants.trustStatus.trusted },
{ text: "Untrusted", value: Constants.trustStatus.untrustworthy } { text: "Untrusted", value: Constants.trustStatus.untrustworthy }
] ]
currentIndex: 0
} }
} }
@ -176,7 +175,6 @@ SplitView {
{ text: "Contact Request Received", value: Constants.contactType.contactRequestReceived }, { text: "Contact Request Received", value: Constants.contactType.contactRequestReceived },
{ text: "Contact Request Sent", value: Constants.contactType.contactRequestSent } { text: "Contact Request Sent", value: Constants.contactType.contactRequestSent }
] ]
currentIndex: 0
} }
} }
@ -223,7 +221,6 @@ SplitView {
{ text: "Profile", value: Constants.chatType.profile }, { text: "Profile", value: Constants.chatType.profile },
{ text: "Community Chat", value: Constants.chatType.communityChat } { text: "Community Chat", value: Constants.chatType.communityChat }
] ]
currentIndex: 0
} }
} }

View File

@ -1,47 +1,107 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import AppLayouts.Chat.panels 1.0 import AppLayouts.Chat.panels 1.0
import StatusQ 0.1
import Storybook 1.0
import Models 1.0 import Models 1.0
import SortFilterProxyModel 0.2 import utils 1.0
SplitView { SplitView {
Logs { id: logs }
orientation: Qt.Vertical orientation: Qt.Vertical
UsersModel { Pane {
id: model
}
UserListPanel {
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.fillHeight: true SplitView.fillHeight: true
label: "Some label" padding: 100
usersModel: SortFilterProxyModel { Rectangle {
sourceModel: model anchors.fill: parent
anchors.margins: -1
color: "transparent"
border.color: "black"
}
proxyRoles: FastExpressionRole { UserListPanel {
name: "compressedKey" anchors.fill: parent
expression: "compressed"
} usersModel: UsersModel {}
label: labelTextField.text
isAdmin: isAdminCheckBox.checked
chatType: chatTypeSelector.currentValue
communityMemberReevaluationStatus:
communityMemberReevaluationStatusSelector.currentValue
} }
} }
LogsAndControlsPanel { Pane {
id: logsAndControlsPanel
SplitView.minimumHeight: 100 SplitView.minimumHeight: 100
SplitView.preferredHeight: 200 SplitView.preferredHeight: 200
logsView.logText: logs.logText ColumnLayout {
RowLayout {
Label {
text: "Label:"
}
TextField {
id: labelTextField
text: "Some label here"
}
}
CheckBox {
id: isAdminCheckBox
text: "Is admin (allows to remove used from private group chat)"
}
RowLayout {
Label {
text: "Chat Type:"
}
ComboBox {
id: chatTypeSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Unknown", value: Constants.chatType.unknown },
{ text: "Category", value: Constants.chatType.category },
{ text: "One-to-One", value: Constants.chatType.oneToOne },
{ text: "Public Chat", value: Constants.chatType.publicChat },
{ text: "Private Group Chat", value: Constants.chatType.privateGroupChat },
{ text: "Profile", value: Constants.chatType.profile },
{ text: "Community Chat", value: Constants.chatType.communityChat }
]
}
}
RowLayout {
Label {
text: "Community member reevaluation status:"
}
ComboBox {
id: communityMemberReevaluationStatusSelector
textRole: "text"
valueRole: "value"
model: [
{ text: "Unknown", value: Constants.CommunityMemberReevaluationStatus.None },
{ text: "InProgress", value: Constants.CommunityMemberReevaluationStatus.InProgress },
{ text: "Done", value: Constants.CommunityMemberReevaluationStatus.Done }
]
}
}
}
} }
} }
// category: Panels // category: Panels
// status: good

View File

@ -1,117 +1,133 @@
import QtQuick 2.15 import QtQuick 2.15
ListModel { import utils 1.0
id: root
ListElement { ListModel {
pubKey: "0x043a7ed0e8d1012cf04" readonly property var data: [
onlineStatus: 1 {
isContact: true pubKey: "0x043a7ed0e8d1012cf04",
isVerified: false compressedPubKey: "zQ3shQBu4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
isAdmin: false onlineStatus: Constants.onlineStatus.online,
isUntrustworthy: true isContact: true,
displayName: "Mike has a very long name that should elide eventually and result in a tooltip displayed instead" isVerified: false,
alias: "" isAdmin: false,
localNickname: "" isUntrustworthy: true,
ensName: "" displayName: "Mike has a very long name that should elide " +
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ "eventually and result in a tooltip displayed instead",
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" alias: "",
colorId: 7 localNickname: "",
isEnsVerified: false ensName: "",
colorHash: [ icon: ModelsData.icons.cryptPunks,
ListElement {colorId: 0; segmentLength: 2}, colorId: 7,
ListElement {colorId: 17; segmentLength: 2} isEnsVerified: false,
] colorHash: [
isAwaitingAddress: false { colorId: 0, segmentLength: 2 },
memberRole: 0 // Constants.memberRole.none { colorId: 17, segmentLength: 2}
} ],
ListElement { isAwaitingAddress: false,
pubKey: "0x04df12f12f12f12f1234" memberRole: Constants.memberRole.none,
onlineStatus: 0 trustStatus: Constants.trustStatus.untrustworthy
isContact: false },
isVerified: false {
isAdmin: false pubKey: "0x04df12f12f12f12f1234",
isUntrustworthy: false compressedPubKey: "zQ3shQBAAPRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
displayName: "Jane" onlineStatus: Constants.onlineStatus.inactive,
alias: "" isContact: false,
localNickname: "" isVerified: false,
ensName: "" isAdmin: false,
icon: "" isUntrustworthy: false,
colorId: 9 displayName: "Jane",
isEnsVerified: false alias: "",
colorHash: [ localNickname: "",
ListElement {colorId: 0; segmentLength: 1}, ensName: "",
ListElement {colorId: 19; segmentLength: 2} icon: "",
] colorId: 9,
isAwaitingAddress: false isEnsVerified: false,
memberRole: 1 // Constants.memberRole.owner colorHash: [
} { colorId: 0, segmentLength: 1 },
ListElement { { colorId: 19, segmentLength: 2 }
pubKey: "0x04d1b7cc0ef3f470f1238" ],
onlineStatus: 0 isAwaitingAddress: false,
isContact: false memberRole: Constants.memberRole.owner,
isVerified: false trustStatus: Constants.trustStatus.trusted
isAdmin: false },
isUntrustworthy: true {
displayName: "John" pubKey: "0x04d1b7cc0ef3f470f1238",
alias: "" compressedPubKey: "zQ3shQ7u3PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsCDF4",
localNickname: "Johnny Johny" onlineStatus: Constants.onlineStatus.inactive,
ensName: "" isContact: false,
icon: "https://cryptologos.cc/logos/status-snt-logo.svg?v=033" isVerified: false,
colorId: 4 isAdmin: false,
isEnsVerified: false isUntrustworthy: true,
isAwaitingAddress: false displayName: "John",
memberRole: 0 alias: "",
} localNickname: "Johnny Johny",
ListElement { ensName: "",
pubKey: "0x04d1bed192343f470f1257" icon: ModelsData.icons.dragonereum,
onlineStatus: 1 colorId: 4,
isContact: true isEnsVerified: false,
isVerified: true isAwaitingAddress: false,
isAdmin: false memberRole: Constants.memberRole.none,
isUntrustworthy: true trustStatus: Constants.trustStatus.untrustworthy
displayName: "Maria" },
alias: "meth" {
localNickname: "86.eth" pubKey: "0x04d1bed192343f470f1257",
ensName: "8⃣6⃣.eth" compressedPubKey: "zQ3shQAL4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
icon: "" onlineStatus: Constants.onlineStatus.online,
colorId: 5 isContact: true,
isEnsVerified: true isVerified: true,
isAwaitingAddress: false isAdmin: false,
memberRole: 0 isUntrustworthy: true,
} displayName: "Maria",
ListElement { alias: "meth",
pubKey: "0x04d1bed192343f470f1255" localNickname: "86.eth",
onlineStatus: 1 ensName: "8⃣_6⃣.eth",
isContact: true icon: "",
isVerified: true colorId: 5,
isAdmin: true isEnsVerified: true,
isUntrustworthy: true isAwaitingAddress: false,
displayName: "" memberRole: Constants.memberRole.none,
alias: "Richard The Lionheart" trustStatus: Constants.trustStatus.untrustworthy
localNickname: "" },
ensName: "richard-the-lionheart.eth" {
icon: "" pubKey: "0x04d1bed192343f470f1255",
colorId: 3 compressedPubKey: "zQ3shQBu4PGDX17vewYyvSczbTj344viTXxcMNvQLeyQsBD1A",
isEnsVerified: true onlineStatus: Constants.onlineStatus.online,
isAwaitingAddress: false isContact: true,
memberRole: 0 isVerified: true,
} isAdmin: true,
ListElement { isUntrustworthy: true,
pubKey: "0x04d1bed192343f470fabc" displayName: "",
onlineStatus: 0 alias: "Richard The Lionheart",
isContact: true localNickname: "",
isVerified: false ensName: "richard-the-lionheart.eth",
isAdmin: false icon: "",
isUntrustworthy: false colorId: 3,
displayName: "" isEnsVerified: true,
alias: "" isAwaitingAddress: false,
localNickname: "" memberRole: Constants.memberRole.none,
ensName: "8⃣6⃣.eth" trustStatus: Constants.trustStatus.untrustworthy
icon: "" },
colorId: 7 {
isEnsVerified: true pubKey: "0x04d1bed192343f470fabc",
isAwaitingAddress: true compressedPubKey: "zQ3shQBk4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsB994",
memberRole: 0 onlineStatus: Constants.onlineStatus.inactive,
} isContact: true,
isVerified: false,
isAdmin: false,
isUntrustworthy: false,
displayName: "",
alias: "",
localNickname: "",
ensName: "8⃣6⃣.sth.eth",
icon: "",
colorId: 7,
isEnsVerified: true,
isAwaitingAddress: true,
memberRole: Constants.memberRole.none,
trustStatus: Constants.trustStatus.trusted
}
]
Component.onCompleted: append(data)
} }

View File

@ -2,44 +2,57 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import StatusQ 0.1
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
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import shared.views.chat 1.0 import shared.views.chat 1.0
import utils 1.0 import utils 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import AppLayouts.Chat.stores 1.0 as ChatStores
Item { Item {
id: root id: root
property ChatStores.RootStore store
property var usersModel property var usersModel
property string label property string label
property int chatType: Constants.chatType.unknown
property bool isAdmin
property int communityMemberReevaluationStatus: Constants.CommunityMemberReevaluationStatus.None property int communityMemberReevaluationStatus: Constants.CommunityMemberReevaluationStatus.None
signal openProfileRequested(string pubKey)
signal createOneToOneChatRequested(string pubKey)
signal reviewContactRequestRequested(string pubKey)
signal sendContactRequestRequested(string pubKey)
signal editNicknameRequested(string pubKey)
signal removeNicknameRequested(string pubKey)
signal blockContactRequested(string pubKey)
signal unblockContactRequested(string pubKey)
signal markAsUntrustedRequested(string pubKey)
signal removeTrustStatusRequested(string pubKey)
signal removeContactRequested(string pubKey)
signal removeContactFromGroupRequested(string pubKey)
StatusBaseText { StatusBaseText {
id: titleText id: titleText
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: Theme.padding anchors.topMargin: Theme.padding
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.padding anchors.leftMargin: Theme.padding
anchors.right: parent.right
anchors.rightMargin: Theme.padding
opacity: (root.width > 58) ? 1.0 : 0.0 opacity: (root.width > 58) ? 1.0 : 0.0
visible: (opacity > 0.1) visible: (opacity > 0.1)
font.pixelSize: Theme.primaryTextFontSize font.pixelSize: Theme.primaryTextFontSize
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.palette.directColor1 color: Theme.palette.directColor1
text: root.label text: root.label
wrapMode: Text.Wrap
} }
StatusBaseText { StatusBaseText {
@ -108,6 +121,7 @@ Item {
section.delegate: (root.width > 58) ? sectionDelegateComponent : null section.delegate: (root.width > 58) ? sectionDelegateComponent : null
delegate: StatusMemberListItem { delegate: StatusMemberListItem {
width: ListView.view.width width: ListView.view.width
nickName: model.localNickname nickName: model.localNickname
userName: ProfileUtils.displayName("", model.ensName, model.displayName, model.alias) userName: ProfileUtils.displayName("", model.ensName, model.displayName, model.alias)
pubKey: model.isEnsVerified ? "" : model.compressedPubKey pubKey: model.isEnsVerified ? "" : model.compressedPubKey
@ -125,9 +139,6 @@ Item {
const profileType = Utils.getProfileType(model.isCurrentUser, false, model.isBlocked) const profileType = Utils.getProfileType(model.isCurrentUser, false, model.isBlocked)
const contactType = Utils.getContactType(model.contactRequest, model.isContact) const contactType = Utils.getContactType(model.contactRequest, model.isContact)
const chatType = chatContentModule.chatDetails.type
const isAdmin = chatContentModule.amIChatAdmin()
const params = { const params = {
profileType, contactType, chatType, isAdmin, profileType, contactType, chatType, isAdmin,
pubKey: model.pubKey, pubKey: model.pubKey,
@ -140,7 +151,9 @@ Item {
trustStatus: model.trustStatus, trustStatus: model.trustStatus,
onlineStatus: model.onlineStatus, onlineStatus: model.onlineStatus,
ensVerified: model.isEnsVerified, ensVerified: model.isEnsVerified,
hasLocalNickname: !!model.localNickname hasLocalNickname: !!model.localNickname,
chatType: root.chatType,
isAdmin: root.isAdmin
} }
Global.openMenu(profileContextMenuComponent, this, params) Global.openMenu(profileContextMenuComponent, this, params)
@ -154,9 +167,11 @@ Item {
Component { Component {
id: sectionDelegateComponent id: sectionDelegateComponent
Item { Item {
width: ListView.view.width width: ListView.view.width
height: 24 height: 24
StatusBaseText { StatusBaseText {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Theme.padding anchors.leftMargin: Theme.padding
@ -184,25 +199,20 @@ Item {
property string pubKey property string pubKey
margins: 8 margins: 8
onOpenProfileClicked: Global.openProfilePopup(profileContextMenu.pubKey, null)
onCreateOneToOneChat: { onOpenProfileClicked: root.openProfileRequested(pubKey)
Global.changeAppSectionBySectionType(Constants.appSection.chat) onCreateOneToOneChat: root.createOneToOneChatRequested(pubKey)
root.store.chatCommunitySectionModule.createOneToOneChat("", profileContextMenu.pubKey, "") onReviewContactRequest: root.reviewContactRequestRequested(pubKey)
} onSendContactRequest: root.sendContactRequestRequested(pubKey)
onReviewContactRequest: Global.openReviewContactRequestPopup(profileContextMenu.pubKey, null) onEditNickname: root.editNicknameRequested(pubKey)
onSendContactRequest: Global.openContactRequestPopup(profileContextMenu.pubKey, null) onRemoveNickname: root.removeNicknameRequested(pubKey)
onEditNickname: Global.openNicknamePopupRequested(profileContextMenu.pubKey, null) onUnblockContact: root.unblockContactRequested(pubKey)
onRemoveNickname: (displayName) => { onMarkAsUntrusted: root.markAsUntrustedRequested(pubKey)
root.store.contactsStore.changeContactNickname(profileContextMenu.pubKey, "", displayName, true) onRemoveTrustStatus: root.removeTrustStatusRequested(pubKey)
} onRemoveContact: root.removeContactRequested(pubKey)
onUnblockContact: Global.unblockContactRequested(profileContextMenu.pubKey) onBlockContact: root.blockContactRequested(pubKey)
onMarkAsUntrusted: Global.markAsUntrustedRequested(profileContextMenu.pubKey) onRemoveFromGroup: root.removeContactFromGroupRequested(pubKey)
onRemoveTrustStatus: root.store.contactsStore.removeTrustStatus(profileContextMenu.pubKey)
onRemoveContact: Global.removeContactRequested(profileContextMenu.pubKey)
onBlockContact: Global.blockContactRequested(profileContextMenu.pubKey)
onRemoveFromGroup: {
root.store.removeMemberFromGroupChat(profileContextMenu.pubKey)
}
onClosed: destroy() onClosed: destroy()
} }
} }

View File

@ -1,5 +1,7 @@
import QtQuick 2.13 import QtQuick 2.15
import QtQuick.Controls 2.13 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Qt.labs.settings 1.0 import Qt.labs.settings 1.0
import utils 1.0 import utils 1.0
@ -13,15 +15,12 @@ import shared.stores.send 1.0 as SendStores
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import StatusQ 0.1 import StatusQ 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Layout 0.1 import StatusQ.Layout 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Controls 0.1
import QtQuick.Layouts 1.15
import "."
import "../panels"
import AppLayouts.Communities.controls 1.0 import AppLayouts.Communities.controls 1.0
import AppLayouts.Communities.panels 1.0 import AppLayouts.Communities.panels 1.0
@ -33,9 +32,10 @@ import AppLayouts.Wallet.stores 1.0 as WalletStore
import AppLayouts.Chat.stores 1.0 as ChatStores import AppLayouts.Chat.stores 1.0 as ChatStores
import "../popups"
import "../helpers"
import "../controls" import "../controls"
import "../helpers"
import "../panels"
import "../popups"
StatusSectionLayout { StatusSectionLayout {
id: root id: root
@ -183,7 +183,10 @@ StatusSectionLayout {
} }
anchors.fill: parent anchors.fill: parent
store: root.rootStore
chatType: root.chatContentModule.chatDetails.type
isAdmin: root.chatContentModule.amIChatAdmin()
label: qsTr("Members") label: qsTr("Members")
communityMemberReevaluationStatus: root.rootStore.communityMemberReevaluationStatus communityMemberReevaluationStatus: root.rootStore.communityMemberReevaluationStatus
@ -196,6 +199,28 @@ StatusSectionLayout {
expectedRoles: ["pubKey"] expectedRoles: ["pubKey"]
} }
} }
onOpenProfileRequested: Global.openProfilePopup(pubKey, null)
onReviewContactRequestRequested: Global.openReviewContactRequestPopup(pubKey, null)
onSendContactRequestRequested: Global.openContactRequestPopup(pubKey, null)
onEditNicknameRequested: Global.openNicknamePopupRequested(pubKey, null)
onBlockContactRequested: Global.blockContactRequested(pubKey)
onUnblockContactRequested: Global.unblockContactRequested(pubKey)
onMarkAsUntrustedRequested: Global.markAsUntrustedRequested(pubKey)
onRemoveContactRequested: Global.removeContactRequested(pubKey)
onRemoveNicknameRequested: {
const oldName = ModelUtils.getByKey(usersModel, "pubKey", pubKey, "localNickname")
root.contactsStore.changeContactNickname(pubKey, "", oldName, true)
}
onCreateOneToOneChatRequested: {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.rootStore.chatCommunitySectionModule.createOneToOneChat("", profileContextMenu.pubKey, "")
}
onRemoveTrustStatusRequested: root.contactsStore.removeTrustStatus(pubKey)
onRemoveContactFromGroupRequested: root.rootStore.removeMemberFromGroupChat(pubKey)
} }
} }