feat: ban/unban/kick system and ephemeral notifications
This commit is contained in:
parent
b92974ffff
commit
9b8c6aa673
|
@ -23,7 +23,10 @@ type
|
|||
CommunityTokenPermissionDeleted,
|
||||
CommunityTokenPermissionCreationFailed,
|
||||
CommunityTokenPermissionUpdateFailed,
|
||||
CommunityTokenPermissionDeletionFailed
|
||||
CommunityTokenPermissionDeletionFailed,
|
||||
CommunityMemberKicked,
|
||||
CommunityMemberBanned,
|
||||
CommunityMemberUnbanned
|
||||
|
||||
NotificationDetails* = object
|
||||
notificationType*: NotificationType # the default value is `UnknownNotification`
|
||||
|
|
|
@ -88,6 +88,10 @@ QtObject:
|
|||
signalConnect(singletonInstance.globalEvents, "showCommunityTokenPermissionUpdateFailedNotification(QString, QString, QString)", self, "onShowCommunityTokenPermissionUpdateFailedNotification(QString, QString, QString)", 2)
|
||||
signalConnect(singletonInstance.globalEvents, "showCommunityTokenPermissionDeletionFailedNotification(QString, QString, QString)", self, "onShowCommunityTokenPermissionDeletionFailedNotification(QString, QString, QString)", 2)
|
||||
|
||||
signalConnect(singletonInstance.globalEvents, "showCommunityMemberKickedNotification(QString, QString, QString)", self, "onShowCommunityMemberKickedNotification(QString, QString, QString)", 2)
|
||||
signalConnect(singletonInstance.globalEvents, "showCommunityMemberBannedNotification(QString, QString, QString)", self, "onShowCommunityMemberBannedNotification(QString, QString, QString)", 2)
|
||||
signalConnect(singletonInstance.globalEvents, "showCommunityMemberUnbannedNotification(QString, QString, QString)", self, "onShowCommunityMemberUnbannedNotification(QString, QString, QString)", 2)
|
||||
|
||||
self.notificationSetUp = true
|
||||
|
||||
proc init*(self: NotificationsManager) =
|
||||
|
@ -205,6 +209,18 @@ QtObject:
|
|||
proc onMeMentionedIconBadgeNotification(self: NotificationsManager, allMentions: int) {.slot.} =
|
||||
self.osNotification.showIconBadgeNotification(allMentions)
|
||||
|
||||
proc onShowCommunityMemberKickedNotification*(self: NotificationsManager, title: string, message: string, sectionId: string) {.slot.} =
|
||||
let details = NotificationDetails(notificationType: NotificationType.CommunityMemberKicked, sectionId: sectionId, isCommunitySection: true)
|
||||
self.processNotification(title, message, details)
|
||||
|
||||
proc onShowCommunityMemberBannedNotification*(self: NotificationsManager, title: string, message: string, sectionId: string) {.slot.} =
|
||||
let details = NotificationDetails(notificationType: NotificationType.CommunityMemberBanned, sectionId: sectionId, isCommunitySection: true)
|
||||
self.processNotification(title, message, details)
|
||||
|
||||
proc onShowCommunityMemberUnbannedNotification*(self: NotificationsManager, title: string, message: string, sectionId: string) {.slot.} =
|
||||
let details = NotificationDetails(notificationType: NotificationType.CommunityMemberUnbanned, sectionId: sectionId, isCommunitySection: true)
|
||||
self.processNotification(title, message, details)
|
||||
|
||||
proc notificationCheck(self: NotificationsManager, title: string, message: string, details: NotificationDetails,
|
||||
notificationWay: string) =
|
||||
var data = NotificationArgs(title: title, message: message, details: details)
|
||||
|
|
|
@ -50,3 +50,9 @@ QtObject:
|
|||
sectionId: string) {.signal.}
|
||||
|
||||
proc meMentionedIconBadgeNotification*(self: GlobalEvents, allMentions: int) {.signal.}
|
||||
|
||||
proc showCommunityMemberKickedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
|
||||
|
||||
proc showCommunityMemberBannedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
|
||||
|
||||
proc showCommunityMemberUnbannedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
|
|
@ -6,6 +6,14 @@ type
|
|||
Success
|
||||
Danger
|
||||
|
||||
type EphemeralActionType* {.pure} = enum
|
||||
None = 0
|
||||
NavigateToCommunityAdmin
|
||||
OpenFinaliseOwnershipPopup
|
||||
OpenSendModalPopup
|
||||
ViewTransactionDetails
|
||||
OpenFirstCommunityTokenPopup
|
||||
|
||||
type
|
||||
Item* = object
|
||||
id: int64
|
||||
|
@ -19,7 +27,7 @@ type
|
|||
loading: bool
|
||||
ephNotifType: EphemeralNotificationType
|
||||
url: string
|
||||
actionType: int
|
||||
actionType: EphemeralActionType
|
||||
actionData: string
|
||||
details: NotificationDetails
|
||||
|
||||
|
@ -33,7 +41,7 @@ proc initItem*(id: int64,
|
|||
loading = false,
|
||||
ephNotifType = EphemeralNotificationType.Default,
|
||||
url = "",
|
||||
actionType = 0, # It means, no action enabled
|
||||
actionType = EphemeralActionType.None, # It means, no action enabled
|
||||
actionData = "",
|
||||
details: NotificationDetails): Item =
|
||||
result = Item()
|
||||
|
@ -85,7 +93,7 @@ proc ephNotifType*(self: Item): EphemeralNotificationType =
|
|||
proc url*(self: Item): string =
|
||||
self.url
|
||||
|
||||
proc actionType*(self: Item): int =
|
||||
proc actionType*(self: Item): EphemeralActionType =
|
||||
self.actionType
|
||||
|
||||
proc actionData*(self: Item): string =
|
||||
|
|
|
@ -84,7 +84,7 @@ QtObject:
|
|||
of ModelRole.Url:
|
||||
result = newQVariant(item.url)
|
||||
of ModelRole.ActionType:
|
||||
result = newQVariant(item.actionType)
|
||||
result = newQVariant(item.actionType.int)
|
||||
of ModelRole.ActionData:
|
||||
result = newQVariant(item.actionData)
|
||||
|
||||
|
|
|
@ -822,6 +822,9 @@ method setActiveSection*[T](self: Module[T], item: SectionItem, skipSavingInSett
|
|||
|
||||
method setActiveSectionById*[T](self: Module[T], id: string) =
|
||||
let item = self.view.model().getItemById(id)
|
||||
if item.isEmpty():
|
||||
discard self.communitiesModule.spectateCommunity(id)
|
||||
else:
|
||||
self.setActiveSection(item)
|
||||
|
||||
proc notifySubModulesAboutChange[T](self: Module[T], sectionId: string) =
|
||||
|
@ -1231,10 +1234,37 @@ method onAcceptRequestToJoinSuccess*[T](self: Module[T], communityId: string, me
|
|||
item.updatePendingRequestLoadingState(memberKey, false)
|
||||
|
||||
method onMembershipStatusUpdated*[T](self: Module[T], communityId: string, memberPubkey: string, status: MembershipRequestState) =
|
||||
let myPublicKey = singletonInstance.userProfile.getPubKey()
|
||||
let communityDto = self.controller.getCommunityById(communityId)
|
||||
|
||||
if myPublicKey == memberPubkey:
|
||||
case status:
|
||||
of MembershipRequestState.Banned:
|
||||
singletonInstance.globalEvents.showCommunityMemberBannedNotification(fmt "You've been banned from {communityDto.name}", "", communityId)
|
||||
of MembershipRequestState.Kicked:
|
||||
singletonInstance.globalEvents.showCommunityMemberKickedNotification(fmt "You were kicked from {communityDto.name}", "", communityId)
|
||||
of MembershipRequestState.Unbanned:
|
||||
singletonInstance.globalEvents.showCommunityMemberUnbannedNotification(fmt "You were unbanned from {communityDto.name}", "", communityId)
|
||||
else:
|
||||
discard
|
||||
elif communityDto.isControlNode:
|
||||
let (contactName, _, _) = self.controller.getContactNameAndImage(memberPubkey)
|
||||
let item = self.view.model().getItemById(communityId)
|
||||
if item.id != "":
|
||||
item.updateMembershipStatus(memberPubkey, status)
|
||||
|
||||
case status:
|
||||
of MembershipRequestState.Banned:
|
||||
self.displayEphemeralNotification(fmt "{contactName} was banned from {communityDto.name}", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "")
|
||||
|
||||
of MembershipRequestState.Kicked:
|
||||
self.displayEphemeralNotification(fmt "{contactName} was kicked from {communityDto.name}", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "")
|
||||
|
||||
of MembershipRequestState.Unbanned:
|
||||
self.displayEphemeralNotification(fmt "{contactName} unbanned from {communityDto.name}", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "")
|
||||
else:
|
||||
discard
|
||||
|
||||
method calculateProfileSectionHasNotification*[T](self: Module[T]): bool =
|
||||
return not self.controller.isMnemonicBackedUp()
|
||||
|
||||
|
@ -1280,7 +1310,7 @@ method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle
|
|||
finalEphNotifType = EphemeralNotificationType.Danger
|
||||
|
||||
let item = ephemeral_notification_item.initItem(id, title, TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS, subTitle, "", icon, "",
|
||||
loading, finalEphNotifType, url, 0, "", details)
|
||||
loading, finalEphNotifType, url, EphemeralActionType.None, "", details)
|
||||
self.view.ephemeralNotificationModel().addItem(item)
|
||||
|
||||
# TO UNIFY with the one above.
|
||||
|
@ -1296,7 +1326,7 @@ method displayEphemeralWithActionNotification*[T](self: Module[T], title: string
|
|||
finalEphNotifType = EphemeralNotificationType.Danger
|
||||
|
||||
let item = ephemeral_notification_item.initItem(id, title, TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS, subTitle, "", icon, iconColor,
|
||||
loading, finalEphNotifType, "", actionType, actionData, details)
|
||||
loading, finalEphNotifType, "", EphemeralActionType(actionType), actionData, details)
|
||||
self.view.ephemeralNotificationModel().addItem(item)
|
||||
|
||||
# TO UNIFY with the one above.
|
||||
|
@ -1313,11 +1343,11 @@ method displayEphemeralImageWithActionNotification*[T](self: Module[T], title: s
|
|||
|
||||
|
||||
let item = ephemeral_notification_item.initItem(id, title, TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS, subTitle, image, "", "", false,
|
||||
finalEphNotifType, "", actionType, actionData, details)
|
||||
finalEphNotifType, "", EphemeralActionType(actionType), actionData, details)
|
||||
self.view.ephemeralNotificationModel().addItem(item)
|
||||
|
||||
method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle: string, details: NotificationDetails) =
|
||||
if(details.notificationType == NotificationType.NewMessage or
|
||||
if details.notificationType == NotificationType.NewMessage or
|
||||
details.notificationType == NotificationType.NewMessageWithPersonalMention or
|
||||
details.notificationType == NotificationType.CommunityTokenPermissionCreated or
|
||||
details.notificationType == NotificationType.CommunityTokenPermissionUpdated or
|
||||
|
@ -1325,17 +1355,26 @@ method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle
|
|||
details.notificationType == NotificationType.CommunityTokenPermissionCreationFailed or
|
||||
details.notificationType == NotificationType.CommunityTokenPermissionUpdateFailed or
|
||||
details.notificationType == NotificationType.CommunityTokenPermissionDeletionFailed or
|
||||
details.notificationType == NotificationType.NewMessageWithGlobalMention):
|
||||
details.notificationType == NotificationType.NewMessageWithGlobalMention:
|
||||
self.displayEphemeralNotification(title, subTitle, "", false, EphemeralNotificationType.Default.int, "", details)
|
||||
|
||||
elif(details.notificationType == NotificationType.NewContactRequest or
|
||||
elif details.notificationType == NotificationType.NewContactRequest or
|
||||
details.notificationType == NotificationType.IdentityVerificationRequest or
|
||||
details.notificationType == NotificationType.ContactRemoved):
|
||||
details.notificationType == NotificationType.ContactRemoved:
|
||||
self.displayEphemeralNotification(title, subTitle, "contact", false, EphemeralNotificationType.Default.int, "", details)
|
||||
|
||||
elif(details.notificationType == NotificationType.AcceptedContactRequest):
|
||||
elif details.notificationType == NotificationType.AcceptedContactRequest:
|
||||
self.displayEphemeralNotification(title, subTitle, "checkmark-circle", false, EphemeralNotificationType.Success.int, "", details)
|
||||
|
||||
elif details.notificationType == NotificationType.CommunityMemberKicked:
|
||||
self.displayEphemeralNotification(title, subTitle, "communities", false, EphemeralNotificationType.Danger.int, "", details)
|
||||
|
||||
elif details.notificationType == NotificationType.CommunityMemberBanned:
|
||||
self.displayEphemeralNotification(title, subTitle, "communities", false, EphemeralNotificationType.Danger.int, "", details)
|
||||
|
||||
elif details.notificationType == NotificationType.CommunityMemberUnbanned:
|
||||
self.displayEphemeralWithActionNotification(title, "Visit community" , "communities", "", false, EphemeralNotificationType.Success.int, EphemeralActionType.NavigateToCommunityAdmin.int, details.sectionId)
|
||||
|
||||
method removeEphemeralNotification*[T](self: Module[T], id: int64) =
|
||||
self.view.ephemeralNotificationModel().removeItemWithId(id)
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ type MembershipRequestState* {.pure} = enum
|
|||
UnbannedPending = 9,
|
||||
KickedPending = 10,
|
||||
AwaitingAddress = 11,
|
||||
Unbanned = 12,
|
||||
|
||||
type
|
||||
ContractTransactionStatus* {.pure.} = enum
|
||||
|
|
|
@ -41,6 +41,8 @@ type
|
|||
BanPending,
|
||||
UnbanPending,
|
||||
KickPending
|
||||
Unbanned,
|
||||
Kicked
|
||||
|
||||
type CommunityMembershipRequestDto* = object
|
||||
id*: string
|
||||
|
@ -479,6 +481,7 @@ proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): Membersh
|
|||
return MembershipRequestState.UnbannedPending
|
||||
of CommunityMemberPendingBanOrKick.KickPending:
|
||||
return MembershipRequestState.KickedPending
|
||||
else:
|
||||
return MembershipRequestState.None
|
||||
|
||||
proc toCommunitySettingsDto*(jsonObj: JsonNode): CommunitySettingsDto =
|
||||
|
|
|
@ -731,11 +731,31 @@ QtObject:
|
|||
self.events.emit(SIGNAL_COMMUNITY_JOINED, CommunityArgs(community: community, fromUserAction: false))
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community]))
|
||||
|
||||
if wasJoined and not community.joined and not community.isMember:
|
||||
if not community.spectated:
|
||||
self.events.emit(SIGNAL_COMMUNITY_LEFT, CommunityIdArgs(communityId: community.id))
|
||||
else:
|
||||
# If we were kicked due to ownership change - we will stay in a spectate mode
|
||||
if community.spectated:
|
||||
self.events.emit(SIGNAL_COMMUNITY_KICKED, CommunityArgs(community: community))
|
||||
else:
|
||||
# We were kicked or banned, leave the community
|
||||
self.events.emit(SIGNAL_COMMUNITY_LEFT, CommunityIdArgs(communityId: community.id))
|
||||
var status = MembershipRequestState.Kicked
|
||||
if community.pendingAndBannedMembers.hasKey(myPublicKey) and
|
||||
community.pendingAndBannedMembers[myPublicKey] == CommunityMemberPendingBanOrKick.Banned:
|
||||
status = MembershipRequestState.Banned
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED, CommunityMemberStatusUpdatedArgs(
|
||||
communityId: community.id,
|
||||
memberPubkey: myPublicKey,
|
||||
status: status))
|
||||
|
||||
# Check if we were unbanned
|
||||
if not wasJoined and not community.joined and prevCommunity.pendingAndBannedMembers.hasKey(myPublicKey) and not
|
||||
community.pendingAndBannedMembers.hasKey(myPublicKey):
|
||||
self.events.emit(SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED, CommunityMemberStatusUpdatedArgs(
|
||||
communityId: community.id,
|
||||
memberPubkey: myPublicKey,
|
||||
status: MembershipRequestState.Unbanned))
|
||||
|
||||
except Exception as e:
|
||||
error "Error handling community updates", msg = e.msg
|
||||
|
@ -2133,10 +2153,13 @@ QtObject:
|
|||
var status: MembershipRequestState = MembershipRequestState.None
|
||||
if community.pendingAndBannedMembers.hasKey(memberPubkey):
|
||||
status = community.pendingAndBannedMembers[memberPubkey].toMembershipRequestState()
|
||||
else:
|
||||
for member in community.members:
|
||||
if member.id == memberPubkey:
|
||||
status = MembershipRequestState.Accepted
|
||||
|
||||
if status == MembershipRequestState.None:
|
||||
let prevCommunity = self.communities[community.id]
|
||||
if prevCommunity.pendingAndBannedMembers.hasKey(memberPubkey):
|
||||
status = MembershipRequestState.Unbanned
|
||||
elif len(prevCommunity.members) > len(community.members):
|
||||
status = MembershipRequestState.Kicked
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED, CommunityMemberStatusUpdatedArgs(
|
||||
communityId: community.id,
|
||||
|
|
|
@ -1229,7 +1229,8 @@ QtObject {
|
|||
BannedPending,
|
||||
UnbannedPending,
|
||||
KickedPending,
|
||||
AwaitingAddress
|
||||
AwaitingAddress,
|
||||
Unbanned
|
||||
}
|
||||
|
||||
readonly property QtObject walletAccountColors: QtObject {
|
||||
|
|
Loading…
Reference in New Issue