feat: ban/unban/kick system and ephemeral notifications

This commit is contained in:
Mykhailo Prakhov 2024-03-01 12:24:09 +01:00 committed by Jonathan Rainville
parent b92974ffff
commit 9b8c6aa673
10 changed files with 184 additions and 84 deletions

View File

@ -23,7 +23,10 @@ type
CommunityTokenPermissionDeleted,
CommunityTokenPermissionCreationFailed,
CommunityTokenPermissionUpdateFailed,
CommunityTokenPermissionDeletionFailed
CommunityTokenPermissionDeletionFailed,
CommunityMemberKicked,
CommunityMemberBanned,
CommunityMemberUnbanned
NotificationDetails* = object
notificationType*: NotificationType # the default value is `UnknownNotification`
@ -41,14 +44,14 @@ proc isEmpty*(self: NotificationDetails): bool =
proc toNotificationDetails*(jsonObj: JsonNode): NotificationDetails =
var notificationType: int
if (not (jsonObj.getProp("notificationType", notificationType) and
if (not (jsonObj.getProp("notificationType", notificationType) and
jsonObj.getProp("sectionId", result.sectionId) and
jsonObj.getProp("isCommunitySection", result.isCommunitySection) and
jsonObj.getProp("sectionActive", result.sectionActive) and
jsonObj.getProp("chatId", result.chatId) and
jsonObj.getProp("chatActive", result.chatActive) and
jsonObj.getProp("isOneToOne", result.isOneToOne) and
jsonObj.getProp("isGroupChat", result.isGroupChat) and
jsonObj.getProp("isCommunitySection", result.isCommunitySection) and
jsonObj.getProp("sectionActive", result.sectionActive) and
jsonObj.getProp("chatId", result.chatId) and
jsonObj.getProp("chatActive", result.chatActive) and
jsonObj.getProp("isOneToOne", result.isOneToOne) and
jsonObj.getProp("isGroupChat", result.isGroupChat) and
jsonObj.getProp("messageId", result.messageId))):
return NotificationDetails()

View File

@ -63,21 +63,21 @@ QtObject:
self.soundManager = newStatusSoundManager()
signalConnect(self.osNotification, "notificationClicked(QString)", self, "onOSNotificationClicked(QString)", 2)
signalConnect(singletonInstance.globalEvents, "showTestNotification(QString, QString)",
signalConnect(singletonInstance.globalEvents, "showTestNotification(QString, QString)",
self, "onShowTestNotification(QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "showMessageNotification(QString, QString, QString, bool, bool, QString, bool, QString, int, bool, bool)",
signalConnect(singletonInstance.globalEvents, "showMessageNotification(QString, QString, QString, bool, bool, QString, bool, QString, int, bool, bool)",
self, "onShowMessageNotification(QString, QString, QString, bool, bool, QString, bool, QString, int, bool, bool)", 2)
signalConnect(singletonInstance.globalEvents, "showNewContactRequestNotification(QString, QString, QString)",
signalConnect(singletonInstance.globalEvents, "showNewContactRequestNotification(QString, QString, QString)",
self, "onShowNewContactRequestNotification(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "showAcceptedContactRequest(QString, QString, QString)",
self, "onShowAcceptedContactRequest(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "showContactRemoved(QString, QString, QString)",
self, "onShowContactRemoved(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "newCommunityMembershipRequestNotification(QString, QString, QString)",
signalConnect(singletonInstance.globalEvents, "newCommunityMembershipRequestNotification(QString, QString, QString)",
self, "onNewCommunityMembershipRequestNotification(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "myRequestToJoinCommunityAcccepted(QString, QString, QString)",
signalConnect(singletonInstance.globalEvents, "myRequestToJoinCommunityAcccepted(QString, QString, QString)",
self, "onMyRequestToJoinCommunityAcccepted(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "myRequestToJoinCommunityRejected(QString, QString, QString)",
signalConnect(singletonInstance.globalEvents, "myRequestToJoinCommunityRejected(QString, QString, QString)",
self, "onMyRequestToJoinCommunityRejected(QString, QString, QString)", 2)
signalConnect(singletonInstance.globalEvents, "meMentionedIconBadgeNotification(int)",
self, "onMeMentionedIconBadgeNotification(int)", 2)
@ -88,12 +88,16 @@ 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) =
self.events.once(FAKE_LOADING_SCREEN_FINISHED) do(e:Args):
self.onAppReady()
proc showOSNotification(self: NotificationsManager, title: string, message: string, identifier: string) =
if defined(windows):
let data = NotificationArgs(title: title, message: message)
@ -107,7 +111,7 @@ QtObject:
## This slot is called once user clicks OS notificaiton bubble, "identifier"
## contains data which uniquely define that notification.
debug "OS notification clicked", identifier=identifier
# Make the app the top most window.
app_makeItActive(singletonInstance.engine)
@ -119,7 +123,7 @@ QtObject:
info "Test notification was clicked"
return
if(details.notificationType == NotificationType.NewMessage or
if(details.notificationType == NotificationType.NewMessage or
details.notificationType == NotificationType.NewMessageWithPersonalMention or
details.notificationType == NotificationType.NewMessageWithGlobalMention):
let data = ActiveSectionChatArgs(sectionId: details.sectionId, chatId: details.chatId, messageId: details.messageId)
@ -131,15 +135,15 @@ QtObject:
let details = NotificationDetails(notificationType: NotificationType.TestNotification)
self.processNotification(title, message, details)
proc onShowMessageNotification(self: NotificationsManager, title: string, message: string, sectionId: string,
isCommunitySection: bool, isSectionActive: bool, chatId: string, isChatActive: bool, messageId: string,
proc onShowMessageNotification(self: NotificationsManager, title: string, message: string, sectionId: string,
isCommunitySection: bool, isSectionActive: bool, chatId: string, isChatActive: bool, messageId: string,
notificationType: int, isOneToOne: bool, isGroupChat: bool) {.slot.} =
let details = NotificationDetails(
notificationType: notificationType.NotificationType,
sectionId: sectionId,
sectionId: sectionId,
isCommunitySection: isCommunitySection,
sectionActive: isSectionActive,
chatId: chatId,
chatId: chatId,
chatActive: isChatActive,
isOneToOne: isOneToOne,
isGroupChat: isGroupChat,
@ -170,12 +174,12 @@ QtObject:
let details = NotificationDetails(notificationType: NotificationType.CommunityTokenPermissionDeletionFailed, sectionId: sectionId, isCommunitySection: true)
self.processNotification(title, message, details)
proc onShowNewContactRequestNotification*(self: NotificationsManager, title: string, message: string,
proc onShowNewContactRequestNotification*(self: NotificationsManager, title: string, message: string,
sectionId: string) {.slot.} =
let details = NotificationDetails(notificationType: NotificationType.NewContactRequest, sectionId: sectionId)
self.processNotification(title, message, details)
proc onShowAcceptedContactRequest*(self: NotificationsManager, title: string, message: string,
proc onShowAcceptedContactRequest*(self: NotificationsManager, title: string, message: string,
sectionId: string) {.slot.} =
let details = NotificationDetails(notificationType: NotificationType.AcceptedContactRequest, sectionId: sectionId)
self.processNotification(title, message, details)
@ -185,26 +189,38 @@ QtObject:
let details = NotificationDetails(notificationType: NotificationType.ContactRemoved, sectionId: sectionId)
self.processNotification(title, message, details)
proc onNewCommunityMembershipRequestNotification*(self: NotificationsManager, title: string, message: string,
proc onNewCommunityMembershipRequestNotification*(self: NotificationsManager, title: string, message: string,
sectionId: string) {.slot.} =
let details = NotificationDetails(notificationType: NotificationType.JoinCommunityRequest, sectionId: sectionId)
self.processNotification(title, message, details)
proc onMyRequestToJoinCommunityAcccepted*(self: NotificationsManager, title: string, message: string,
proc onMyRequestToJoinCommunityAcccepted*(self: NotificationsManager, title: string, message: string,
sectionId: string) {.slot.} =
let details = NotificationDetails(notificationType: NotificationType.MyRequestToJoinCommunityAccepted,
let details = NotificationDetails(notificationType: NotificationType.MyRequestToJoinCommunityAccepted,
sectionId: sectionId)
self.processNotification(title, message, details)
proc onMyRequestToJoinCommunityRejected*(self: NotificationsManager, title: string, message: string,
proc onMyRequestToJoinCommunityRejected*(self: NotificationsManager, title: string, message: string,
sectionId: string) {.slot.} =
let details = NotificationDetails(notificationType: NotificationType.MyRequestToJoinCommunityRejected,
let details = NotificationDetails(notificationType: NotificationType.MyRequestToJoinCommunityRejected,
sectionId: sectionId)
self.processNotification(title, message, details)
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)
@ -213,32 +229,32 @@ QtObject:
debug "Add AC notification", title=title, message=message
self.events.emit(SIGNAL_ADD_NOTIFICATION_TO_ACTIVITY_CENTER, data)
# An exemption from the diagrams, at least for now, is that we don't need to implement the "Badge Check" block here,
# An exemption from the diagrams, at least for now, is that we don't need to implement the "Badge Check" block here,
# cause that's already handled in appropriate modules.
let appIsActive = app_isActive(singletonInstance.engine)
if details.notificationType == NotificationType.NewMessage or
if details.notificationType == NotificationType.NewMessage or
details.notificationType == NotificationType.NewMessageWithPersonalMention or
details.notificationType == NotificationType.NewMessageWithGlobalMention or
details.notificationType == NotificationType.NewContactRequest or
details.notificationType == NotificationType.NewContactRequest or
details.notificationType == NotificationType.ContactRemoved or
details.notificationType == NotificationType.IdentityVerificationRequest:
if notificationWay == VALUE_NOTIF_DELIVER_QUIETLY:
return
if (details.notificationType == NotificationType.NewMessage or
if (details.notificationType == NotificationType.NewMessage or
details.notificationType == NotificationType.NewMessageWithPersonalMention or
details.notificationType == NotificationType.NewMessageWithGlobalMention) and
details.sectionActive and
details.sectionActive and
details.chatActive and appIsActive:
return
if appIsActive:
debug "Add APP notification", title=title, message=message
self.events.emit(SIGNAL_DISPLAY_APP_NOTIFICATION, data)
if not appIsActive or details.notificationType == NotificationType.TestNotification:
# Check anonymity level
if(self.settingsService.getNotificationMessagePreview() == PREVIEW_ANONYMOUS):
@ -249,18 +265,18 @@ QtObject:
let identifier = $(details.toJsonNode())
debug "Add OS notification", title=data.title, message=data.message, identifier=identifier
self.showOSNotification(data.title, data.message, identifier)
self.showOSNotification(data.title, data.message, identifier)
if self.settingsService.getNotificationSoundsEnabled():
self.soundManager.setPlayerVolume(self.settingsService.getNotificationVolume())
self.soundManager.playSound(NOTIFICATION_SOUND)
proc processNotification(self: NotificationsManager, title: string, message: string, details: NotificationDetails) =
## This is the main method which need to be called to process an event according to the preferences set in the
## This is the main method which need to be called to process an event according to the preferences set in the
## "Notifications & Sounds" panel of the "Settings" section.
##
##
## This method determines whether a notification need to be displayed or not, what notification to display, whether
## to display App or OS notification and/or add notification to Activity Center, what level of anonymous to apply,
## to display App or OS notification and/or add notification to Activity Center, what level of anonymous to apply,
## whether to play sound or not and so...
# The flow used here follows these diagrams:
@ -274,7 +290,7 @@ QtObject:
if(details.notificationType == NotificationType.NewContactRequest):
if(self.settingsService.getNotifSettingContactRequests() != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, self.settingsService.getNotifSettingContactRequests())
return
return
# In case of identity verification request
elif(details.notificationType == NotificationType.IdentityVerificationRequest):
@ -283,7 +299,7 @@ QtObject:
return
# In case of new message (regardless it's message with mention or not)
elif(details.notificationType == NotificationType.NewMessage or
elif(details.notificationType == NotificationType.NewMessage or
details.notificationType == NotificationType.NewMessageWithPersonalMention or
details.notificationType == NotificationType.NewMessageWithGlobalMention):
if(self.settingsService.getNotifSettingAllMessages() != VALUE_NOTIF_TURN_OFF):
@ -296,17 +312,17 @@ QtObject:
if(exemptions.muteAllMessages):
return
if(details.notificationType == NotificationType.NewMessageWithPersonalMention and
if(details.notificationType == NotificationType.NewMessageWithPersonalMention and
exemptions.personalMentions != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, exemptions.personalMentions)
return
if(details.notificationType == NotificationType.NewMessageWithGlobalMention and
if(details.notificationType == NotificationType.NewMessageWithGlobalMention and
exemptions.globalMentions != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, exemptions.globalMentions)
return
if(details.notificationType == NotificationType.NewMessage and
if(details.notificationType == NotificationType.NewMessage and
exemptions.otherMessages != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, exemptions.otherMessages)
return
@ -320,16 +336,16 @@ QtObject:
(details.isGroupChat and details.notificationType != NotificationType.NewMessageWithPersonalMention):
return
if(details.notificationType == NotificationType.NewMessageWithPersonalMention and
if(details.notificationType == NotificationType.NewMessageWithPersonalMention and
self.settingsService.getNotifSettingPersonalMentions() != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, self.settingsService.getNotifSettingPersonalMentions())
return
if(details.notificationType == NotificationType.NewMessageWithGlobalMention and
if(details.notificationType == NotificationType.NewMessageWithGlobalMention and
self.settingsService.getNotifSettingGlobalMentions() != VALUE_NOTIF_TURN_OFF):
self.notificationCheck(title, message, details, self.settingsService.getNotifSettingGlobalMentions())
return
if(details.notificationType == NotificationType.NewMessage):
if(details.isOneToOne and
self.settingsService.getNotifSettingOneToOneChats() != VALUE_NOTIF_TURN_OFF):

View File

@ -14,7 +14,7 @@ QtObject:
result.setup
proc showTestNotification*(self: GlobalEvents, title: string, message: string) {.signal.}
proc showCommunityTokenPermissionCreatedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
proc showCommunityTokenPermissionUpdatedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
@ -27,10 +27,10 @@ QtObject:
proc showCommunityTokenPermissionDeletionFailedNotification*(self: GlobalEvents, sectionId: string, title: string, message: string) {.signal.}
proc showMessageNotification*(self: GlobalEvents, title: string, message: string, sectionId: string,
isCommunitySection: bool, isSectionActive: bool, chatId: string, isChatActive: bool, messageId: string,
proc showMessageNotification*(self: GlobalEvents, title: string, message: string, sectionId: string,
isCommunitySection: bool, isSectionActive: bool, chatId: string, isChatActive: bool, messageId: string,
notificationType: int, isOneToOne: bool, isGroupChat: bool) {.signal.}
proc showNewContactRequestNotification*(self: GlobalEvents, title: string, message: string,
sectionId: string) {.signal.}
@ -39,14 +39,20 @@ QtObject:
proc showContactRemoved*(self: GlobalEvents, title: string, message: string,
sectionId: string) {.signal.}
proc newCommunityMembershipRequestNotification*(self: GlobalEvents, title: string, message: string,
sectionId: string) {.signal.}
proc myRequestToJoinCommunityAcccepted*(self: GlobalEvents, title: string, message: string,
proc newCommunityMembershipRequestNotification*(self: GlobalEvents, title: string, message: string,
sectionId: string) {.signal.}
proc myRequestToJoinCommunityRejected*(self: GlobalEvents, title: string, message: string,
proc myRequestToJoinCommunityAcccepted*(self: GlobalEvents, title: string, message: string,
sectionId: string) {.signal.}
proc myRequestToJoinCommunityRejected*(self: GlobalEvents, title: string, message: string,
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.}

View File

@ -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()
@ -63,7 +71,7 @@ proc title*(self: Item): string =
proc durationInMs*(self: Item): int =
self.durationInMs
proc subTitle*(self: Item): string =
self.subTitle
@ -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 =

View File

@ -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)
@ -93,7 +93,7 @@ QtObject:
if(self.items[i].id == id):
return i
return -1
proc getItemWithId*(self: Model, id: int64): Item =
let ind = self.findIndexById(id)
if(ind == -1):

View File

@ -822,7 +822,10 @@ method setActiveSection*[T](self: Module[T], item: SectionItem, skipSavingInSett
method setActiveSectionById*[T](self: Module[T], id: string) =
let item = self.view.model().getItemById(id)
self.setActiveSection(item)
if item.isEmpty():
discard self.communitiesModule.spectateCommunity(id)
else:
self.setActiveSection(item)
proc notifySubModulesAboutChange[T](self: Module[T], sectionId: string) =
for cModule in self.channelGroupModules.values:
@ -1231,9 +1234,36 @@ 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 item = self.view.model().getItemById(communityId)
if item.id != "":
item.updateMembershipStatus(memberPubkey, status)
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)

View File

@ -71,6 +71,7 @@ type MembershipRequestState* {.pure} = enum
UnbannedPending = 9,
KickedPending = 10,
AwaitingAddress = 11,
Unbanned = 12,
type
ContractTransactionStatus* {.pure.} = enum

View File

@ -41,6 +41,8 @@ type
BanPending,
UnbanPending,
KickPending
Unbanned,
Kicked
type CommunityMembershipRequestDto* = object
id*: string
@ -479,7 +481,8 @@ proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): Membersh
return MembershipRequestState.UnbannedPending
of CommunityMemberPendingBanOrKick.KickPending:
return MembershipRequestState.KickedPending
return MembershipRequestState.None
else:
return MembershipRequestState.None
proc toCommunitySettingsDto*(jsonObj: JsonNode): CommunitySettingsDto =
result = CommunitySettingsDto()

View File

@ -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,

View File

@ -1229,7 +1229,8 @@ QtObject {
BannedPending,
UnbannedPending,
KickedPending,
AwaitingAddress
AwaitingAddress,
Unbanned
}
readonly property QtObject walletAccountColors: QtObject {