feat(Settings/Communities): implement new communities list
Closes #11145
This commit is contained in:
parent
9df6e68a77
commit
620c7a746d
|
@ -69,6 +69,10 @@ ListModel {
|
||||||
title: "DeviceSyncingView"
|
title: "DeviceSyncingView"
|
||||||
section: "Views"
|
section: "Views"
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
title: "CommunitiesView"
|
||||||
|
section: "Views"
|
||||||
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
title: "StatusCommunityCard"
|
title: "StatusCommunityCard"
|
||||||
section: "Panels"
|
section: "Panels"
|
||||||
|
|
|
@ -221,5 +221,8 @@
|
||||||
],
|
],
|
||||||
"StatusButton": [
|
"StatusButton": [
|
||||||
"https://www.figma.com/file/MtAO3a7HnEH5xjCDVNilS7/%F0%9F%8E%A8-Design-System-%E2%8E%9C-Desktop?type=design&node-id=1-12&t=UHegCbqAa5K7qUKd-0"
|
"https://www.figma.com/file/MtAO3a7HnEH5xjCDVNilS7/%F0%9F%8E%A8-Design-System-%E2%8E%9C-Desktop?type=design&node-id=1-12&t=UHegCbqAa5K7qUKd-0"
|
||||||
|
],
|
||||||
|
"CommunitiesView": [
|
||||||
|
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=16089-387522&t=HRT9BmZXnl7Lt55Q-0"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
|
||||||
|
import AppLayouts.Profile.views 1.0
|
||||||
|
import mainui 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import Storybook 1.0
|
||||||
|
import Models 1.0
|
||||||
|
|
||||||
|
SplitView {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Logs { id: logs }
|
||||||
|
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
Popups {
|
||||||
|
popupParent: root
|
||||||
|
rootStore: QtObject {}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: emptyModel
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: communitiesModel
|
||||||
|
Component.onCompleted:
|
||||||
|
append([{
|
||||||
|
id: "0x0001",
|
||||||
|
name: "Test community",
|
||||||
|
description: "Lorem ipsum dolor sit amet",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: true,
|
||||||
|
spectated: false,
|
||||||
|
memberRole: Constants.memberRole.owner,
|
||||||
|
image: ModelsData.icons.dribble,
|
||||||
|
color: "yellow",
|
||||||
|
muted: false,
|
||||||
|
members: [ { pubKey: "0xdeadbeef" } ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "0x0002",
|
||||||
|
name: "Test community 2",
|
||||||
|
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: true,
|
||||||
|
spectated: false,
|
||||||
|
memberRole: Constants.memberRole.none,
|
||||||
|
image: ModelsData.icons.status,
|
||||||
|
color: "peach",
|
||||||
|
muted: false,
|
||||||
|
members: [ { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" } ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "0x0003",
|
||||||
|
name: "Free to join",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: false,
|
||||||
|
spectated: true,
|
||||||
|
memberRole: Constants.memberRole.none,
|
||||||
|
image: "",
|
||||||
|
color: "red",
|
||||||
|
muted: false,
|
||||||
|
members: [ { pubKey: "0xdeadbeef" } ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "0x0004",
|
||||||
|
name: "Muted community",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
description: "Lorem ipsum dolor sit amet",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: true,
|
||||||
|
spectated: false,
|
||||||
|
memberRole: Constants.memberRole.none,
|
||||||
|
image: "",
|
||||||
|
color: "whitesmoke",
|
||||||
|
muted: true,
|
||||||
|
members: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "0x0005",
|
||||||
|
name: "Test community 4",
|
||||||
|
description: "Lorem ipsum dolor sit amet",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: true,
|
||||||
|
spectated: false,
|
||||||
|
memberRole: Constants.memberRole.admin,
|
||||||
|
image: ModelsData.icons.spotify,
|
||||||
|
color: "green",
|
||||||
|
muted: false,
|
||||||
|
members: [{ pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "0x0006",
|
||||||
|
name: "Pending request here",
|
||||||
|
description: "Lorem ipsum dolor sit amet",
|
||||||
|
introMessage: "Welcome to ze club",
|
||||||
|
outroMessage: "Sad to see you go",
|
||||||
|
joined: false,
|
||||||
|
spectated: true,
|
||||||
|
memberRole: Constants.memberRole.none,
|
||||||
|
image: ModelsData.icons.spotify,
|
||||||
|
color: "pink",
|
||||||
|
muted: false,
|
||||||
|
members: [{ pubKey: "0xdeadbeef" }]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
CommunitiesView {
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
SplitView.preferredHeight: 400
|
||||||
|
|
||||||
|
contentWidth: 664
|
||||||
|
profileSectionStore: QtObject {
|
||||||
|
property var communitiesProfileModule: QtObject {
|
||||||
|
function setCommunityMuted(communityId, mutedType) {
|
||||||
|
logs.logEvent("profileSectionStore::communitiesProfileModule::setCommunityMuted", ["communityId", "mutedType"], arguments)
|
||||||
|
}
|
||||||
|
function leaveCommunity(communityId) {
|
||||||
|
logs.logEvent("profileSectionStore::communitiesProfileModule::leaveCommunity", ["communityId"], arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property var communitiesList: ctrlEmptyView.checked ? emptyModel : communitiesModel
|
||||||
|
}
|
||||||
|
rootStore: QtObject {
|
||||||
|
function isCommunityRequestPending(communityId) {
|
||||||
|
return communityId === "0x0006"
|
||||||
|
}
|
||||||
|
function cancelPendingRequest(communityId) {
|
||||||
|
logs.logEvent("rootStore::cancelPendingRequest", ["communityId"], arguments)
|
||||||
|
}
|
||||||
|
function setActiveCommunity(communityId) {
|
||||||
|
logs.logEvent("rootStore::setActiveCommunity", ["communityId"], arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogsAndControlsPanel {
|
||||||
|
id: logsAndControlsPanel
|
||||||
|
|
||||||
|
SplitView.minimumHeight: 100
|
||||||
|
SplitView.preferredHeight: 200
|
||||||
|
|
||||||
|
logsView.logText: logs.logText
|
||||||
|
|
||||||
|
Switch {
|
||||||
|
id: ctrlEmptyView
|
||||||
|
text: "No communities"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -143,11 +143,13 @@ StatusListItem {
|
||||||
statusListItemIcon.badge.implicitHeight: 12 // 8 px + 2 px * 2 borders
|
statusListItemIcon.badge.implicitHeight: 12 // 8 px + 2 px * 2 borders
|
||||||
statusListItemIcon.badge.implicitWidth: 12 // 8 px + 2 px * 2 borders
|
statusListItemIcon.badge.implicitWidth: 12 // 8 px + 2 px * 2 borders
|
||||||
components: [
|
components: [
|
||||||
StatusIcon {
|
Loader {
|
||||||
|
active: root.isAdmin
|
||||||
|
sourceComponent: StatusIcon {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: root.isAdmin
|
|
||||||
icon: "crown"
|
icon: "crown"
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,25 +91,6 @@ 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +117,7 @@ StackLayout {
|
||||||
viewAndPostPermissionsModel: root.permissionsStore.viewAndPostPermissionsModel
|
viewAndPostPermissionsModel: root.permissionsStore.viewAndPostPermissionsModel
|
||||||
assetsModel: root.rootStore.assetsModel
|
assetsModel: root.rootStore.assetsModel
|
||||||
collectiblesModel: root.rootStore.collectiblesModel
|
collectiblesModel: root.rootStore.collectiblesModel
|
||||||
isInvitationPending: root.rootStore.isCommunityRequestPending(root.sectionItemModel.id)
|
isInvitationPending: root.rootStore.isCommunityRequestPending(chatView.communityId)
|
||||||
|
|
||||||
onCommunityInfoButtonClicked: root.currentIndex = 1
|
onCommunityInfoButtonClicked: root.currentIndex = 1
|
||||||
onCommunityManageButtonClicked: root.currentIndex = 1
|
onCommunityManageButtonClicked: root.currentIndex = 1
|
||||||
|
@ -149,8 +130,8 @@ StackLayout {
|
||||||
}
|
}
|
||||||
onRevealAddressClicked: {
|
onRevealAddressClicked: {
|
||||||
Global.openPopup(communityIntroDialogPopup, {
|
Global.openPopup(communityIntroDialogPopup, {
|
||||||
communityId: root.sectionItemModel.id,
|
communityId: chatView.communityId,
|
||||||
isInvitationPending: root.rootStore.isCommunityRequestPending(root.sectionItemModel.id),
|
isInvitationPending: root.rootStore.isCommunityRequestPending(chatView.communityId),
|
||||||
name: root.sectionItemModel.name,
|
name: root.sectionItemModel.name,
|
||||||
introMessage: root.sectionItemModel.introMessage,
|
introMessage: root.sectionItemModel.introMessage,
|
||||||
imageSrc: root.sectionItemModel.image,
|
imageSrc: root.sectionItemModel.image,
|
||||||
|
@ -158,8 +139,8 @@ StackLayout {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onInvitationPendingClicked: {
|
onInvitationPendingClicked: {
|
||||||
root.rootStore.cancelPendingRequest(root.sectionItemModel.id)
|
root.rootStore.cancelPendingRequest(chatView.communityId)
|
||||||
chatView.isInvitationPending = root.rootStore.isCommunityRequestPending(root.sectionItemModel.id)
|
chatView.isInvitationPending = root.rootStore.isCommunityRequestPending(chatView.communityId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,12 +108,11 @@ SettingsPageLayout {
|
||||||
model: root.membersModel
|
model: root.membersModel
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
placeholderText: {
|
placeholderText: {
|
||||||
if (root.membersModel.count === 0) {
|
if (root.membersModel.count === 0)
|
||||||
return qsTr("No members to search")
|
return qsTr("No members to search")
|
||||||
} else {
|
|
||||||
return qsTr("Search %1's %n member(s)", "", root.membersModel ? root.membersModel.count : 0).arg(root.communityName)
|
return qsTr("Search %1's %n member(s)", "", root.membersModel ? root.membersModel.count : 0).arg(root.communityName)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
panelType: CommunityMembersTabPanel.TabType.AllMembers
|
panelType: CommunityMembersTabPanel.TabType.AllMembers
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -136,13 +135,10 @@ SettingsPageLayout {
|
||||||
model: root.pendingMemberRequestsModel
|
model: root.pendingMemberRequestsModel
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
placeholderText: {
|
placeholderText: {
|
||||||
if (root.pendingMemberRequestsModel.count === 0) {
|
if (root.pendingMemberRequestsModel.count === 0)
|
||||||
return qsTr("No pending requests to search")
|
return qsTr("No pending requests to search")
|
||||||
} else {
|
|
||||||
return qsTr("Search %1's %2 pending request%3").arg(root.communityName)
|
return qsTr("Search %1's %n pending request(s)", "", root.pendingMemberRequestsModel.count).arg(root.communityName)
|
||||||
.arg(root.pendingMemberRequestsModel.count)
|
|
||||||
.arg(root.pendingMemberRequestsModel.count > 1 ? "s" : "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
panelType: CommunityMembersTabPanel.TabType.PendingRequests
|
panelType: CommunityMembersTabPanel.TabType.PendingRequests
|
||||||
|
|
||||||
|
@ -157,13 +153,10 @@ SettingsPageLayout {
|
||||||
model: root.declinedMemberRequestsModel
|
model: root.declinedMemberRequestsModel
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
placeholderText: {
|
placeholderText: {
|
||||||
if (root.declinedMemberRequestsModel.count === 0) {
|
if (root.declinedMemberRequestsModel.count === 0)
|
||||||
return qsTr("No rejected members to search")
|
return qsTr("No rejected members to search")
|
||||||
} else {
|
|
||||||
return qsTr("Search %1's %2 rejected member%3").arg(root.communityName)
|
return qsTr("Search %1's %n rejected member(s)", "", root.declinedMemberRequestsModel.count).arg(root.communityName)
|
||||||
.arg(root.declinedMemberRequestsModel.count)
|
|
||||||
.arg(root.declinedMemberRequestsModel.count > 1 ? "s" : "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
panelType: CommunityMembersTabPanel.TabType.DeclinedRequests
|
panelType: CommunityMembersTabPanel.TabType.DeclinedRequests
|
||||||
|
|
||||||
|
@ -177,13 +170,10 @@ SettingsPageLayout {
|
||||||
model: root.bannedMembersModel
|
model: root.bannedMembersModel
|
||||||
rootStore: root.rootStore
|
rootStore: root.rootStore
|
||||||
placeholderText: {
|
placeholderText: {
|
||||||
if (root.bannedMembersModel.count === 0) {
|
if (root.bannedMembersModel.count === 0)
|
||||||
return qsTr("No banned members to search")
|
return qsTr("No banned members to search")
|
||||||
} else {
|
|
||||||
return qsTr("Search %1's %2 banned member%3").arg(root.communityName)
|
return qsTr("Search %1's %n banned member(s)", "", root.bannedMembersModel.count).arg(root.communityName)
|
||||||
.arg(root.bannedMembersModel.count)
|
|
||||||
.arg(root.bannedMembersModel.count > 1 ? "s" : "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
panelType: CommunityMembersTabPanel.TabType.BannedMembers
|
panelType: CommunityMembersTabPanel.TabType.BannedMembers
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ Item {
|
||||||
ProfileContextMenu {
|
ProfileContextMenu {
|
||||||
id: memberContextMenuView
|
id: memberContextMenuView
|
||||||
store: root.rootStore
|
store: root.rootStore
|
||||||
myPublicKey: root.rootStore.myPublicKey()
|
myPublicKey: userProfile.pubKey
|
||||||
|
|
||||||
onOpenProfileClicked: {
|
onOpenProfileClicked: {
|
||||||
Global.openProfilePopup(publicKey, null)
|
Global.openProfilePopup(publicKey, null)
|
||||||
|
|
|
@ -632,6 +632,7 @@ StatusSectionLayout {
|
||||||
TransferOwnershipPopup {
|
TransferOwnershipPopup {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
store: root.rootStore
|
store: root.rootStore
|
||||||
|
onClosed: destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -300,7 +300,6 @@ StatusSectionLayout {
|
||||||
|
|
||||||
profileSectionStore: root.store
|
profileSectionStore: root.store
|
||||||
rootStore: root.globalStore
|
rootStore: root.globalStore
|
||||||
contactStore: root.store.contactsStore
|
|
||||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.communitiesSettings)
|
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.communitiesSettings)
|
||||||
contentWidth: d.contentWidth
|
contentWidth: d.contentWidth
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,88 +8,155 @@ import StatusQ.Controls 0.1
|
||||||
import StatusQ.Popups 0.1
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import shared.controls.chat.menuItems 1.0
|
import shared.controls.chat.menuItems 1.0
|
||||||
|
|
||||||
StatusListView {
|
StatusListView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool hasAddedContacts: false
|
property var rootStore
|
||||||
|
|
||||||
signal inviteFriends(var communityData)
|
signal inviteFriends(var communityData)
|
||||||
|
|
||||||
signal closeCommunityClicked(string communityId)
|
signal closeCommunityClicked(string communityId)
|
||||||
signal leaveCommunityClicked(string community, string communityId, string outroMessage)
|
signal leaveCommunityClicked(string community, string communityId, string outroMessage)
|
||||||
|
|
||||||
signal setCommunityMutedClicked(string communityId, int mutedType)
|
signal setCommunityMutedClicked(string communityId, int mutedType)
|
||||||
|
|
||||||
signal setActiveCommunityClicked(string communityId)
|
signal setActiveCommunityClicked(string communityId)
|
||||||
|
signal showCommunityIntroDialog(string communityId, string name, string introMessage, string imageSrc, int accessType)
|
||||||
|
signal cancelMembershipRequest(string communityId)
|
||||||
|
|
||||||
interactive: false
|
interactive: false
|
||||||
implicitHeight: contentItem.childrenRect.height
|
implicitHeight: contentItem.childrenRect.height
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
delegate: StatusListItem {
|
delegate: StatusListItem {
|
||||||
id: statusCommunityItem
|
id: listItem
|
||||||
width: parent.width
|
width: ListView.view.width
|
||||||
title: model.name
|
title: model.name
|
||||||
statusListItemTitle.font.pixelSize: 17
|
statusListItemTitle.font.pixelSize: 17
|
||||||
statusListItemTitle.font.bold: true
|
statusListItemTitle.font.bold: true
|
||||||
|
statusListItemIcon.anchors.verticalCenter: undefined
|
||||||
|
statusListItemIcon.anchors.top: statusListItemTitleArea.top
|
||||||
subTitle: model.description
|
subTitle: model.description
|
||||||
tertiaryTitle: qsTr("%n member(s)", "", model.members.count)
|
tertiaryTitle: qsTr("%n member(s)", "", model.members.count)
|
||||||
|
statusListItemTertiaryTitle.font.weight: Font.Medium
|
||||||
asset.name: model.image
|
asset.name: model.image
|
||||||
asset.isLetterIdenticon: !model.image
|
asset.isLetterIdenticon: !model.image
|
||||||
asset.bgColor: model.color || Theme.palette.primaryColor1
|
asset.bgColor: model.color || Theme.palette.primaryColor1
|
||||||
asset.width: 40
|
asset.width: 40
|
||||||
asset.height: 40
|
asset.height: 40
|
||||||
visible: model.joined
|
|
||||||
height: visible ? implicitHeight: 0
|
|
||||||
|
|
||||||
onClicked: setActiveCommunityClicked(model.id)
|
onClicked: setActiveCommunityClicked(model.id)
|
||||||
|
|
||||||
components: [
|
readonly property bool isOwner: model.memberRole === Constants.memberRole.owner
|
||||||
|
readonly property bool isAdmin: model.memberRole === Constants.memberRole.admin
|
||||||
|
readonly property bool isInvitationPending: root.rootStore.isCommunityRequestPending(model.id)
|
||||||
|
|
||||||
|
components: [
|
||||||
StatusFlatButton {
|
StatusFlatButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
size: StatusBaseButton.Size.Small
|
size: StatusBaseButton.Size.Small
|
||||||
icon.name: "dots-icon"
|
icon.name: "notification-muted"
|
||||||
onClicked: menu.popup(0, height)
|
icon.color: Theme.palette.baseColor1
|
||||||
|
visible: model.muted
|
||||||
|
onClicked: root.setCommunityMutedClicked(model.id, Constants.MutingVariations.Unmuted)
|
||||||
|
},
|
||||||
|
StatusFlatButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
size: StatusBaseButton.Size.Small
|
||||||
|
text: listItem.isInvitationPending ? qsTr("Membership Request Sent") : qsTr("View & Join Community")
|
||||||
|
visible: model.spectated
|
||||||
|
onClicked: root.showCommunityIntroDialog(model.id, model.name, model.introMessage, model.image, model.access)
|
||||||
|
},
|
||||||
|
StatusFlatButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
size: StatusBaseButton.Size.Small
|
||||||
|
icon.name: "more"
|
||||||
|
icon.color: Theme.palette.directColor1
|
||||||
|
highlighted: moreMenu.opened
|
||||||
|
onClicked: moreMenu.popup(-moreMenu.width + width, height + 4)
|
||||||
|
|
||||||
property StatusMenu menu: StatusMenu {
|
StatusMenu {
|
||||||
id: communityContextMenu
|
id: moreMenu
|
||||||
width: 180
|
|
||||||
|
|
||||||
StatusAction {
|
StatusAction {
|
||||||
text: qsTr("Invite People")
|
text: qsTr("Community Admin")
|
||||||
icon.name: "share-ios"
|
icon.name: "settings"
|
||||||
enabled: model.canManageUsers
|
enabled: listItem.isOwner || listItem.isAdmin
|
||||||
onTriggered: root.inviteFriends(model)
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
Global.switchToCommunity(model.id)
|
||||||
|
Global.switchToCommunitySettings(model.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusAction {
|
||||||
|
text: qsTr("Unmute Community")
|
||||||
|
enabled: model.muted
|
||||||
|
icon.name: "notification"
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
root.setCommunityMutedClicked(model.id, Constants.MutingVariations.Unmuted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MuteChatMenuItem {
|
MuteChatMenuItem {
|
||||||
enabled: !model.muted
|
enabled: (model.joined || (model.spectated && !listItem.isInvitationPending)) && !model.muted
|
||||||
title: qsTr("Mute Community")
|
title: qsTr("Mute Community")
|
||||||
onMuteTriggered: {
|
onMuteTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
root.setCommunityMutedClicked(model.id, interval)
|
root.setCommunityMutedClicked(model.id, interval)
|
||||||
communityContextMenu.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusAction {
|
StatusAction {
|
||||||
enabled: model.muted
|
text: qsTr("Invite People")
|
||||||
text: qsTr("Unmute Community")
|
icon.name: "invite-users"
|
||||||
icon.name: "notification-muted"
|
onTriggered: {
|
||||||
onTriggered: root.setCommunityMutedClicked(model.id, Constants.MutingVariations.Unmuted)
|
moreMenu.close()
|
||||||
|
root.inviteFriends(model)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuSeparator {}
|
|
||||||
|
|
||||||
StatusAction {
|
StatusAction {
|
||||||
text: model.spectated ? qsTr("Close Community") : qsTr("Leave Community")
|
id: shareAddressesMenuItem
|
||||||
icon.name: "arrow-left"
|
text: qsTr("Edit Shared Addresses")
|
||||||
|
icon.name: "wallet"
|
||||||
|
enabled: {
|
||||||
|
if (listItem.isOwner)
|
||||||
|
return false
|
||||||
|
if (model.spectated && !listItem.isInvitationPending)
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
Global.openEditSharedAddressesFlow(model.id)
|
||||||
|
// TODO shared addresses flow, cf https://github.com/status-im/status-desktop/issues/11138
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuSeparator {
|
||||||
|
visible: shareAddressesMenuItem.enabled && leaveMenuItem.enabled
|
||||||
|
}
|
||||||
|
StatusAction {
|
||||||
|
id: leaveMenuItem
|
||||||
|
objectName: "CommunitiesListPanel_leaveCommunityPopupButton"
|
||||||
|
text: {
|
||||||
|
if (listItem.isInvitationPending)
|
||||||
|
return qsTr("Cancel Membership Request")
|
||||||
|
return model.spectated ? qsTr("Close Community") : qsTr("Leave Community")
|
||||||
|
}
|
||||||
|
icon.name: {
|
||||||
|
if (listItem.isInvitationPending)
|
||||||
|
return "arrow-left"
|
||||||
|
return model.spectated ? "close-circle" : "arrow-left"
|
||||||
|
}
|
||||||
type: StatusAction.Type.Danger
|
type: StatusAction.Type.Danger
|
||||||
onTriggered: model.spectated ? root.closeCommunityClicked(model.id)
|
enabled: !listItem.isOwner
|
||||||
: root.leaveCommunityClicked(model.name, model.id, model.outroMessage)
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
if (listItem.isInvitationPending)
|
||||||
|
root.cancelMembershipRequest(model.id)
|
||||||
|
else if (model.spectated)
|
||||||
|
root.closeCommunityClicked(model.id)
|
||||||
|
else
|
||||||
|
root.leaveCommunityClicked(model.name, model.id, model.outroMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ SettingsContentBase {
|
||||||
|
|
||||||
property var profileSectionStore
|
property var profileSectionStore
|
||||||
property var rootStore
|
property var rootStore
|
||||||
property var contactStore
|
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ SettingsContentBase {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: noCommunitiesLayout
|
id: noCommunitiesLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: communitiesList.count === 0
|
visible: !root.profileSectionStore.communitiesList.count
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -90,29 +89,80 @@ SettingsContentBase {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
spacing: Style.current.padding
|
spacing: Style.current.padding
|
||||||
|
|
||||||
StatusBaseText {
|
Heading {
|
||||||
|
text: qsTr("Owner")
|
||||||
|
visible: panelOwners.count
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel {
|
||||||
|
id: panelOwners
|
||||||
|
filters: ValueFilter {
|
||||||
|
readonly property int role: Constants.memberRole.owner
|
||||||
|
roleName: "memberRole"
|
||||||
|
value: role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Heading {
|
||||||
|
text: qsTr("Admin")
|
||||||
|
visible: panelAdmins.count
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel {
|
||||||
|
id: panelAdmins
|
||||||
|
filters: ValueFilter {
|
||||||
|
readonly property int role: Constants.memberRole.admin
|
||||||
|
roleName: "memberRole"
|
||||||
|
value: role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Heading {
|
||||||
|
text: qsTr("Member")
|
||||||
|
visible: panelMembers.count
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel {
|
||||||
|
id: panelMembers
|
||||||
|
filters: ExpressionFilter {
|
||||||
|
readonly property int ownerRole: Constants.memberRole.owner
|
||||||
|
readonly property int adminRole: Constants.memberRole.admin
|
||||||
|
expression: model.joined && model.memberRole !== ownerRole && model.memberRole !== adminRole
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Heading {
|
||||||
|
text: qsTr("Pending")
|
||||||
|
visible: panelPendingRequests.count
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel {
|
||||||
|
id: panelPendingRequests
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "spectated"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Heading: StatusBaseText {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Style.current.padding
|
anchors.leftMargin: Style.current.padding
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: qsTr("Communities you've joined")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunitiesListPanel {
|
component Panel: CommunitiesListPanel {
|
||||||
id: communitiesList
|
id: panel
|
||||||
|
|
||||||
|
property var filters
|
||||||
|
|
||||||
objectName: "CommunitiesView_communitiesListPanel"
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
rootStore: root.rootStore
|
||||||
|
|
||||||
model: SortFilterProxyModel {
|
model: SortFilterProxyModel {
|
||||||
id: filteredModel
|
|
||||||
|
|
||||||
sourceModel: root.profileSectionStore.communitiesList
|
sourceModel: root.profileSectionStore.communitiesList
|
||||||
filters: [
|
filters: panel.filters
|
||||||
ValueFilter {
|
|
||||||
roleName: "joined"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCloseCommunityClicked: {
|
onCloseCommunityClicked: {
|
||||||
|
@ -136,6 +186,43 @@ SettingsContentBase {
|
||||||
root.profileSectionStore.communitiesProfileModule,
|
root.profileSectionStore.communitiesProfileModule,
|
||||||
null)
|
null)
|
||||||
}
|
}
|
||||||
|
onShowCommunityIntroDialog: {
|
||||||
|
Global.openPopup(communityIntroDialogPopup, {
|
||||||
|
communityId: communityId,
|
||||||
|
isInvitationPending: root.rootStore.isCommunityRequestPending(communityId),
|
||||||
|
name: name,
|
||||||
|
introMessage: introMessage,
|
||||||
|
imageSrc: imageSrc,
|
||||||
|
accessType: accessType
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onCancelMembershipRequest: {
|
||||||
|
root.rootStore.cancelPendingRequest(communityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var communityIntroDialogPopup: Component {
|
||||||
|
id: communityIntroDialogPopup
|
||||||
|
CommunityIntroDialog {
|
||||||
|
id: communityIntroDialog
|
||||||
|
|
||||||
|
property string communityId
|
||||||
|
|
||||||
|
readonly property var chatCommunitySectionModule: {
|
||||||
|
root.rootStore.mainModuleInst.prepareCommunitySectionModuleForCommunityId(communityIntroDialog.communityId)
|
||||||
|
return root.rootStore.mainModuleInst.getCommunitySectionModule()
|
||||||
|
}
|
||||||
|
|
||||||
|
onJoined: {
|
||||||
|
chatCommunitySectionModule.requestToJoinCommunityWithAuthentication(communityIntroDialog.communityId, root.rootStore.userProfileInst.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancelMembershipRequest: {
|
||||||
|
root.rootStore.cancelPendingRequest(communityIntroDialog.communityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,14 @@ QtObject {
|
||||||
return communitiesModuleInst.isMemberOfCommunity(communityId, pubKey)
|
return communitiesModuleInst.isMemberOfCommunity(communityId, pubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCommunityRequestPending(id: string) {
|
||||||
|
return communitiesModuleInst.isCommunityRequestPending(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelPendingRequest(id: string) {
|
||||||
|
communitiesModuleInst.cancelRequestToJoinCommunity(id)
|
||||||
|
}
|
||||||
|
|
||||||
function copyToClipboard(text) {
|
function copyToClipboard(text) {
|
||||||
globalUtils.copyToClipboard(text)
|
globalUtils.copyToClipboard(text)
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ Item {
|
||||||
StatusAction {
|
StatusAction {
|
||||||
enabled: model.muted
|
enabled: model.muted
|
||||||
text: qsTr("Unmute Community")
|
text: qsTr("Unmute Community")
|
||||||
icon.name: "notification-muted"
|
icon.name: "notification"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
communityContextMenu.chatCommunitySectionModule.setCommunityMuted(Constants.MutingVariations.Unmuted)
|
communityContextMenu.chatCommunitySectionModule.setCommunityMuted(Constants.MutingVariations.Unmuted)
|
||||||
}
|
}
|
||||||
|
@ -1096,6 +1096,15 @@ Item {
|
||||||
restoreMode: Binding.RestoreBindingOrValue
|
restoreMode: Binding.RestoreBindingOrValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Global
|
||||||
|
function onSwitchToCommunitySettings(communityId: string) {
|
||||||
|
if (communityId !== model.id)
|
||||||
|
return
|
||||||
|
chatLayoutComponent.currentIndex = 1 // Settings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
emojiPopup: statusEmojiPopup.item
|
emojiPopup: statusEmojiPopup.item
|
||||||
stickersPopup: statusStickersPopupLoader.item
|
stickersPopup: statusStickersPopupLoader.item
|
||||||
sectionItemModel: model
|
sectionItemModel: model
|
||||||
|
|
|
@ -549,8 +549,8 @@ QtObject {
|
||||||
type: StatusBaseButton.Type.Danger
|
type: StatusBaseButton.Type.Danger
|
||||||
text: qsTr("Leave %1").arg(leavePopup.community)
|
text: qsTr("Leave %1").arg(leavePopup.community)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.rootStore.profileSectionStore.communitiesProfileModule.leaveCommunity(leavePopup.communityId)
|
|
||||||
leavePopup.close()
|
leavePopup.close()
|
||||||
|
root.rootStore.profileSectionStore.communitiesProfileModule.leaveCommunity(leavePopup.communityId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,7 +14,7 @@ StatusMenu {
|
||||||
|
|
||||||
title: isCommunityChat ? qsTr("Mute Channel") : qsTr("Mute Chat")
|
title: isCommunityChat ? qsTr("Mute Channel") : qsTr("Mute Chat")
|
||||||
|
|
||||||
assetSettings.name: "notification"
|
assetSettings.name: "notification-muted"
|
||||||
|
|
||||||
StatusAction {
|
StatusAction {
|
||||||
text: qsTr("For 15 mins")
|
text: qsTr("For 15 mins")
|
||||||
|
@ -37,7 +37,7 @@ StatusMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusAction {
|
StatusAction {
|
||||||
text: qsTr("Until you turn it back on")
|
text: qsTr("Until I turn it back on")
|
||||||
onTriggered: muteTriggered(Constants.MutingVariations.TillUnmuted)
|
onTriggered: muteTriggered(Constants.MutingVariations.TillUnmuted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,11 @@ QtObject {
|
||||||
|
|
||||||
signal openSendModal(string address)
|
signal openSendModal(string address)
|
||||||
signal switchToCommunity(string communityId)
|
signal switchToCommunity(string communityId)
|
||||||
|
signal switchToCommunitySettings(string communityId)
|
||||||
signal createCommunityPopupRequested(bool isDiscordImport)
|
signal createCommunityPopupRequested(bool isDiscordImport)
|
||||||
signal importCommunityPopupRequested()
|
signal importCommunityPopupRequested()
|
||||||
signal leaveCommunityRequested(string community, string communityId, string outroMessage)
|
signal leaveCommunityRequested(string community, string communityId, string outroMessage)
|
||||||
|
signal openEditSharedAddressesFlow(string communityId)
|
||||||
|
|
||||||
signal playSendMessageSound()
|
signal playSendMessageSound()
|
||||||
signal playNotificationSound()
|
signal playNotificationSound()
|
||||||
|
|
Loading…
Reference in New Issue