refactor(Communities): replace `CommunityMembersPopup` with `CommunityProfilePopup`

When right-clicking a community from the navbar and selecting "View community", Status Desktop
opens `CommunityMembersPopup` which looks like it was either never really finished or more of an
intermediate solution until a proper community profile popup was created.

That's why this commit replaces it with a `CommunityProfilePopup` instead.
In fact, this lead to changes in `CommunityProfilePopup` where the `activeCommunity` dependency
is entirely removed, which allows us to use this popup in various places given that it's hydrated
with proper data.

Because we're no longer relying on `activeCommunity` inside that popup, all of its children and
connected popups needed that same refactor as well, hence this PR introduces a few more changes.

Closes #2890
This commit is contained in:
Pascal Precht 2021-07-16 14:36:27 +02:00 committed by Iuri Matias
parent 9eb752885d
commit 4dab6f9239
8 changed files with 79 additions and 280 deletions

View File

@ -37,8 +37,11 @@ Item {
qsTrId("-1-members").arg(chatsModel.communities.activeCommunity.nbMembers)
chatInfoButton.image.source: chatsModel.communities.activeCommunity.thumbnailImage
chatInfoButton.icon.color: chatsModel.communities.activeCommunity.communityColor
chatInfoButton.onClicked: communityProfilePopup.open()
menuButton.visible: chatsModel.communities.activeCommunity.admin && chatsModel.communities.activeCommunity.canManageUsers
chatInfoButton.onClicked: openPopup(communityProfilePopup, {
community: chatsModel.communities.activeCommunity
})
popupMenu: StatusPopupMenu {
StatusMenuItem {
//% "Create channel"
@ -276,24 +279,6 @@ Item {
}
}
Component {
id: transferOwnershipPopup
TransferOwnershipPopup {}
}
CommunityProfilePopup {
id: communityProfilePopup
anchors.centerIn: parent
communityId: chatsModel.communities.activeCommunity.id
name: chatsModel.communities.activeCommunity.name
description: chatsModel.communities.activeCommunity.description
access: chatsModel.communities.activeCommunity.access
nbMembers: chatsModel.communities.activeCommunity.nbMembers
isAdmin: chatsModel.communities.activeCommunity.admin
source: chatsModel.communities.activeCommunity.thumbnailImage
communityColor: chatsModel.communities.activeCommunity.communityColor
}
Component {
id: deleteCategoryConfirmationDialogComponent
ConfirmationDialog {

View File

@ -68,5 +68,15 @@ Rectangle {
openPopup(transferOwnershipPopup, {privateKey: chatsModel.communities.exportComumnity()})
}
}
Component {
id: transferOwnershipPopup
TransferOwnershipPopup {
anchors.centerIn: parent
onClosed: {
destroy()
}
}
}
}

View File

@ -1,203 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "./"
import "../components"
ModalPopup {
id: popup
property QtObject community: chatsModel.communities.activeCommunity
header: Item {
height: childrenRect.height
width: parent.width
StyledText {
id: groupName
//% "Members"
text: qsTrId("members-title")
anchors.top: parent.top
anchors.topMargin: 2
anchors.left: parent.left
font.bold: true
font.pixelSize: 14
wrapMode: Text.WordWrap
}
StyledText {
id: nbMembersText
text: community.nbMembers.toString()
width: 160
anchors.left: parent.left
anchors.top: groupName.bottom
anchors.topMargin: 2
font.pixelSize: 14
color: Style.current.secondaryText
}
Separator {
anchors.top: nbMembersText.bottom
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: -Style.current.padding
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
}
}
CommunityPopupButton {
id: inviteBtn
//% "Invite People"
label: qsTrId("invite-people")
width: parent.width
iconName: "invite"
onClicked: openPopup(inviteFriendsToCommunityPopup)
}
Separator {
id: sep
anchors.left: parent.left
anchors.right: parent.right
anchors.top: inviteBtn.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
MembershipRequestsButton {
id: membershipRequestsBtn
anchors.top: sep.bottom
anchors.topMargin: visible ? Style.current.smallPadding : 0
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
Separator {
id: sep2
visible: membershipRequestsBtn.visible
anchors.left: parent.left
anchors.right: parent.right
anchors.top: membershipRequestsBtn.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
ListView {
id: memberList
anchors.top: sep2.visible ? sep2.bottom : sep.bottom
anchors.topMargin: Style.current.smallPadding
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: Style.current.halfPadding
spacing: 4
Layout.fillWidth: true
Layout.fillHeight: true
model: community.members
clip: true
delegate: Item {
id: contactRow
width: parent.width
height: identicon.height
property string nickname: appMain.getUserNickname(model.pubKey)
StatusImageIdenticon {
id: identicon
anchors.left: parent.left
source: model.identicon
}
StyledText {
text: !model.userName.endsWith(".eth") && !!contactRow.nickname ?
contactRow.nickname : Utils.removeStatusEns(model.userName)
anchors.left: identicon.right
anchors.leftMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 13
}
StyledText {
id: moreActionsBtn
text: "..."
font.letterSpacing: 0.5
font.bold: true
lineHeight: 1.4
font.pixelSize: 25
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
onClicked: contextMenu.popup(-contextMenu.width / 2 + moreActionsBtn.width / 2, moreActionsBtn.height)
cursorShape: Qt.PointingHandCursor
PopupMenu {
id: contextMenu
Action {
icon.source: "../../../img/communities/menu/view-profile.svg"
icon.width: 16
icon.height: 16
//% "View Profile"
text: qsTrId("view-profile")
onTriggered: openProfilePopup(model.userName, model.pubKey, model.identicon, '', contactRow.nickname)
}
Action {
icon.source: "../../../img/communities/menu/roles.svg"
icon.width: 16
icon.height: 16
//% "Roles"
text: qsTrId("roles")
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: console.log("TODO")
}
Separator {
visible: chatsModel.communities.activeCommunity.admin
}
Action {
icon.source: "../../../img/communities/menu/kick.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
//% "Kick"
text: qsTrId("kick")
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: chatsModel.communities.removeUserFromCommunity(model.pubKey)
}
Action {
icon.source: "../../../img/communities/menu/ban.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
//% "Ban"
text: qsTrId("ban")
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: console.log("TODO")
}
Separator {
visible: chatsModel.communities.activeCommunity.admin
}
Action {
icon.source: "../../../img/communities/menu/transfer-ownership.svg"
icon.width: 16
icon.height: 16
icon.color: Style.current.red
//% "Transfer ownership"
text: qsTrId("transfer-ownership")
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: console.log("TODO")
}
}
}
}
}
}
}

View File

@ -7,14 +7,9 @@ import StatusQ.Popups 0.1
import "../../../../imports"
StatusModal {
property string communityId: chatsModel.communities.activeCommunity.id
property string name: chatsModel.communities.activeCommunity.name
property string description: chatsModel.communities.activeCommunity.description
property int access: chatsModel.communities.activeCommunity.access
property string source: chatsModel.communities.activeCommunity.source
property string communityColor: chatsModel.communities.activeCommunity.communityColor
property int nbMembers: chatsModel.communities.activeCommunity.nbMembers
property bool isAdmin: chatsModel.communities.activeCommunity.isAdmin
property var community
id: popup
onClosed: {
@ -44,9 +39,9 @@ StatusModal {
CommunityProfilePopupOverview {
width: stack.width
headerTitle: chatsModel.communities.activeCommunity.name
headerTitle: popup.community.name
headerSubtitle: {
switch(access) {
switch(popup.community.access) {
//% "Public community"
case Constants.communityChatPublicAccess: return qsTrId("public-community");
//% "Invitation only community"
@ -57,16 +52,28 @@ StatusModal {
default: return qsTrId("unknown-community");
}
}
headerImageSource: chatsModel.communities.activeCommunity.thumbnailImage
description: chatsModel.communities.activeCommunity.description
headerImageSource: popup.community.thumbnailImage
community: popup.community
onMembersListButtonClicked: popup.contentComponent.push(membersList)
onNotificationsButtonClicked: {
chatsModel.communities.setCommunityMuted(chatsModel.communities.activeCommunity.id, checked)
chatsModel.communities.setCommunityMuted(popup.community.id, checked)
}
onEditButtonClicked: openPopup(editCommunityPopup)
onEditButtonClicked: openPopup(editCommunityPopup, {
community: popup.community
})
onTransferOwnershipButtonClicked: openPopup(transferOwnershipPopup, {privateKey: chatsModel.communities.exportComumnity()})
onLeaveButtonClicked: chatsModel.communities.leaveCommunity(communityId)
onLeaveButtonClicked: chatsModel.communities.leaveCommunity(popup.community.id)
}
}
Component {
id: transferOwnershipPopup
TransferOwnershipPopup {
anchors.centerIn: parent
onClosed: {
destroy()
}
}
}
@ -74,10 +81,9 @@ StatusModal {
id: membersList
CommunityProfilePopupMembersList {
width: stack.width
//% "Members"
headerTitle: qsTrId("members-label")
headerSubtitle: popup.nbMembers.toString()
members: chatsModel.communities.activeCommunity.members
headerTitle: qsTr("Members")
headerSubtitle: popup.community.nbMembers.toString()
community: popup.community
onInviteButtonClicked: popup.contentComponent.push(inviteFriendsView)
}
}
@ -86,8 +92,8 @@ StatusModal {
id: inviteFriendsView
CommunityProfilePopupInviteFriendsView {
width: stack.width
//% "Invite friends"
headerTitle: qsTrId("invite-friends")
headerTitle: qsTr("Invite friends")
community: popup.community
contactListSearch.chatKey.text: ""
contactListSearch.pubKey: ""

View File

@ -15,10 +15,11 @@ Column {
property string headerTitle: ""
property var community
property alias contactListSearch: contactFieldAndList
function sendInvites(pubKeys) {
const error = chatsModel.communities.inviteUsersToCommunityById(popup.communityId, JSON.stringify(pubKeys))
const error = chatsModel.communities.inviteUsersToCommunityById(root.community.id, JSON.stringify(pubKeys))
if (error) {
console.error('Error inviting', error)
contactFieldAndList.validationError = error
@ -29,14 +30,12 @@ Column {
}
StatusDescriptionListItem {
//% "Share community"
title: qsTrId("share-community")
subTitle: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
//% "Copy to clipboard"
tooltip.text: qsTrId("copy-to-clipboard")
title: qsTr("Share community")
subTitle: `${Constants.communityLinkPrefix}${root.community.id.substring(0, 4)}...${root.community.id.substring(root.community.id.length -2)}`
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let link = `${Constants.communityLinkPrefix}${communityId}`
let link = `${Constants.communityLinkPrefix}${root.community.id}`
chatsModel.copyToClipboard(link)
tooltip.visible = !tooltip.visible
}

View File

@ -20,6 +20,7 @@ Item {
property string headerSubtitle: ""
property string headerImageSource: ""
property alias members: memberList.model
property var community
signal inviteButtonClicked()
@ -43,9 +44,8 @@ Item {
StatusListItem {
id: inviteButton
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
//% "Invite People"
title: qsTrId("invite-people")
visible: root.community.admin || root.community.isAdmin
title: qsTr("Invite People")
icon.name: "share-ios"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.inviteButtonClicked()
@ -61,9 +61,9 @@ Item {
id: memberRequestsButton
property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests
property int nbRequests: root.community.communityMembershipRequests.nbRequests
width: parent.width - 32
visible: isAdmin && nbRequests > 0
visible: (root.community.isAdmin || root.community.admin) && nbRequests > 0
anchors.horizontalCenter: parent.horizontalCenter
//% "Membership requests"
@ -124,6 +124,7 @@ Item {
Repeater {
id: memberList
model: root.community.members
delegate: StatusListItem {
id: memberItem
@ -177,7 +178,7 @@ Item {
}
StatusMenuSeparator {
visible: chatsModel.communities.activeCommunity.admin
visible: root.community.admin
}
StatusMenuItem {
@ -186,7 +187,7 @@ Item {
icon.name: "arrow-right"
iconRotation: 180
type: StatusMenuItem.Type.Danger
enabled: chatsModel.communities.activeCommunity.admin
enabled: root.community.admin
onTriggered: chatsModel.communities.removeUserFromCommunity(model.pubKey)
}
@ -195,8 +196,8 @@ Item {
text: qsTrId("ban")
icon.name: "cancel"
type: StatusMenuItem.Type.Danger
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: chatsModel.communities.banUserFromCommunity(model.pubKey, chatsModel.communities.activeCommunity.id)
enabled: root.community.admin
onTriggered: chatsModel.communities.banUserFromCommunity(model.pubKey, root.community.id)
}
}
}

View File

@ -15,7 +15,7 @@ Column {
property string headerTitle: ""
property string headerSubtitle: ""
property string headerImageSource: ""
property string description: ""
property var community
signal membersListButtonClicked()
signal notificationsButtonClicked(bool checked)
@ -33,7 +33,7 @@ Column {
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
text: root.description
text: root.community.description
font.pixelSize: 15
color: Theme.palette.directColor1
wrapMode: Text.Wrap
@ -46,14 +46,12 @@ Column {
}
StatusDescriptionListItem {
//% "Share community"
title: qsTrId("share-community")
subTitle: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
//% "Copy to clipboard"
tooltip.text: qsTrId("copy-to-clipboard")
title: qsTr("Share community")
subTitle: `${Constants.communityLinkPrefix}${root.community.id.substring(0, 4)}...${root.community.id.substring(root.community.id.length -2)}`
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let link = `${Constants.communityLinkPrefix}${communityId}`
let link = `${Constants.communityLinkPrefix}${root.community.id}`
chatsModel.copyToClipboard(link)
tooltip.visible = !tooltip.visible
}
@ -69,12 +67,12 @@ Column {
id: membersListItem
anchors.horizontalCenter: parent.horizontalCenter
property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests
property int nbRequests: root.community.communityMembershipRequests.nbRequests
//% "Members"
title: qsTrId("members-label")
icon.name: "group-chat"
label: nbMembers.toString()
label: root.community.nbMembers.toString()
sensor.onClicked: root.membersListButtonClicked()
components: [
@ -97,7 +95,7 @@ Column {
icon.name: "notification"
components: [
StatusSwitch {
checked: !chatsModel.communities.activeCommunity.muted
checked: !root.community.muted
onClicked: root.notificationsButtonClicked(checked)
}
]
@ -110,9 +108,8 @@ Column {
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
//% "Edit community"
title: qsTrId("edit-community")
visible: root.community.isAdmin || root.community.admin
title: qsTr("Edit community")
icon.name: "edit"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.editButtonClicked()
@ -120,9 +117,8 @@ Column {
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
//% "Transfer ownership"
title: qsTrId("transfer-ownership")
visible: root.community.isAdmin || root.community.admin
title: qsTr("Transfer ownership")
icon.name: "exchange"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.transferOwnershipButtonClicked()
@ -143,7 +139,7 @@ Column {
//% "Roles"
/* // TODO add this back when roles exist */
/* // Loader { */
/* // active: isAdmin */
/* // active: root.community.isAdmin */
/* // width: parent.width */
/* // sourceComponent: CommunityPopupButton { */
/* // label: qsTrId("community-roles") */

View File

@ -170,7 +170,9 @@ StatusAppLayout {
//% "View Community"
text: qsTrId("view-community")
icon.name: "group-chat"
onTriggered: openPopup(communityMembersPopup, {community: chatsModel.communities.observedCommunity})
onTriggered: openPopup(communityProfilePopup, {
community: chatsModel.communities.observedCommunity
})
}
StatusMenuItem {
@ -512,9 +514,12 @@ StatusAppLayout {
}
Component {
id: communityMembersPopup
CommunityMembersPopup {
id: communityProfilePopup
CommunityProfilePopup {
id: communityProfilePopup
anchors.centerIn: parent
onClosed: {
destroy()
}