fix: community context menu should not say "Leave community" if not joined

- differentiate between "Close" and "Leave" a community where the former
applies to spectated communities
- move the "leave community" confirmation popup to a shared place
(Popups.qml), extend it with the outro message and reuse it everywhere
- don't let admins leave a community
- some minor cleanups and dead code removals

Fixes #10963
This commit is contained in:
Lukáš Tinkl 2023-06-14 10:42:52 +02:00 committed by Lukáš Tinkl
parent 60d14180cf
commit 7bf7f272f3
10 changed files with 115 additions and 133 deletions

View File

@ -42,6 +42,7 @@ StackLayout {
id: joinCommunityView
readonly property var communityData: sectionItemModel
name: communityData.name
introMessage: communityData.introMessage
communityDesc: communityData.description
color: communityData.color
image: communityData.image
@ -62,13 +63,19 @@ StackLayout {
loginType: root.rootStore.loginType
onNotificationButtonClicked: Global.openActivityCenterPopup()
onAdHocChatButtonClicked: rootStore.openCloseCreateChatView()
onRevealAddressClicked: {
communityIntroDialog.open()
}
onRevealAddressClicked: openJoinCommunityDialog()
onInvitationPendingClicked: {
root.rootStore.cancelPendingRequest(communityData.id)
joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
}
onJoined: {
root.rootStore.requestToJoinCommunityWithAuthentication(communityData.id, root.rootStore.userProfileInst.name)
}
onCancelMembershipRequest: {
root.rootStore.cancelPendingRequest(communityData.id)
joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
}
Connections {
target: root.rootStore.communitiesModuleInst
@ -78,28 +85,7 @@ StackLayout {
}
}
}
CommunityIntroDialog {
id: communityIntroDialog
isInvitationPending: joinCommunityView.isInvitationPending
name: communityData.name
introMessage: communityData.introMessage
imageSrc: communityData.image
accessType: communityData.access
onJoined: {
root.rootStore.requestToJoinCommunityWithAuthentication(communityData.id, root.rootStore.userProfileInst.name)
}
onCancelMembershipRequest: {
root.rootStore.cancelPendingRequest(communityData.id)
joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
}
}
}
}
Component {

View File

@ -73,8 +73,9 @@ Column {
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: qsTr("Leave community")
asset.name: "arrow-left"
visible: !root.community.amISectionAdmin
title: root.community.spectated ? qsTr("Close Community") : qsTr("Leave Community")
asset.name: root.community.spectated ? "close-circle" : "arrow-left"
type: StatusListItem.Type.Danger
onClicked: root.leaveButtonClicked()
}

View File

@ -64,8 +64,9 @@ StatusModal {
store: root.store
})
onLeaveButtonClicked: {
communitySectionModule.leaveCommunity();
root.close();
root.community.spectated ? communitySectionModule.leaveCommunity()
: Global.leaveCommunityRequested(root.community.name, root.community.id, root.community.outroMessage)
}
onCopyToClipboard: {
root.store.copyToClipboard(link);
@ -79,17 +80,6 @@ StatusModal {
destroyOnClose: true
}
}
Component {
id: inviteFriendsView
CommunityProfilePopupInviteFriendsPanel {
width: stack.width
headerTitle: qsTr("Invite friends")
community: root.community
contactsStore: root.contactsStore
rootStore: root.store
}
}
}
leftButtons: [
@ -102,18 +92,4 @@ StatusModal {
}
}
]
rightButtons: [
StatusButton {
text: qsTr("Invite")
visible: root.contentItem.depth > 2
height: !visible ? 0 : implicitHeight
enabled: root.contentItem.currentItem !== undefined && root.contentItem.currentItem.pubKeys.length > 0
onClicked: {
root.contentItem.currentItem.sendInvites(root.contentItem.currentItem.pubKeys, "") // NOTE: empty message
root.contentItem.pop()
}
}
]
}

View File

@ -112,6 +112,7 @@ Item {
root.store.cancelPendingRequest(communityData.id)
joinCommunityButton.invitationPending = root.store.isCommunityRequestPending(communityData.id)
}
onClosed: destroy()
}
}
}

View File

@ -172,9 +172,9 @@ QtObject {
readonly property Connections connections: Connections {
target: communitiesModuleInst
function onImportingCommunityStateChanged(communityId, state, errorMsg) {
root.importingCommunityStateChanged(communityId, state, errorMsg)
}
target: communitiesModuleInst
function onImportingCommunityStateChanged(communityId, state, errorMsg) {
root.importingCommunityStateChanged(communityId, state, errorMsg)
}
}
}

View File

