fix: the member search is adding empty spaces on the search results

Also fix other smaller issues found in this panel:
- display correct user name (not just `model.displayName`)
- do not display tooltips for invisible buttons
- vertically center the action buttons
- use `SearchBox` for consistency

Fixes #11848
This commit is contained in:
Lukáš Tinkl 2023-08-17 10:55:28 +02:00 committed by Lukáš Tinkl
parent 4d770e6a7f
commit 5b2a7b9264
4 changed files with 91 additions and 35 deletions

View File

@ -333,14 +333,14 @@ SplitView {
CheckBox { CheckBox {
id: transferibleChecker id: transferibleChecker
text: "Tranferible" text: "Tranferable"
checked: true checked: true
} }
CheckBox { CheckBox {
id: selfdestructChecker id: selfdestructChecker
text: "Remote self-desctruct" text: "Remote self-destruct"
checked: true checked: true
} }
} }

View File

@ -12,38 +12,78 @@ import Models 1.0
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import Storybook 1.0 import Storybook 1.0
import StatusQ.Core.Utils 0.1 as SQUtils
SplitView { SplitView {
id: root id: root
orientation: Qt.Vertical orientation: Qt.Vertical
Logs { id: logs } Logs { id: logs }
// Utils.globalUtilsInst mock
QtObject {
function getEmojiHashAsJson(publicKey) {
return JSON.stringify(["👨🏻‍🍼", "🏃🏿‍♂️", "🌇", "🤶🏿", "🏮","🤷🏻‍♂️", "🤦🏻", "📣", "🤎", "👷🏽", "😺", "🥞", "🔃", "🧝🏽‍♂️"])
}
function getColorId(publicKey) {
return SQUtils.ModelUtils.getByKey(usersModel, "pubKey", publicKey, "colorId")
}
function getCompressedPk(publicKey) { return "zx3sh" + publicKey }
function getColorHashAsJson(publicKey) {
return JSON.stringify([{colorId: 0, segmentLength: 1},
{colorId: 19, segmentLength: 2}])
}
function isCompressedPubKey(publicKey) { return true }
Component.onCompleted: {
Utils.globalUtilsInst = this
}
Component.onDestruction: {
Utils.globalUtilsInst = {}
}
}
// Global.userProfile mock
QtObject {
readonly property string pubKey: "0x043a7ed0e8d1012cf04" // Mike from UsersModel
Component.onCompleted: {
Global.userProfile = this
}
Component.onDestruction: {
Utils.userProfile = {}
}
}
MembersTabPanel { MembersTabPanel {
id: membersTabPanelPage id: membersTabPanelPage
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.fillHeight: true SplitView.fillHeight: true
placeholderText: "Placeholder text" placeholderText: "Search users"
model: usersModelWithMembershipState model: usersModelWithMembershipState
panelType: viewStateSelector.currentValue panelType: viewStateSelector.currentValue
onKickUserClicked: { onKickUserClicked: {
logs.logEvent("MembersTabPanel::onKickUserClicked") logs.logEvent("MembersTabPanel::onKickUserClicked", ["id", "name"], arguments)
} }
onBanUserClicked: { onBanUserClicked: {
logs.logEvent("MembersTabPanel::onBanUserClicked") logs.logEvent("MembersTabPanel::onBanUserClicked", ["id", "name"], arguments)
} }
onUnbanUserClicked: { onUnbanUserClicked: {
logs.logEvent("MembersTabPanel::onUnbanUserClicked") logs.logEvent("MembersTabPanel::onUnbanUserClicked", ["id"], arguments)
} }
onAcceptRequestToJoin: { onAcceptRequestToJoin: {
logs.logEvent("MembersTabPanel::onAcceptRequestToJoin") logs.logEvent("MembersTabPanel::onAcceptRequestToJoin", ["id"], arguments)
} }
onDeclineRequestToJoin: { onDeclineRequestToJoin: {
logs.logEvent("MembersTabPanel::onDeclineRequestToJoin") logs.logEvent("MembersTabPanel::onDeclineRequestToJoin", ["id"], arguments)
} }
} }
@ -51,7 +91,6 @@ SplitView {
id: usersModel id: usersModel
} }
SortFilterProxyModel { SortFilterProxyModel {
id: usersModelWithMembershipState id: usersModelWithMembershipState
readonly property var membershipStatePerView: [ readonly property var membershipStatePerView: [
@ -106,7 +145,6 @@ SplitView {
} }
} }
} }
} }
Settings { Settings {

View File

@ -7,9 +7,9 @@ ListModel {
pubKey: "0x043a7ed0e8d1012cf04" pubKey: "0x043a7ed0e8d1012cf04"
onlineStatus: 1 onlineStatus: 1
isContact: true isContact: true
isVerified: true isVerified: false
isAdmin: false isAdmin: false
isUntrustworthy: false isUntrustworthy: true
displayName: "Mike" displayName: "Mike"
alias: "" alias: ""
localNickname: "" localNickname: ""
@ -17,12 +17,13 @@ ListModel {
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
colorId: 7 colorId: 7
isEnsVerified: false
} }
ListElement { ListElement {
pubKey: "0x04df12f12f12f12f1234" pubKey: "0x04df12f12f12f12f1234"
onlineStatus: 0 onlineStatus: 0
isContact: true isContact: false
isVerified: true isVerified: false
isAdmin: false isAdmin: false
isUntrustworthy: false isUntrustworthy: false
displayName: "Jane" displayName: "Jane"
@ -30,24 +31,26 @@ ListModel {
localNickname: "" localNickname: ""
ensName: "" ensName: ""
icon: "" icon: ""
colorId: 7 colorId: 9
isEnsVerified: false
} }
ListElement { ListElement {
pubKey: "0x04d1b7cc0ef3f470f1238" pubKey: "0x04d1b7cc0ef3f470f1238"
onlineStatus: 0 onlineStatus: 0
isContact: true isContact: false
isVerified: false isVerified: false
isAdmin: false isAdmin: false
isUntrustworthy: true isUntrustworthy: true
displayName: "John" displayName: "John"
alias: "" alias: ""
localNickname: "Johny Johny" localNickname: "Johnny Johny"
ensName: "" ensName: ""
icon: "" icon: ""
colorId: 7 colorId: 4
isEnsVerified: false
} }
ListElement { ListElement {
pubKey: "0x04d1bed192343f470f1255" pubKey: "0x04d1bed192343f470f1257"
onlineStatus: 1 onlineStatus: 1
isContact: true isContact: true
isVerified: true isVerified: true
@ -58,6 +61,22 @@ ListModel {
localNickname: "" localNickname: ""
ensName: "maria.eth" ensName: "maria.eth"
icon: "" icon: ""
colorId: 7 colorId: 5
isEnsVerified: true
}
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
} }
} }

View File

@ -42,20 +42,15 @@ Item {
anchors.fill: parent anchors.fill: parent
spacing: 30 spacing: 30
StatusInput { SearchBox {
id: memberSearch id: memberSearch
Layout.preferredWidth: 400 Layout.preferredWidth: 400
Layout.leftMargin: 12 Layout.leftMargin: 12
maximumHeight: 36
topPadding: 0
bottomPadding: 0
rightPadding: 0
placeholderText: root.placeholderText placeholderText: root.placeholderText
input.asset.name: "search"
enabled: !!model && model.count > 0 enabled: !!model && model.count > 0
} }
ListView { StatusListView {
id: membersList id: membersList
objectName: "CommunityMembersTabPanel_MembersListViews" objectName: "CommunityMembersTabPanel_MembersListViews"
@ -63,13 +58,12 @@ Item {
Layout.fillHeight: true Layout.fillHeight: true
model: root.model model: root.model
clip: true spacing: 0
spacing: 15
delegate: StatusMemberListItem { delegate: StatusMemberListItem {
id: memberItem id: memberItem
readonly property bool itsMe: model.pubKey.toLowerCase() === userProfile.pubKey.toLowerCase() readonly property bool itsMe: model.pubKey.toLowerCase() === Global.userProfile.pubKey.toLowerCase()
readonly property bool isHovered: memberItem.sensor.containsMouse readonly property bool isHovered: memberItem.sensor.containsMouse
readonly property bool canBeBanned: !memberItem.itsMe && (model.memberRole !== Constants.memberRole.owner && model.memberRole !== Constants.memberRole.admin) readonly property bool canBeBanned: !memberItem.itsMe && (model.memberRole !== Constants.memberRole.owner && model.memberRole !== Constants.memberRole.admin)
readonly property bool canEnableKickBanButtons: canBeBanned && root.panelType === MembersTabPanel.TabType.AllMembers readonly property bool canEnableKickBanButtons: canBeBanned && root.panelType === MembersTabPanel.TabType.AllMembers
@ -91,6 +85,7 @@ Item {
components: [ components: [
DisabledTooltipButton { DisabledTooltipButton {
id: kickButton id: kickButton
anchors.verticalCenter: parent.verticalCenter
visible: kickVisible visible: kickVisible
interactive: kickEnabled interactive: kickEnabled
tooltipText: qsTr("Waiting for owner node to come online") tooltipText: qsTr("Waiting for owner node to come online")
@ -99,27 +94,29 @@ Item {
text: model.membershipRequestState === Constants.CommunityMembershipRequestState.KickedPending ? qsTr("Kick pending") : qsTr("Kick") text: model.membershipRequestState === Constants.CommunityMembershipRequestState.KickedPending ? qsTr("Kick pending") : qsTr("Kick")
type: StatusBaseButton.Type.Danger type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small size: StatusBaseButton.Size.Small
onClicked: root.kickUserClicked(model.pubKey, model.displayName) onClicked: root.kickUserClicked(model.pubKey, memberItem.title)
enabled: kickButton.interactive enabled: kickButton.interactive
} }
}, },
DisabledTooltipButton { DisabledTooltipButton {
id: banButton id: banButton
anchors.verticalCenter: parent.verticalCenter
//using opacity instead of visible to avoid the acceptButton jumping around //using opacity instead of visible to avoid the acceptButton jumping around
opacity: banVisible opacity: banVisible
interactive: banEnabled interactive: banEnabled
tooltipText: qsTr("Waiting for owner node to come online") tooltipText: banVisible ? qsTr("Waiting for owner node to come online") : ""
buttonComponent: StatusButton { buttonComponent: StatusButton {
text: model.membershipRequestState === Constants.CommunityMembershipRequestState.BannedPending || !banVisible ? qsTr("Ban pending") : qsTr("Ban") text: model.membershipRequestState === Constants.CommunityMembershipRequestState.BannedPending || !banVisible ? qsTr("Ban pending") : qsTr("Ban")
type: StatusBaseButton.Type.Danger type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small size: StatusBaseButton.Size.Small
onClicked: root.banUserClicked(model.pubKey, model.displayName) onClicked: root.banUserClicked(model.pubKey, memberItem.title)
enabled: banButton.interactive enabled: banButton.interactive
} }
}, },
StatusButton { StatusButton {
anchors.verticalCenter: parent.verticalCenter
visible: unBanVisible visible: unBanVisible
text: qsTr("Unban") text: qsTr("Unban")
onClicked: root.unbanUserClicked(model.pubKey) onClicked: root.unbanUserClicked(model.pubKey)
@ -127,6 +124,7 @@ Item {
DisabledTooltipButton { DisabledTooltipButton {
id: acceptButton id: acceptButton
anchors.verticalCenter: parent.verticalCenter
visible: ((root.panelType === MembersTabPanel.TabType.PendingRequests || visible: ((root.panelType === MembersTabPanel.TabType.PendingRequests ||
root.panelType === MembersTabPanel.TabType.DeclinedRequests) && isHovered) || root.panelType === MembersTabPanel.TabType.DeclinedRequests) && isHovered) ||
isAcceptedPending isAcceptedPending
@ -149,6 +147,7 @@ Item {
DisabledTooltipButton { DisabledTooltipButton {
id: rejectButton id: rejectButton
anchors.verticalCenter: parent.verticalCenter
//using opacity instead of visible to avoid the acceptButton jumping around //using opacity instead of visible to avoid the acceptButton jumping around
opacity: ((root.panelType === MembersTabPanel.TabType.PendingRequests) && isHovered) || isRejectedPending opacity: ((root.panelType === MembersTabPanel.TabType.PendingRequests) && isHovered) || isRejectedPending
//TODO: Only the current user can reject a pending request, so we should check that here //TODO: Only the current user can reject a pending request, so we should check that here
@ -188,7 +187,7 @@ Item {
if(mouse.button === Qt.RightButton) { if(mouse.button === Qt.RightButton) {
Global.openMenu(memberContextMenuComponent, this, { Global.openMenu(memberContextMenuComponent, this, {
selectedUserPublicKey: model.pubKey, selectedUserPublicKey: model.pubKey,
selectedUserDisplayName: userName, selectedUserDisplayName: memberItem.title,
selectedUserIcon: asset.name, selectedUserIcon: asset.name,
}) })
} else { } else {
@ -205,7 +204,7 @@ Item {
ProfileContextMenu { ProfileContextMenu {
id: memberContextMenuView id: memberContextMenuView
store: root.rootStore store: root.rootStore
myPublicKey: userProfile.pubKey myPublicKey: Global.userProfile.pubKey
onOpenProfileClicked: { onOpenProfileClicked: {
Global.openProfilePopup(publicKey, null) Global.openProfilePopup(publicKey, null)