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

View File

@ -1,47 +1,107 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import AppLayouts.Chat.panels 1.0
import StatusQ 0.1
import Storybook 1.0
import Models 1.0
import SortFilterProxyModel 0.2
import utils 1.0
SplitView {
Logs { id: logs }
orientation: Qt.Vertical
UsersModel {
id: model
}
UserListPanel {
Pane {
SplitView.fillWidth: true
SplitView.fillHeight: true
label: "Some label"
padding: 100
usersModel: SortFilterProxyModel {
sourceModel: model
Rectangle {
anchors.fill: parent
anchors.margins: -1
color: "transparent"
border.color: "black"
}
proxyRoles: FastExpressionRole {
name: "compressedKey"
expression: "compressed"
}
UserListPanel {
anchors.fill: parent
usersModel: UsersModel {}
label: labelTextField.text
isAdmin: isAdminCheckBox.checked
chatType: chatTypeSelector.currentValue
communityMemberReevaluationStatus:
communityMemberReevaluationStatusSelector.currentValue
}
}
LogsAndControlsPanel {
id: logsAndControlsPanel
Pane {
SplitView.minimumHeight: 100
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
// status: good

View File

@ -1,117 +1,133 @@
import QtQuick 2.15
ListModel {
id: root
import utils 1.0
ListElement {
pubKey: "0x043a7ed0e8d1012cf04"
onlineStatus: 1
isContact: true
isVerified: false
isAdmin: false
isUntrustworthy: true
displayName: "Mike has a very long name that should elide eventually and result in a tooltip displayed instead"
alias: ""
localNickname: ""
ensName: ""
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
colorId: 7
isEnsVerified: false
colorHash: [
ListElement {colorId: 0; segmentLength: 2},
ListElement {colorId: 17; segmentLength: 2}
]
isAwaitingAddress: false
memberRole: 0 // Constants.memberRole.none
}
ListElement {
pubKey: "0x04df12f12f12f12f1234"
onlineStatus: 0
isContact: false
isVerified: false
isAdmin: false
isUntrustworthy: false
displayName: "Jane"
alias: ""
localNickname: ""
ensName: ""
icon: ""
colorId: 9
isEnsVerified: false
colorHash: [
ListElement {colorId: 0; segmentLength: 1},
ListElement {colorId: 19; segmentLength: 2}
]
isAwaitingAddress: false
memberRole: 1 // Constants.memberRole.owner
}
ListElement {
pubKey: "0x04d1b7cc0ef3f470f1238"
onlineStatus: 0
isContact: false
isVerified: false
isAdmin: false
isUntrustworthy: true
displayName: "John"
alias: ""
localNickname: "Johnny Johny"
ensName: ""
icon: "https://cryptologos.cc/logos/status-snt-logo.svg?v=033"
colorId: 4
isEnsVerified: false
isAwaitingAddress: false
memberRole: 0
}
ListElement {
pubKey: "0x04d1bed192343f470f1257"
onlineStatus: 1
isContact: true
isVerified: true
isAdmin: false
isUntrustworthy: true
displayName: "Maria"
alias: "meth"
localNickname: "86.eth"
ensName: "8⃣6⃣.eth"
icon: ""
colorId: 5
isEnsVerified: true
isAwaitingAddress: false
memberRole: 0
}
ListElement {
pubKey: "0x04d1bed192343f470f1255"
onlineStatus: 1
isContact: true
isVerified: true
isAdmin: true
isUntrustworthy: true
displayName: ""
alias: "Richard The Lionheart"
localNickname: ""
ensName: "richard-the-lionheart.eth"
icon: ""
colorId: 3
isEnsVerified: true
isAwaitingAddress: false
memberRole: 0
}
ListElement {
pubKey: "0x04d1bed192343f470fabc"
onlineStatus: 0
isContact: true
isVerified: false
isAdmin: false
isUntrustworthy: false
displayName: ""
alias: ""
localNickname: ""
ensName: "8⃣6⃣.eth"
icon: ""
colorId: 7
isEnsVerified: true
isAwaitingAddress: true
memberRole: 0
}
ListModel {
readonly property var data: [
{
pubKey: "0x043a7ed0e8d1012cf04",
compressedPubKey: "zQ3shQBu4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
onlineStatus: Constants.onlineStatus.online,
isContact: true,
isVerified: false,
isAdmin: false,
isUntrustworthy: true,
displayName: "Mike has a very long name that should elide " +
"eventually and result in a tooltip displayed instead",
alias: "",
localNickname: "",
ensName: "",
icon: ModelsData.icons.cryptPunks,
colorId: 7,
isEnsVerified: false,
colorHash: [
{ colorId: 0, segmentLength: 2 },
{ colorId: 17, segmentLength: 2}
],
isAwaitingAddress: false,
memberRole: Constants.memberRole.none,
trustStatus: Constants.trustStatus.untrustworthy
},
{
pubKey: "0x04df12f12f12f12f1234",
compressedPubKey: "zQ3shQBAAPRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
onlineStatus: Constants.onlineStatus.inactive,
isContact: false,
isVerified: false,
isAdmin: false,
isUntrustworthy: false,
displayName: "Jane",
alias: "",
localNickname: "",
ensName: "",
icon: "",
colorId: 9,
isEnsVerified: false,
colorHash: [
{ colorId: 0, segmentLength: 1 },
{ colorId: 19, segmentLength: 2 }
],
isAwaitingAddress: false,
memberRole: Constants.memberRole.owner,
trustStatus: Constants.trustStatus.trusted
},
{
pubKey: "0x04d1b7cc0ef3f470f1238",
compressedPubKey: "zQ3shQ7u3PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsCDF4",
onlineStatus: Constants.onlineStatus.inactive,
isContact: false,
isVerified: false,
isAdmin: false,
isUntrustworthy: true,
displayName: "John",
alias: "",
localNickname: "Johnny Johny",
ensName: "",
icon: ModelsData.icons.dragonereum,
colorId: 4,
isEnsVerified: false,
isAwaitingAddress: false,
memberRole: Constants.memberRole.none,
trustStatus: Constants.trustStatus.untrustworthy
},
{
pubKey: "0x04d1bed192343f470f1257",
compressedPubKey: "zQ3shQAL4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsBDF4",
onlineStatus: Constants.onlineStatus.online,
isContact: true,
isVerified: true,
isAdmin: false,
isUntrustworthy: true,
displayName: "Maria",
alias: "meth",
localNickname: "86.eth",
ensName: "8⃣_6⃣.eth",
icon: "",
colorId: 5,
isEnsVerified: true,
isAwaitingAddress: false,
memberRole: Constants.memberRole.none,
trustStatus: Constants.trustStatus.untrustworthy
},
{
pubKey: "0x04d1bed192343f470f1255",
compressedPubKey: "zQ3shQBu4PGDX17vewYyvSczbTj344viTXxcMNvQLeyQsBD1A",
onlineStatus: Constants.onlineStatus.online,
isContact: true,
isVerified: true,
isAdmin: true,
isUntrustworthy: true,
displayName: "",
alias: "Richard The Lionheart",
localNickname: "",
ensName: "richard-the-lionheart.eth",
icon: "",
colorId: 3,
isEnsVerified: true,
isAwaitingAddress: false,
memberRole: Constants.memberRole.none,
trustStatus: Constants.trustStatus.untrustworthy
},
{
pubKey: "0x04d1bed192343f470fabc",
compressedPubKey: "zQ3shQBk4PRDX17vewYyvSczbTj344viTXxcMNvQLeyQsB994",
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.Layouts 1.15
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 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 utils 1.0
import SortFilterProxyModel 0.2
import AppLayouts.Chat.stores 1.0 as ChatStores
Item {
id: root
property ChatStores.RootStore store
property var usersModel
property string label
property int chatType: Constants.chatType.unknown
property bool isAdmin
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 {
id: titleText
anchors.top: parent.top
anchors.topMargin: Theme.padding
anchors.left: parent.left
anchors.leftMargin: Theme.padding
anchors.right: parent.right
anchors.rightMargin: Theme.padding
opacity: (root.width > 58) ? 1.0 : 0.0
visible: (opacity > 0.1)
font.pixelSize: Theme.primaryTextFontSize
font.weight: Font.Medium
color: Theme.palette.directColor1
text: root.label
wrapMode: Text.Wrap
}
StatusBaseText {
@ -108,6 +121,7 @@ Item {
section.delegate: (root.width > 58) ? sectionDelegateComponent : null
delegate: StatusMemberListItem {
width: ListView.view.width
nickName: model.localNickname
userName: ProfileUtils.displayName("", model.ensName, model.displayName, model.alias)
pubKey: model.isEnsVerified ? "" : model.compressedPubKey
@ -125,9 +139,6 @@ Item {
const profileType = Utils.getProfileType(model.isCurrentUser, false, model.isBlocked)
const contactType = Utils.getContactType(model.contactRequest, model.isContact)
const chatType = chatContentModule.chatDetails.type
const isAdmin = chatContentModule.amIChatAdmin()
const params = {
profileType, contactType, chatType, isAdmin,
pubKey: model.pubKey,
@ -140,7 +151,9 @@ Item {
trustStatus: model.trustStatus,
onlineStatus: model.onlineStatus,
ensVerified: model.isEnsVerified,
hasLocalNickname: !!model.localNickname
hasLocalNickname: !!model.localNickname,
chatType: root.chatType,
isAdmin: root.isAdmin
}
Global.openMenu(profileContextMenuComponent, this, params)
@ -154,9 +167,11 @@ Item {
Component {
id: sectionDelegateComponent
Item {
width: ListView.view.width
height: 24
StatusBaseText {
anchors.fill: parent
anchors.leftMargin: Theme.padding
@ -184,25 +199,20 @@ Item {
property string pubKey
margins: 8
onOpenProfileClicked: Global.openProfilePopup(profileContextMenu.pubKey, null)
onCreateOneToOneChat: {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.store.chatCommunitySectionModule.createOneToOneChat("", profileContextMenu.pubKey, "")
}
onReviewContactRequest: Global.openReviewContactRequestPopup(profileContextMenu.pubKey, null)
onSendContactRequest: Global.openContactRequestPopup(profileContextMenu.pubKey, null)
onEditNickname: Global.openNicknamePopupRequested(profileContextMenu.pubKey, null)
onRemoveNickname: (displayName) => {
root.store.contactsStore.changeContactNickname(profileContextMenu.pubKey, "", displayName, true)
}
onUnblockContact: Global.unblockContactRequested(profileContextMenu.pubKey)
onMarkAsUntrusted: Global.markAsUntrustedRequested(profileContextMenu.pubKey)
onRemoveTrustStatus: root.store.contactsStore.removeTrustStatus(profileContextMenu.pubKey)
onRemoveContact: Global.removeContactRequested(profileContextMenu.pubKey)
onBlockContact: Global.blockContactRequested(profileContextMenu.pubKey)
onRemoveFromGroup: {
root.store.removeMemberFromGroupChat(profileContextMenu.pubKey)
}
onOpenProfileClicked: root.openProfileRequested(pubKey)
onCreateOneToOneChat: root.createOneToOneChatRequested(pubKey)
onReviewContactRequest: root.reviewContactRequestRequested(pubKey)
onSendContactRequest: root.sendContactRequestRequested(pubKey)
onEditNickname: root.editNicknameRequested(pubKey)
onRemoveNickname: root.removeNicknameRequested(pubKey)
onUnblockContact: root.unblockContactRequested(pubKey)
onMarkAsUntrusted: root.markAsUntrustedRequested(pubKey)
onRemoveTrustStatus: root.removeTrustStatusRequested(pubKey)
onRemoveContact: root.removeContactRequested(pubKey)
onBlockContact: root.blockContactRequested(pubKey)
onRemoveFromGroup: root.removeContactFromGroupRequested(pubKey)
onClosed: destroy()
}
}

View File

@ -1,5 +1,7 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Qt.labs.settings 1.0
import utils 1.0
@ -13,15 +15,12 @@ import shared.stores.send 1.0 as SendStores
import SortFilterProxyModel 0.2
import StatusQ 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Layout 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.panels 1.0
@ -33,9 +32,10 @@ import AppLayouts.Wallet.stores 1.0 as WalletStore
import AppLayouts.Chat.stores 1.0 as ChatStores
import "../popups"
import "../helpers"
import "../controls"
import "../helpers"
import "../panels"
import "../popups"
StatusSectionLayout {
id: root
@ -183,7 +183,10 @@ StatusSectionLayout {
}
anchors.fill: parent
store: root.rootStore
chatType: root.chatContentModule.chatDetails.type
isAdmin: root.chatContentModule.amIChatAdmin()
label: qsTr("Members")
communityMemberReevaluationStatus: root.rootStore.communityMemberReevaluationStatus
@ -196,6 +199,28 @@ StatusSectionLayout {
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)
}
}