@ -15,7 +15,8 @@ StatusListView {
property bool hasAddedContacts: false
signal inviteFriends(var communityData)
signal leaveCommunityClicked(string communityId)
signal closeCommunityClicked(string communityId)
signal leaveCommunityClicked(string community, string communityId, string outroMessage)
signal setCommunityMutedClicked(string communityId, bool muted)
signal setActiveCommunityClicked(string communityId)
@ -43,17 +44,14 @@ StatusListView {
components: [
StatusFlatButton {
anchors.verticalCenter: parent.verticalCenter
objectName: "CommunitiesListPanel_leaveCommunityPopupButton"
size: StatusBaseButton.Size.Small
type: StatusBaseButton.Type.Danger
borderColor: "transparent"
text: qsTr("Leave Community")
onClicked: {
Global.openPopup(leaveCommunityPopup, {
community: model.name,
communityId: model.id
})
}
enabled: !model.amISectionAdmin
text: model.spectated ? qsTr("Close Community") : qsTr("Leave Community")
onClicked: model.spectated ? root.closeCommunityClicked(model.id) : root.leaveCommunityClicked(model.name, model.id, model.outroMessage)
},
StatusFlatButton {
anchors.verticalCenter: parent.verticalCenter
@ -68,46 +66,5 @@ StatusListView {
onClicked: root.inviteFriends(model)
}
]
} // StatusListItem
property Component leaveCommunityPopup: StatusModal {
id: leavePopup
property string community: ""
property string communityId: ""
anchors.centerIn: parent
headerSettings.title: qsTr("Leave %1").arg(community)
contentItem: Item {
implicitWidth: 368
implicitHeight: msg.implicitHeight + 32
StatusBaseText {
id: msg
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: 16
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: qsTr("Are you sure you want to leave? Once you leave, you will have to request to rejoin if you change your mind.")
color: Theme.palette.directColor1
font.pixelSize: 15
}
}
rightButtons: [
StatusButton {
text: qsTr("Cancel")
onClicked: leavePopup.close()
},
StatusButton {
objectName: "CommunitiesListPanel_leaveCommunityButtonInPopup"
type: StatusBaseButton.Type.Danger
text: qsTr("Leave community")
onClicked: {
root.leaveCommunityClicked(leavePopup.communityId)
leavePopup.close()
}
}
]
}
} // ListView
}

View File

@ -30,9 +30,7 @@ SettingsContentBase {
titleRowComponentLoader.sourceComponent: StatusButton {
text: qsTr("Import community")
size: StatusBaseButton.Size.Small
onClicked: {
Global.openPopup(importCommunitiesPopupComponent)
}
onClicked: Global.importCommunityPopupRequested()
}
Item {
@ -117,10 +115,14 @@ SettingsContentBase {
]
}
onLeaveCommunityClicked: {
onCloseCommunityClicked: {
root.profileSectionStore.communitiesProfileModule.leaveCommunity(communityId)
}
onLeaveCommunityClicked: {
Global.leaveCommunityRequested(community, communityId, outroMessage)
}
onSetCommunityMutedClicked: {
root.profileSectionStore.communitiesProfileModule.setCommunityMuted(communityId, muted)
}
@ -135,16 +137,6 @@ SettingsContentBase {
null)
}
}
} // Column
} // Item
property Component importCommunitiesPopupComponent: ImportCommunityPopup {
anchors.centerIn: parent
store: root.profileSectionStore
onClosed: {
destroy()
}
}
} // ScrollView
}

View File

@ -354,6 +354,8 @@ Item {
onTriggered: popups.openCommunityProfilePopup(appMain.rootStore, model, communityContextMenu.chatCommunitySectionModule)
}
StatusMenuSeparator {}
StatusAction {
text: model.muted ? qsTr("Unmute Community") : qsTr("Mute Community")
icon.name: model.muted ? "notification-muted" : "notification"
@ -362,13 +364,20 @@ Item {
}
}
StatusMenuSeparator {}
StatusMenuSeparator { visible: leaveCommunityMenuItem.enabled }
StatusAction {
text: qsTr("Leave Community")
icon.name: "arrow-left"
id: leaveCommunityMenuItem
enabled: !model.amISectionAdmin
text: {
if (model.spectated)
return qsTr("Close Community")
return qsTr("Leave Community")
}
icon.name: model.spectated ? "close-circle" : "arrow-left"
type: StatusAction.Type.Danger
onTriggered: communityContextMenu.chatCommunitySectionModule.leaveCommunity()
onTriggered: model.spectated ? communityContextMenu.chatCommunitySectionModule.leaveCommunity()
: popups.openLeaveCommunityPopup(model.name, model.id, model.outroMessage)
}
}
}

