refactor(Communities) replace `CommunityProfilePopup` with `StatusModal`

This commit refactors the `CommunityProfilePopup` to use `StatusModal`. Since it's made of
various popup content components, it also updates the memberlist, the overview and the
invite friends view, so it doesn't break the UI along the way.

Closes: #2885, #2887, #2888
This commit is contained in:
Pascal Precht 2021-07-15 13:15:56 +02:00 committed by Iuri Matias
parent c0da840a87
commit 1a9d6d178c
7 changed files with 415 additions and 552 deletions

@ -1 +1 @@
Subproject commit 7136968b3ad50d6d222849d53c793ecf82566786
Subproject commit 58e8f1cd23e87572d57a886e65a31a27462cfb9c

View File

@ -272,6 +272,7 @@ Item {
CommunityProfilePopup {
id: communityProfilePopup
anchors.centerIn: parent
communityId: chatsModel.communities.activeCommunity.id
name: chatsModel.communities.activeCommunity.name
description: chatsModel.communities.activeCommunity.description

View File

@ -1,15 +1,12 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import QtQuick.Controls.Universal 2.12
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "../ContactsColumn"
ModalPopup {
import StatusQ.Controls 0.1
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
@ -18,136 +15,37 @@ ModalPopup {
property string communityColor: chatsModel.communities.activeCommunity.communityColor
property int nbMembers: chatsModel.communities.activeCommunity.nbMembers
property bool isAdmin: chatsModel.communities.activeCommunity.isAdmin
height: stack.currentItem.height + modalHeader.height + modalFooter.height + Style.current.padding * 3
id: popup
onClosed: {
while (stack.depth > 1) {
stack.pop()
while (contentComponent.depth > 1) {
contentComponent.pop()
}
}
header: Item {
id: modalHeader
height: childrenRect.height
width: parent.width
header.title: contentComponent.currentItem.headerTitle
header.subTitle: contentComponent.currentItem.headerSubtitle || ""
header.image.source: contentComponent.currentItem.headerImageSource || ""
property string title: stack.currentItem.headerTitle
property string description: stack.currentItem.headerDescription
property string imageSource: stack.currentItem.headerImageSource
property bool useLetterIdenticon: !!stack.currentItem.useLetterIdenticon
Loader {
id: communityImg
sourceComponent: !modalHeader.useLetterIdenticon ? commmunityImgCmp : letterIdenticonCmp
active: !!modalHeader.imageSource || modalHeader.useLetterIdenticon
}
Component {
id: commmunityImgCmp
RoundedImage {
source: modalHeader.imageSource
width: 40
height: 40
visible: !!modalHeader.imageSource
}
}
Component {
id: letterIdenticonCmp
StatusLetterIdenticon {
width: 40
height: 40
chatName: popup.name
color: popup.communityColor || Style.current.blue
}
}
StyledTextEdit {
id: communityName
text: textMetrics.elidedText
anchors.top: parent.top
anchors.topMargin: 2
anchors.left: communityImg.active ? communityImg.right : parent.left
anchors.leftMargin: communityImg.active ? Style.current.smallPadding : 0
anchors.right: parent.right
/* Because of ModalPopup's close button we must set rightMargin,
cause we don't want overlap it.
This should be generally fixed in ModalPopup file. */
anchors.rightMargin: 40
font.bold: true
font.pixelSize: 17
readOnly: true
}
TextMetrics {
id: textMetrics
font: communityName.font
text: modalHeader.title
elideWidth: communityName.width
elide: Text.ElideMiddle
}
StyledText {
id: headerDescription
text: modalHeader.description
anchors.left: communityName.left
anchors.top: communityName.bottom
anchors.topMargin: 2
font.pixelSize: 15
font.weight: Font.Thin
color: Style.current.secondaryText
}
Separator {
anchors.top: headerDescription.bottom
anchors.topMargin: modalHeader.description === "" ? 0 : Style.current.padding
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
anchors.leftMargin: -Style.current.padding
}
}
StackView {
content: StackView {
id: stack
initialItem: profileOverview
width: parent.width
anchors.centerIn: parent
width: popup.width
height: currentItem.implicitHeight || currentItem.height
pushEnter: Transition { enabled: false }
pushExit: Transition { enabled: false }
popEnter: Transition { enabled: false }
popExit: Transition { enabled: false }
Component {
id: inviteFriendsView
CommunityProfilePopupInviteFriendsView {
headerTitle: qsTr("Invite friends")
contactListSearch.chatKey.text: ""
contactListSearch.pubKey: ""
contactListSearch.pubKeys: []
contactListSearch.ensUsername: ""
contactListSearch.existingContacts.visible: profileModel.contacts.list.hasAddedContacts()
contactListSearch.noContactsRect.visible: !contactListSearch.existingContacts.visible
}
}
Component {
id: membersList
CommunityProfilePopupMembersList {
headerTitle: qsTr("Members")
headerDescription: popup.nbMembers.toString()
members: chatsModel.communities.activeCommunity.members
}
}
Component {
id: profileOverview
CommunityProfilePopupOverview {
property bool useLetterIdenticon: !!!popup.source
width: stack.width
headerTitle: chatsModel.communities.activeCommunity.name
headerDescription: {
headerSubtitle: {
switch(access) {
//% "Public community"
case Constants.communityChatPublicAccess: return qsTrId("public-community");
@ -161,37 +59,69 @@ ModalPopup {
}
headerImageSource: chatsModel.communities.activeCommunity.thumbnailImage
description: chatsModel.communities.activeCommunity.description
onMembersListButtonClicked: popup.contentComponent.push(membersList)
onNotificationsButtonClicked: {
chatsModel.communities.setCommunityMuted(chatsModel.communities.activeCommunity.id, checked)
}
onEditButtonClicked: openPopup(editCommunityPopup)
onTransferOwnershipButtonClicked: openPopup(transferOwnershipPopup, {privateKey: chatsModel.communities.exportComumnity()})
onLeaveButtonClicked: chatsModel.communities.leaveCommunity(communityId)
}
}
Component {
id: membersList
CommunityProfilePopupMembersList {
width: stack.width
headerTitle: qsTr("Members")
headerSubtitle: popup.nbMembers.toString()
members: chatsModel.communities.activeCommunity.members
onInviteButtonClicked: popup.contentComponent.push(inviteFriendsView)
}
}
Component {
id: inviteFriendsView
CommunityProfilePopupInviteFriendsView {
width: stack.width
headerTitle: qsTr("Invite friends")
contactListSearch.chatKey.text: ""
contactListSearch.pubKey: ""
contactListSearch.pubKeys: []
contactListSearch.ensUsername: ""
contactListSearch.existingContacts.visible: profileModel.contacts.list.hasAddedContacts()
contactListSearch.noContactsRect.visible: !contactListSearch.existingContacts.visible
}
}
}
footer: Item {
id: modalFooter
visible: stack.depth > 1
width: parent.width
height: modalFooter.visible ? btnBack.height : 0
leftButtons: [
StatusRoundButton {
id: btnBack
anchors.left: parent.left
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
icon.width: 20
rotation: 180
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
visible: contentComponent.depth > 1
height: !visible ? 0 : implicitHeight
onClicked: {
stack.pop()
contentComponent.pop()
}
}
]
rightButtons: [
StatusButton {
text: qsTr("Invite")
anchors.right: parent.right
enabled: stack.currentItem.contactListSearch !== undefined && stack.currentItem.contactListSearch.pubKeys.length > 0
visible: popup.contentComponent.depth > 2
height: !visible ? 0 : implicitHeight
enabled: popup.contentComponent.currentItem.contactListSearch !== undefined && popup.contentComponent.currentItem.contactListSearch.pubKeys.length > 0
onClicked: {
stack.currentItem.sendInvites(stack.currentItem.contactListSearch.pubKeys)
stack.pop()
popup.contentComponent.currentItem.sendInvites(popup.contentComponent.currentItem.contactListSearch.pubKeys)
popup.contentComponent.pop()
}
}
}
]
}

View File

@ -7,17 +7,16 @@ import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
Item {
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
Column {
id: root
property string headerTitle: ""
property string headerDescription: ""
property string headerImageSource: ""
property alias contactListSearch: contactFieldAndList
height: 400
function sendInvites(pubKeys) {
const error = chatsModel.communities.inviteUsersToCommunityById(popup.communityId, JSON.stringify(pubKeys))
if (error) {
@ -28,31 +27,32 @@ Item {
contactFieldAndList.successMessage = qsTr("Invite successfully sent")
}
TextWithLabel {
id: shareCommunity
anchors.top: parent.top
anchors.topMargin: 0
//% "Share community"
label: qsTrId("share-community")
text: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
textToCopy: Constants.communityLinkPrefix + communityId
StatusModalDivider {
bottomPadding: 8
}
Separator {
id: sep
anchors.left: parent.left
anchors.right: parent.right
anchors.top: shareCommunity.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
StatusDescriptionListItem {
title: qsTr("Share community")
subTitle: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let link = `${Constants.communityLinkPrefix}${communityId}`
chatsModel.copyToClipboard(link)
tooltip.visible = !tooltip.visible
}
width: parent.width
}
StatusModalDivider {
bottomPadding: 16
}
ContactsListAndSearch {
id: contactFieldAndList
anchors.top: sep.bottom
anchors.topMargin: Style.current.smallPadding
width: parent.width
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - 32
showCheckbox: true
hideCommunityMembers: true
}

View File

@ -1,206 +1,205 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtQuick.Controls.Universal 2.12
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "./"
import "../components"
Item {
id: root
height: childrenRect.height
implicitWidth: 480
property string headerTitle: ""
property string headerDescription: ""
property string headerSubtitle: ""
property string headerImageSource: ""
property alias members: memberList.model
height: 450
CommunityPopupButton {
id: inviteBtn
visible: isAdmin
//% "Invite People"
label: qsTrId("invite-people")
width: parent.width
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
iconName: "invite"
onClicked: stack.push(inviteFriendsView)
height: visible ? 64 : 0
}
signal inviteButtonClicked()
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
visible: inviteBtn.visible
}
Column {
StatusSettingsLineButton {
id: membershipRequestsBtn
text: qsTr("Membership requests")
badgeText: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests.toString()
visible: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests > 0
badgeSize: 22
badgeRadius: badgeSize / 2
isBadge: true
height: 64
anchors.top: sep.bottom
anchors.topMargin: visible ? Style.current.smallPadding : 0
anchors.leftMargin: 0
anchors.rightMargin: 0
onClicked: membershipRequestPopup.open()
}
id: memberSearchAndInviteButton
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
}
StatusModalDivider {}
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.bigPadding
spacing: 4
clip: true
delegate: Rectangle {
id: contactRow
Item {
width: parent.width
height: 64
radius: Style.current.radius
color: isHovered ? Style.current.backgroundHover : Style.current.transparent
height: 76
property bool isHovered: false
property string nickname: appMain.getUserNickname(model.pubKey)
StatusImageIdenticon {
id: identicon
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
source: model.identicon
Input {
id: memberSearch
width: parent.width - 32
anchors.centerIn: parent
placeholderText: qsTr("Member name")
}
}
StyledText {
id: txtUsername
text: !model.userName.endsWith(".eth") && !!contactRow.nickname ?
contactRow.nickname : Utils.removeStatusEns(model.userName)
anchors.left: identicon.right
anchors.leftMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
StatusListItem {
id: inviteButton
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
title: qsTr("Invite People")
icon.name: "share-ios"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.inviteButtonClicked()
}
StatusModalDivider {
visible: inviteButton.visible && memberRequestsButton.visible
topPadding: 8
bottomPadding: 8
}
StatusContactRequestsIndicatorListItem {
id: memberRequestsButton
property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests
width: parent.width - 32
visible: isAdmin && nbRequests > 0
anchors.horizontalCenter: parent.horizontalCenter
title: qsTr("Membership requests")
requestsCount: nbRequests
sensor.onClicked: membershipRequestPopup.open()
}
StatusModalDivider {
topPadding: !memberRequestsButton.visible && !inviteButton.visible ? 0 : 8
bottomPadding: 8
}
}
ScrollView {
id: scrollView
width: parent.width
height: 300
anchors.top: memberSearchAndInviteButton.bottom
contentHeight: Math.max(300, memberListColumn.height)
clip: true
Item {
width: parent.width
height: 300
visible: memberList.count === 0
StatusBaseText {
anchors.centerIn: parent
text: qsTr("Community members will appear here")
font.pixelSize: 15
color: Theme.palette.baseColor1
}
StyledText {
text: " (" + qsTr("You") + ")"
visible: !moreActionsBtn.visible
anchors.left: txtUsername.right
anchors.leftMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
color: Style.current.secondaryText
}
Item {
width: parent.width
height: 300
visible: !!memberSearch.text && !!memberList.count && !memberListColumn.height
StatusBaseText {
anchors.centerIn: parent
text: qsTr("No contacts found")
font.pixelSize: 15
color: Theme.palette.baseColor1
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: contactRow.isHovered = true
onExited: contactRow.isHovered = false
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: openProfilePopup(model.userName, model.pubKey, model.identicon, '', contactRow.nickname)
}
Column {
id: memberListColumn
width: parent.width
visible: memberList.count > 0 || height > 0
anchors.horizontalCenter: parent.horizontalCenter
StatusContextMenuButton {
id: moreActionsBtn
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
visible: model.pubKey.toLowerCase() !== profileModel.profile.pubKey.toLowerCase()
MouseArea {
anchors.fill: parent
onClicked: contextMenu.popup(-contextMenu.width + moreActionsBtn.width, moreActionsBtn.height + 4)
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onExited: {
contactRow.isHovered = false
moreActionsBtn.highlighted = false
Repeater {
id: memberList
delegate: StatusListItem {
id: memberItem
property string nickname: appMain.getUserNickname(model.pubKey)
property string profileImage: appMain.getProfileImage(model.pubKey)
visible: !!!memberSearch.text ||
model.userName.toLowerCase().includes(memberSearch.text.toLowerCase()) ||
nickname.toLowerCase().includes(memberSearch.text.toLowerCase())
anchors.horizontalCenter: parent.horizontalCenter
image.isIdenticon: !profileImage
image.source: profileImage || model.identicon
title: {
if (menuButton.visible) {
return !model.userName.endsWith(".eth") && !!nickname ?
nickname : Utils.removeStatusEns(model.userName)
}
return qsTr("You")
}
onEntered: {
contactRow.isHovered = true
moreActionsBtn.highlighted = true
}
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)
components: [
StatusFlatRoundButton {
id: menuButton
width: 32
height: 32
visible: model.pubKey.toLowerCase() !== profileModel.profile.pubKey.toLowerCase()
icon.name: "more"
type: StatusFlatRoundButton.Type.Secondary
onClicked: {
highlighted = true
communityMemberContextMenu.popup(-communityMemberContextMenu.width+menuButton.width, menuButton.height + 4)
}
StatusPopupMenu {
id: communityMemberContextMenu
onClosed: {
menuButton.highlighted = false
}
StatusMenuItem {
text: qsTr("View Profile")
icon.name: "channel"
onTriggered: openProfilePopup(model.userName, model.pubKey, memberItem.image.source, '', memberItem.nickname)
}
StatusMenuSeparator {
visible: chatsModel.communities.activeCommunity.admin
}
StatusMenuItem {
text: qsTr("Kick")
icon.name: "arrow-right"
iconRotation: 180
type: StatusMenuItem.Type.Danger
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: chatsModel.communities.removeUserFromCommunity(model.pubKey)
}
StatusMenuItem {
text: qsTr("Ban")
icon.name: "cancel"
type: StatusMenuItem.Type.Danger
enabled: chatsModel.communities.activeCommunity.admin
onTriggered: chatsModel.communities.banUserFromCommunity(model.pubKey, chatsModel.communities.activeCommunity.id)
}
}
}
/* Action { */
/* icon.source: "../../../img/communities/menu/roles.svg" */
/* icon.width: 16 */
/* icon.height: 16 */
/* //% "Roles" */
/* text: qsTrId("roles") */
/* onTriggered: console.log("TODO") */
/* } */
Separator {
height: 10
visible: chatsModel.communities.activeCommunity.admin
}
Action {
property string type: "danger"
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 {
property string type: "danger"
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: chatsModel.communities.banUserFromCommunity(model.pubKey, chatsModel.communities.activeCommunity.id)
}
/* Separator {} */
/* 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") */
/* onTriggered: console.log("TODO") */
/* } */
}
]
}
}
}
}
StatusModalDivider {
anchors.top: scrollView.bottom
topPadding: 8
}
}

View File

@ -1,236 +1,166 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import QtQuick.Controls.Universal 2.12
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "../ContactsColumn"
Item {
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import "../../../../imports"
Column {
id: root
property string headerTitle: ""
property string headerDescription: ""
property string headerSubtitle: ""
property string headerImageSource: ""
property string description: ""
width: parent.width
height: childrenRect.height
signal membersListButtonClicked()
signal notificationsButtonClicked(bool checked)
signal editButtonClicked()
signal transferOwnershipButtonClicked()
signal leaveButtonClicked()
StyledText {
id: descriptionText
text: root.description
wrapMode: Text.Wrap
StatusModalDivider {
bottomPadding: 8
}
Item {
height: 46
width: parent.width
font.pixelSize: 15
}
Separator {
id: sep1
anchors.left: parent.left
anchors.right: parent.right
anchors.top: descriptionText.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
TextWithLabel {
id: shareCommunity
anchors.top: sep1.bottom
anchors.topMargin: Style.current.bigPadding
//% "Share community"
label: qsTrId("share-community")
text: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
textToCopy: Constants.communityLinkPrefix + communityId
}
Separator {
id: sep2
anchors.left: parent.left
anchors.right: parent.right
anchors.top: shareCommunity.bottom
anchors.topMargin: Style.current.smallPadding
anchors.leftMargin: -Style.current.padding
anchors.rightMargin: -Style.current.padding
}
Column {
anchors.top: sep2.bottom
anchors.topMargin: Style.current.halfPadding
width: parent.width
Loader {
width: parent.width
sourceComponent: Component {
CommunityPopupButton {
id: memberBtn
label: qsTr("Members")
iconName: "members"
txtColor: Style.current.textColor
onClicked: stack.push(membersList)
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
Item {
property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests
id: memberBlock
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
width: childrenRect.width
height: memberBtn.height
StyledText {
id: nbMemberText
text: nbMembers.toString()
anchors.verticalCenter: parent.verticalCenter
padding: 0
font.pixelSize: 15
color: Style.current.secondaryText
}
Rectangle {
id: badge
visible: memberBlock.nbRequests > 0
anchors.left: nbMemberText.right
anchors.leftMargin: visible ? Style.current.halfPadding : 0
anchors.verticalCenter: parent.verticalCenter
color: Style.current.blue
width: visible ? 22 : 0
height: 22
radius: width / 2
Text {
font.pixelSize: 12
color: Style.current.white
anchors.centerIn: parent
text: memberBlock.nbRequests
}
}
SVGImage {
id: caret
anchors.left: badge.right
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
source: "../../../img/caret.svg"
width: 13
height: 7
rotation: -90
ColorOverlay {
anchors.fill: parent
source: parent
color: Style.current.secondaryText
}
}
}
}
}
}
// TODO add this back when roles exist
// Loader {
// active: isAdmin
// width: parent.width
// sourceComponent: CommunityPopupButton {
// label: qsTr("Roles")
// iconName: "roles"
// width: parent.width
// onClicked: console.log("TODO:")
// txtColor: Style.current.textColor
// SVGImage {
// anchors.verticalCenter: parent.verticalCenter
// anchors.right: parent.right
// anchors.rightMargin: Style.current.padding
// source: "../../../img/caret.svg"
// width: 13
// height: 7
// rotation: -90
// ColorOverlay {
// anchors.fill: parent
// source: parent
// color: Style.current.secondaryText
// }
// }
// }
// }
CommunityPopupButton {
id: notificationsBtn
//% "Notifications"
label: qsTrId("notifications")
iconName: "notifications"
width: parent.width
txtColor: Style.current.textColor
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
onClicked: function(){
notificationSwitch.clicked()
}
StatusSwitch {
id: notificationSwitch
checked: !chatsModel.communities.activeCommunity.muted
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
onClicked: function () {
chatsModel.communities.setCommunityMuted(chatsModel.communities.activeCommunity.id, notificationSwitch.checked)
}
}
}
Item {
id: spacer1
width: parent.width
height: Style.current.halfPadding
}
Separator {
StatusBaseText {
id: communityDescription
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: -Style.current.padding
anchors.leftMargin: -Style.current.padding
}
Item {
id: spacer2
width: parent.width
height: Style.current.halfPadding
}
Loader {
// TODO: once Edit is vailable in the app, put back isAdmin
active: isAdmin
width: parent.width
sourceComponent: CommunityPopupButton {
//% "Edit community"
label: qsTrId("edit-community")
iconName: "edit"
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
onClicked: openPopup(editCommunityPopup)
}
}
Loader {
active: isAdmin
width: parent.width
sourceComponent: CommunityPopupButton {
label: qsTr("Transfer ownership")
iconName: "../transfer"
type: globalSettings.theme === Universal.Dark ? "secondary" : "primary"
onClicked: openPopup(transferOwnershipPopup, {privateKey: chatsModel.communities.exportComumnity()})
}
}
CommunityPopupButton {
//% "Leave community"
label: qsTrId("leave-community")
iconName: "leave"
type: "warn"
txtColor: Style.current.red
onClicked: chatsModel.communities.leaveCommunity(communityId)
anchors.leftMargin: 16
anchors.rightMargin: 16
text: root.description
font.pixelSize: 15
color: Theme.palette.directColor1
wrapMode: Text.Wrap
}
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusDescriptionListItem {
title: qsTr("Share community")
subTitle: `${Constants.communityLinkPrefix}${communityId.substring(0, 4)}...${communityId.substring(communityId.length -2)}`
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let link = `${Constants.communityLinkPrefix}${communityId}`
chatsModel.copyToClipboard(link)
tooltip.visible = !tooltip.visible
}
width: parent.width
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
id: membersListItem
anchors.horizontalCenter: parent.horizontalCenter
property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests
title: qsTr("Members")
icon.name: "group-chat"
label: nbMembers.toString()
sensor.onClicked: root.membersListButtonClicked()
components: [
StatusBadge {
visible: !!membersListItem.nbRequests
value: membersListItem.nbRequests
},
StatusIcon {
icon: "chevron-down"
rotation: 270
color: Theme.palette.baseColor1
}
]
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: qsTr("Notifications")
icon.name: "notification"
components: [
StatusSwitch {
checked: !chatsModel.communities.activeCommunity.muted
onClicked: root.notificationsButtonClicked(checked)
}
]
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
title: qsTr("Edit community")
icon.name: "edit"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.editButtonClicked()
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: isAdmin
title: qsTr("Transfer ownership")
icon.name: "exchange"
type: StatusListItem.Type.Secondary
sensor.onClicked: root.transferOwnershipButtonClicked()
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: qsTr("Leave community")
icon.name: "arrow-right"
icon.height: 16
icon.width: 20
icon.rotation: 180
type: StatusListItem.Type.Secondary
sensor.onClicked: root.leaveButtonClicked()
}
/* // TODO add this back when roles exist */
/* // Loader { */
/* // active: isAdmin */
/* // width: parent.width */
/* // sourceComponent: CommunityPopupButton { */
/* // label: qsTr("Roles") */
/* // iconName: "roles" */
/* // width: parent.width */
/* // onClicked: console.log("TODO:") */
/* // txtColor: Style.current.textColor */
/* // SVGImage { */
/* // anchors.verticalCenter: parent.verticalCenter */
/* // anchors.right: parent.right */
/* // anchors.rightMargin: Style.current.padding */
/* // source: "../../../img/caret.svg" */
/* // width: 13 */
/* // height: 7 */
/* // rotation: -90 */
/* // ColorOverlay { */
/* // anchors.fill: parent */
/* // source: parent */
/* // color: Style.current.secondaryText */
/* // } */
/* // } */
/* // } */
/* // } */
}

View File

@ -492,6 +492,7 @@ StatusAppLayout {
Component {
id: inviteFriendsToCommunityPopup
InviteFriendsToCommunityPopup {
anchors.centerIn: parent
onClosed: {
destroy()
}
@ -501,6 +502,7 @@ StatusAppLayout {
Component {
id: communityMembersPopup
CommunityMembersPopup {
anchors.centerIn: parent
onClosed: {
destroy()
}
@ -510,6 +512,7 @@ StatusAppLayout {
Component {
id: editCommunityPopup
CreateCommunityPopup {
anchors.centerIn: parent
isEdit: true
onClosed: {
destroy()