diff --git a/src/app/modules/main/communities/models/curated_community_item.nim b/src/app/modules/main/communities/models/curated_community_item.nim index d020e0114c..840b3aa96e 100644 --- a/src/app/modules/main/communities/models/curated_community_item.nim +++ b/src/app/modules/main/communities/models/curated_community_item.nim @@ -15,6 +15,7 @@ type activeMembers: int featured: bool permissionModel: TokenPermissionsModel + amIBanned: bool proc initCuratedCommunityItem*( id: string, @@ -28,7 +29,8 @@ proc initCuratedCommunityItem*( members: int, activeMembers: int, featured: bool, - tokenPermissionsItems: seq[TokenPermissionItem] + tokenPermissionsItems: seq[TokenPermissionItem], + amIBanned: bool ): CuratedCommunityItem = result.id = id result.name = name @@ -44,6 +46,7 @@ proc initCuratedCommunityItem*( result.permissionModel = newTokenPermissionsModel() if tokenPermissionsItems.len > 0: result.permissionModel.setItems(tokenPermissionsItems) + result.amIBanned = amIBanned proc `$`*(self: CuratedCommunityItem): string = result = fmt"""CuratedCommunityItem( @@ -56,6 +59,7 @@ proc `$`*(self: CuratedCommunityItem): string = members: {self.members} activeMembers: {self.activeMembers} featured: {self.featured} + amIBanned: {self.amIBanned} ]""" proc getId*(self: CuratedCommunityItem): string = @@ -96,3 +100,6 @@ proc getPermissionsModel*(self: CuratedCommunityItem): TokenPermissionsModel = proc setPermissionModelItems*(self: CuratedCommunityItem, items: seq[TokenPermissionItem]) = self.permissionModel.setItems(items) + +proc getAmIBanned*(self: CuratedCommunityItem): bool = + return self.amIBanned \ No newline at end of file diff --git a/src/app/modules/main/communities/models/curated_community_model.nim b/src/app/modules/main/communities/models/curated_community_model.nim index 332137399e..46fbb07a3f 100644 --- a/src/app/modules/main/communities/models/curated_community_model.nim +++ b/src/app/modules/main/communities/models/curated_community_model.nim @@ -17,6 +17,7 @@ type Color Tags Permissions + AmIBanned QtObject: type CuratedCommunityModel* = ref object of QAbstractListModel @@ -65,6 +66,7 @@ QtObject: ModelRole.Popularity.int:"popularity", ModelRole.Tags.int:"tags", ModelRole.Permissions.int:"permissionsModel", + ModelRole.AmIBanned.int:"amIBanned", }.toTable method data(self: CuratedCommunityModel, index: QModelIndex, role: int): QVariant = @@ -102,6 +104,8 @@ QtObject: result = newQVariant(item.getPermissionsModel()) of ModelRole.Featured: result = newQVariant(item.getFeatured()) + of ModelRole.AmIBanned: + result = newQVariant(item.getAmIBanned()) proc findIndexById(self: CuratedCommunityModel, id: string): int = for i in 0 ..< self.items.len: diff --git a/src/app/modules/main/communities/module.nim b/src/app/modules/main/communities/module.nim index 870446c59f..b1899a4206 100644 --- a/src/app/modules/main/communities/module.nim +++ b/src/app/modules/main/communities/module.nim @@ -254,6 +254,11 @@ proc getCuratedCommunityItem(self: Module, community: CommunityDto): CuratedComm let tokenPermissionItem = buildTokenPermissionItem(tokenPermission, chats) tokenPermissionsItems.add(tokenPermissionItem) + let myPublicKey = singletonInstance.userProfile.getPubKey() + var amIbanned = false + if myPublicKey in community.pendingAndBannedMembers: + amIbanned = community.pendingAndBannedMembers[myPublicKey] == CommunityMemberPendingBanOrKick.Banned + return initCuratedCommunityItem( community.id, community.name, @@ -267,6 +272,7 @@ proc getCuratedCommunityItem(self: Module, community: CommunityDto): CuratedComm int(community.activeMembersCount), community.featuredInDirectory, tokenPermissionsItems, + amIbanned ) proc getDiscordCategoryItem(self: Module, c: DiscordCategoryDto): DiscordCategoryItem = diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index b9ce3ad033..fc1a526341 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -732,7 +732,10 @@ QtObject: self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community])) if wasJoined and not community.joined and not community.isMember: - self.events.emit(SIGNAL_COMMUNITY_KICKED, CommunityArgs(community: community)) + if not community.spectated: + self.events.emit(SIGNAL_COMMUNITY_LEFT, CommunityIdArgs(communityId: community.id)) + else: + self.events.emit(SIGNAL_COMMUNITY_KICKED, CommunityArgs(community: community)) except Exception as e: error "Error handling community updates", msg = e.msg diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusNavBarTabButton.qml b/ui/StatusQ/src/StatusQ/Controls/StatusNavBarTabButton.qml index ec098b3363..1abdd2f0c6 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusNavBarTabButton.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusNavBarTabButton.qml @@ -1,13 +1,17 @@ import QtQuick 2.13 +import StatusQ.Core 0.1 import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Popups 0.1 +import StatusQ.Core.Theme 0.1 StatusIconTabButton { id: statusNavBarTabButton property alias badge: statusBadge property alias tooltip: statusTooltip property Component popupMenu + property alias stateIcon: stateIcon + StatusToolTip { id: statusTooltip @@ -18,6 +22,17 @@ StatusIconTabButton { y: statusNavBarTabButton.height / 2 - height / 2 + 4 } + StatusRoundIcon { + id: stateIcon + visible: false + width: 20 + height: width + anchors.top: parent.top + anchors.left: parent.right + + anchors.leftMargin: (width) * -1 + } + StatusBadge { id: statusBadge visible: value > 0 diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index 9aa4ea5904..2cca034e09 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -63,7 +63,9 @@ StackLayout { sourceComponent: { if (chatItem.isCommunity() && !chatItem.amIMember) { - if (chatItem.isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin) { + if (sectionItemModel.amIBanned) { + return communityBanComponent + } else if (chatItem.isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin) { return controlNodeOfflineComponent } else if (chatItem.requiresTokenPermissionToJoin) { return joinCommunityViewComponent @@ -228,7 +230,24 @@ StackLayout { ControlNodeOfflineCommunityView { id: controlNodeOfflineView readonly property var communityData: sectionItemModel - readonly property string communityId: communityData.id + name: communityData.name + communityDesc: communityData.description + color: communityData.color + image: communityData.image + membersCount: communityData.members.count + communityItemsModel: root.rootStore.communityItemsModel + notificationCount: activityCenterStore.unreadNotificationsCount + hasUnseenNotifications: activityCenterStore.hasUnseenNotifications + onNotificationButtonClicked: Global.openActivityCenterPopup() + onAdHocChatButtonClicked: rootStore.openCloseCreateChatView() + } + } + + Component { + id: communityBanComponent + BannedMemberCommunityView { + id: communityBanView + readonly property var communityData: sectionItemModel name: communityData.name communityDesc: communityData.description color: communityData.color diff --git a/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml b/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml index d3d6b61ff5..87dc1028af 100644 --- a/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml +++ b/ui/app/AppLayouts/Communities/CommunitiesPortalLayout.qml @@ -1,8 +1,10 @@ import QtQuick 2.13 import QtQuick.Layouts 1.13 +import StatusQ 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 +import StatusQ.Core.Utils 0.1 import StatusQ.Controls 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 @@ -12,6 +14,7 @@ import StatusQ.Layout 0.1 import utils 1.0 import shared.controls 1.0 import shared.popups 1.0 +import shared.stores 1.0 import SortFilterProxyModel 0.2 @@ -78,6 +81,10 @@ StatusSectionLayout { expression: { return filteredCommunitiesModel.selectedTagsPredicate(communityTags.selectedTagsNames, model.tags) } + }, + FastExpressionFilter { + expression: !model.amIBanned + expectedRoles: ["amIBanned"] } ] } diff --git a/ui/app/AppLayouts/Communities/panels/CommunityBannedMemberCenterPanel.qml b/ui/app/AppLayouts/Communities/panels/CommunityBannedMemberCenterPanel.qml new file mode 100644 index 0000000000..6be4241f01 --- /dev/null +++ b/ui/app/AppLayouts/Communities/panels/CommunityBannedMemberCenterPanel.qml @@ -0,0 +1,143 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtGraphicalEffects 1.0 + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Components 0.1 +import StatusQ.Controls 0.1 +import StatusQ.Layout 0.1 + +ColumnLayout { + id: root + + property string name + property string chatDateTimeText + property string listUsersText + property var messagesModel + + spacing: 0 + + // Blur background: + Item { + Layout.fillWidth: true + Layout.preferredHeight: Math.min( + centralPanelData.implicitHeight, + parent.height) + + ColumnLayout { + id: centralPanelData + width: parent.width + layer.enabled: true + layer.effect: fastBlur + + StatusBaseText { + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 30 + Layout.bottomMargin: 30 + text: root.chatDateTimeText + font.pixelSize: 13 + color: Theme.palette.baseColor1 + } + + RowLayout { + Layout.alignment: Qt.AlignHCenter + + StatusBaseText { + text: root.listUsersText + font.pixelSize: 13 + } + } + + ListView { + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + spacing + Layout.topMargin: 16 + spacing: 16 + model: root.messagesModel + delegate: StatusMessage { + width: ListView.view.width + timestamp: model.timestamp + enabled: false + messageDetails: StatusMessageDetails { + messageText: model.message + contentType: model.contentType + sender.displayName: model.senderDisplayName + sender.isContact: model.isContact + sender.trustIndicator: model.trustIndicator + sender.profileImage: StatusProfileImageSettings { + width: 40 + height: 40 + name: model.profileImage || "" + colorId: model.colorId + } + } + } + } + } + } + + // User information content + Rectangle { + id: panelBase + + Layout.fillWidth: true + Layout.fillHeight: true + color: Theme.palette.statusAppLayout.rightPanelBackgroundColor + gradient: Gradient { + GradientStop { + position: 0.000 + color: "transparent" + } + GradientStop { + position: 0.180 + color: panelBase.color + } + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + Item { + Layout.fillHeight: true + } + + RowLayout { + Layout.alignment: Qt.AlignHCenter + spacing: 6 + + StatusSmartIdenticon { + Layout.alignment: Qt.AlignVCenter + + asset { + width: 24 + height: width + name: "communities" + color: Theme.palette.dangerColor1 + bgWidth: 22 + bgHeight: 22 + } + } + + StatusBaseText { + text: qsTr("You've been banned from %1").arg(root.name) + color: Theme.palette.dangerColor1 + font.pixelSize: Style.current.secondaryAdditionalTextSize + } + } + Item { + Layout.fillHeight: true + } + } + } + + Component { + id: fastBlur + + FastBlur { + radius: 32 + transparentBorder: true + } + } +} diff --git a/ui/app/AppLayouts/Communities/panels/qmldir b/ui/app/AppLayouts/Communities/panels/qmldir index 9f626d0df3..1b40e76b49 100644 --- a/ui/app/AppLayouts/Communities/panels/qmldir +++ b/ui/app/AppLayouts/Communities/panels/qmldir @@ -5,6 +5,7 @@ ChannelsAndCategoriesBannerPanel 1.0 ChannelsAndCategoriesBannerPanel.qml ChatPermissionQualificationPanel 1.0 ChatPermissionQualificationPanel.qml ColorPanel 1.0 ColorPanel.qml ColumnHeaderPanel 1.0 ColumnHeaderPanel.qml +CommunityBannedMemberCenterPanel 1.0 CommunityBannedMemberCenterPanel.qml ControlNodeOfflineCenterPanel 1.0 ControlNodeOfflineCenterPanel.qml EditSettingsPanel 1.0 EditSettingsPanel.qml FeesBox 1.0 FeesBox.qml diff --git a/ui/app/AppLayouts/Communities/views/BannedMemberCommunityView.qml b/ui/app/AppLayouts/Communities/views/BannedMemberCommunityView.qml new file mode 100644 index 0000000000..61a0021fd2 --- /dev/null +++ b/ui/app/AppLayouts/Communities/views/BannedMemberCommunityView.qml @@ -0,0 +1,113 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.14 +import QtGraphicalEffects 1.0 + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Components 0.1 +import StatusQ.Controls 0.1 + +import AppLayouts.Communities.panels 1.0 +import AppLayouts.Chat.views 1.0 + +import StatusQ.Layout 0.1 + +import utils 1.0 +import shared.popups 1.0 + +StatusSectionLayout { + id: root + + // General properties: + property string name + property string communityDesc + property color color + property string channelName + property string channelDesc + + // Blur view properties: + property int membersCount + property url image + property var communityItemsModel + property string chatDateTimeText + property string listUsersText + property var messagesModel + + signal adHocChatButtonClicked + + QtObject { + id: d + + readonly property int blurryRadius: 32 + } + + headerContent: JoinCommunityHeaderPanel { + color: root.color + name: root.name + channelName: root.channelName + communityDesc: root.communityDesc + channelDesc: root.channelDesc + } + + // Blur background: + leftPanel: ColumnLayout { + anchors.fill: parent + + ColumnHeaderPanel { + Layout.fillWidth: true + name: root.name + membersCount: root.membersCount + image: root.image + color: root.color + amISectionAdmin: false + openCreateChat: false + onAdHocChatButtonClicked: root.adHocChatButtonClicked() + } + + ColumnLayout { + Layout.fillWidth: true + Layout.margins: Style.current.halfPadding + layer.enabled: true + layer.effect: fastBlur + + Repeater { + model: root.communityItemsModel + delegate: StatusChatListItem { + enabled: false + name: model.name + asset.color: root.color + selected: model.selected + type: StatusChatListItem.Type.CommunityChat + notificationsCount: model.notificationsCount + hasUnreadMessages: model.hasUnreadMessages + } + } + } + + Item { + // filler + Layout.fillHeight: true + Layout.fillWidth: true + } + } + + centerPanel: CommunityBannedMemberCenterPanel { + anchors.fill: parent + name: root.name + chatDateTimeText: root.chatDateTimeText + listUsersText: root.listUsersText + messagesModel: root.messagesModel + } + + showRightPanel: false + + Component { + id: fastBlur + + FastBlur { + radius: d.blurryRadius + transparentBorder: true + } + } +} diff --git a/ui/app/AppLayouts/Communities/views/qmldir b/ui/app/AppLayouts/Communities/views/qmldir index 3b8864079a..8168429827 100644 --- a/ui/app/AppLayouts/Communities/views/qmldir +++ b/ui/app/AppLayouts/Communities/views/qmldir @@ -1,3 +1,4 @@ +BannedMemberCommunityView 1.0 BannedMemberCommunityView.qml ChannelsSelectionModel 1.0 ChannelsSelectionModel.qml CommunityColumnView 1.0 CommunityColumnView.qml CommunitiesGridView 1.0 CommunitiesGridView.qml diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index f43808d938..143e152d1a 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -549,6 +549,15 @@ Item { badge.visible: model.hasNotification badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor badge.border.width: 2 + + stateIcon.color: Theme.palette.dangerColor1 + stateIcon.border.color: Theme.palette.baseColor2 + stateIcon.border.width: 2 + stateIcon.visible: model.amIBanned + stateIcon.asset.name: "cancel" + stateIcon.asset.color: Theme.palette.baseColor2 + stateIcon.asset.width: 14 + onClicked: { changeAppSectionBySectionId(model.id) } diff --git a/ui/imports/Themes/Theme.qml b/ui/imports/Themes/Theme.qml index a03876af9e..d8bd0a62ae 100644 --- a/ui/imports/Themes/Theme.qml +++ b/ui/imports/Themes/Theme.qml @@ -102,6 +102,7 @@ QtObject { property int additionalTextSize: 13 + property int secondaryAdditionalTextSize: 17 property int primaryTextFontSize: 15 property int secondaryTextFontSize: 14 property int tertiaryTextFontSize: 12 diff --git a/vendor/status-go b/vendor/status-go index 54ea0981a5..92bc64bb41 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 54ea0981a5e1496c1358ea9dcc8c99ffc2098c73 +Subproject commit 92bc64bb418ecd3764d6e7063cc08209029dda2d