View File

@ -1,5 +1,13 @@
import QtQuick 2.15
import QtQuick.Dialogs 1.0
import QtQuick.Layouts 1.15
import QtQuick.Dialogs 1.3
import QtQml.Models 2.15
import QtQml 2.15
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import AppLayouts.Chat.popups 1.0
import AppLayouts.Profile.popups 1.0
@ -44,6 +52,7 @@ QtObject {
Global.closePopupRequested.connect(closePopup)
Global.openDeleteMessagePopup.connect(openDeleteMessagePopup)
Global.openDownloadImageDialog.connect(openDownloadImageDialog)
Global.leaveCommunityRequested.connect(openLeaveCommunityPopup)
}
property var currentPopup
@ -228,6 +237,10 @@ QtObject {
popup.open()
}
function openLeaveCommunityPopup(community, communityId, outroMessage) {
openPopup(leaveCommunityPopupComponent, {community, communityId, outroMessage})
}
readonly property list<Component> _components: [
Component {
id: removeContactConfirmationDialog
@ -280,7 +293,6 @@ QtObject {
Component {
id: sendIDRequestPopupComponent
SendContactRequestModal {
anchors.centerIn: parent
rootStore: root.rootStore
onAccepted: root.rootStore.profileSectionStore.contactsStore.sendVerificationRequest(userPublicKey, message)
onClosed: destroy()
@ -291,7 +303,6 @@ QtObject {
id: inviteFriendsToCommunityPopup
InviteFriendsToCommunityPopup {
anchors.centerIn: parent
rootStore: root.rootStore
contactsStore: root.rootStore.contactStore
onClosed: destroy()
@ -302,7 +313,6 @@ QtObject {
id: sendContactRequestPopupComponent
SendContactRequestModal {
anchors.centerIn: parent
rootStore: root.rootStore
onAccepted: root.rootStore.profileSectionStore.contactsStore.sendContactRequest(userPublicKey, message)
onClosed: destroy()
@ -312,7 +322,6 @@ QtObject {
Component {
id: backupSeedModalComponent
BackupSeedModal {
anchors.centerIn: parent
privacyStore: rootStore.profileSectionStore.privacyStore
onClosed: destroy()
}
@ -321,7 +330,6 @@ QtObject {
Component {
id: displayNamePopupComponent
DisplayNamePopup {
anchors.centerIn: parent
profileStore: rootStore.profileSectionStore.profileStore
onClosed: destroy()
}
@ -395,7 +403,6 @@ QtObject {
id: communityProfilePopup
CommunityProfilePopup {
anchors.centerIn: parent
contactsStore: rootStore.contactStore
hasAddedContacts: rootStore.hasAddedContacts
@ -459,7 +466,6 @@ QtObject {
Component {
id: createCommunitiesPopupComponent
CreateCommunityPopup {
anchors.centerIn: parent
store: root.communitiesStore
onClosed: {
destroy()
@ -498,6 +504,59 @@ QtObject {
destroy()
}
}
},
Component {
id: leaveCommunityPopupComponent
StatusModal {
id: leavePopup
property string community
property string communityId
property string outroMessage
headerSettings.title: qsTr("Are you sure want to leave '%1'?").arg(community)
padding: 16
width: 640
contentItem: ColumnLayout {
spacing: 16
StatusBaseText {
id: outroMessage
Layout.fillWidth: true
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: leavePopup.outroMessage
visible: !!text
}
StatusMenuSeparator {
Layout.fillWidth: true
visible: outroMessage.visible
}
StatusBaseText {
Layout.fillWidth: true
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pixelSize: 13
text: qsTr("You will need to request to join if you want to become a member again in the future. If you joined the Community via public key ensure you have a copy of it before you go.")
}
}
rightButtons: [
StatusFlatButton {
text: qsTr("Cancel")
onClicked: leavePopup.close()
},
StatusButton {
objectName: "CommunitiesListPanel_leaveCommunityButtonInPopup"
type: StatusBaseButton.Type.Danger
text: qsTr("Leave %1").arg(leavePopup.community)
onClicked: {
root.rootStore.profileSectionStore.communitiesProfileModule.leaveCommunity(leavePopup.communityId)
leavePopup.close()
}
}
]
onClosed: destroy()
}
}
]
}

View File

@ -56,6 +56,7 @@ QtObject {
signal switchToCommunity(string communityId)
signal createCommunityPopupRequested(bool isDiscordImport)
signal importCommunityPopupRequested()
signal leaveCommunityRequested(string community, string communityId, string outroMessage)
signal playSendMessageSound()
signal playNotificationSound()