feat(@desktop/community): allow owner delete all messages during the ban and ban/unban AC notifications (#13653)
This commit is contained in:
parent
34f801231c
commit
12569d795f
|
@ -1,4 +1,4 @@
|
|||
import json, chronicles
|
||||
import json, chronicles, tables
|
||||
|
||||
import base
|
||||
|
||||
|
@ -28,7 +28,8 @@ type MessageSignal* = ref object of Signal
|
|||
membershipRequests*: seq[CommunityMembershipRequestDto]
|
||||
activityCenterNotifications*: seq[ActivityCenterNotificationDto]
|
||||
statusUpdates*: seq[StatusUpdateDto]
|
||||
deletedMessages*: seq[RemovedMessageDto]
|
||||
removedMessages*: seq[RemovedMessageDto]
|
||||
deletedMessages*: Table[string, seq[string]]
|
||||
removedChats*: seq[string]
|
||||
currentStatus*: seq[StatusUpdateDto]
|
||||
settings*: seq[SettingsFieldDto]
|
||||
|
@ -117,7 +118,15 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
|||
|
||||
if e.contains("removedMessages"):
|
||||
for jsonRemovedMessage in e["removedMessages"]:
|
||||
signal.deletedMessages.add(jsonRemovedMessage.toRemovedMessageDto())
|
||||
signal.removedMessages.add(jsonRemovedMessage.toRemovedMessageDto())
|
||||
|
||||
if e.contains("deletedMessages"):
|
||||
let deletedMessagesObj = e["deletedMessages"]
|
||||
for chatId, messageIdsArrayJson in deletedMessagesObj:
|
||||
if not signal.deletedMessages.hasKey(chatId):
|
||||
signal.deletedMessages[chatId] = @[]
|
||||
for messageId in messageIdsArrayJson:
|
||||
signal.deletedMessages[chatId].add(messageId.getStr())
|
||||
|
||||
if e.contains("removedChats"):
|
||||
for removedChatID in e["removedChats"]:
|
||||
|
@ -161,6 +170,5 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
|
|||
if e.contains("updatedProfileShowcases"):
|
||||
for jsonProfileShowcase in e["updatedProfileShowcases"]:
|
||||
signal.updatedProfileShowcases.add(jsonProfileShowcase.toProfileShowcaseDto())
|
||||
|
||||
result = signal
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import NimQml
|
||||
import json
|
||||
import NimQml, tables, json
|
||||
import io_interface
|
||||
|
||||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
|
@ -153,13 +152,20 @@ proc init*(self: Controller) =
|
|||
self.delegate.onMutualContactChanged()
|
||||
self.delegate.onContactDetailsUpdated(args.contactId)
|
||||
|
||||
self.events.on(SIGNAL_MESSAGE_DELETION) do(e: Args):
|
||||
let args = MessageDeletedArgs(e)
|
||||
self.events.on(SIGNAL_MESSAGE_REMOVED) do(e: Args):
|
||||
let args = MessageRemovedArgs(e)
|
||||
if(self.chatId != args.chatId):
|
||||
return
|
||||
# remove from pinned messages model
|
||||
self.delegate.onUnpinMessage(args.messageId)
|
||||
|
||||
self.events.on(SIGNAL_MESSAGES_DELETED) do(e: Args):
|
||||
let args = MessagesDeletedArgs(e)
|
||||
if self.chatId in args.deletedMessages:
|
||||
for deletedMessage in args.deletedMessages[self.chatId]:
|
||||
# delete from pinned messages model
|
||||
self.delegate.onUnpinMessage(deletedMessage)
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_CHANNEL_EDITED) do(e:Args):
|
||||
let args = CommunityChatArgs(e)
|
||||
if(args.chat.communityId != self.sectionId or args.chat.id != self.chatId):
|
||||
|
|
|
@ -131,7 +131,7 @@ proc getChatId*(self: Controller): string =
|
|||
|
||||
proc belongsToCommunity*(self: Controller): bool =
|
||||
return self.belongsToCommunity
|
||||
|
||||
|
||||
proc setLinkPreviewEnabledForThisMessage*(self: Controller, enabled: bool) =
|
||||
self.linkPreviewCurrentMessageSetting = if enabled: UrlUnfurlingMode.Enabled else: UrlUnfurlingMode.Disabled
|
||||
self.delegate.setAskToEnableLinkPreview(false)
|
||||
|
@ -142,18 +142,18 @@ proc resetLinkPreviews(self: Controller) =
|
|||
self.linkPreviewCurrentMessageSetting = self.linkPreviewPersistentSetting
|
||||
self.delegate.setAskToEnableLinkPreview(false)
|
||||
|
||||
proc sendImages*(self: Controller,
|
||||
imagePathsAndDataJson: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
proc sendImages*(self: Controller,
|
||||
imagePathsAndDataJson: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview]): string =
|
||||
self.resetLinkPreviews()
|
||||
self.chatService.sendImages(
|
||||
self.chatId,
|
||||
imagePathsAndDataJson,
|
||||
msg,
|
||||
replyTo,
|
||||
self.chatId,
|
||||
imagePathsAndDataJson,
|
||||
msg,
|
||||
replyTo,
|
||||
preferredUsername,
|
||||
linkPreviews
|
||||
)
|
||||
|
@ -165,10 +165,10 @@ proc sendChatMessage*(self: Controller,
|
|||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview]) =
|
||||
self.resetLinkPreviews()
|
||||
self.chatService.sendChatMessage(self.chatId,
|
||||
msg,
|
||||
replyTo,
|
||||
contentType,
|
||||
self.chatService.sendChatMessage(self.chatId,
|
||||
msg,
|
||||
replyTo,
|
||||
contentType,
|
||||
preferredUsername,
|
||||
linkPreviews
|
||||
)
|
||||
|
@ -288,7 +288,7 @@ proc asyncUnfurlUrls(self: Controller, urls: seq[string]) =
|
|||
proc asyncUnfurlUnknownUrls(self: Controller, urls: seq[string]) =
|
||||
let newUrls = self.linkPreviewCache.unknownUrls(urls)
|
||||
self.asyncUnfurlUrls(newUrls)
|
||||
|
||||
|
||||
proc linkPreviewsFromCache*(self: Controller, urls: seq[string]): Table[string, LinkPreview] =
|
||||
return self.linkPreviewCache.linkPreviews(urls)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import chronicles, uuids, times
|
||||
import chronicles, uuids, times, tables
|
||||
import io_interface
|
||||
|
||||
import ../../../../../../app/global/global_singleton
|
||||
|
@ -182,11 +182,16 @@ proc init*(self: Controller) =
|
|||
self.events.on(SIGNAL_LOGGEDIN_USER_IMAGE_CHANGED) do(e: Args):
|
||||
self.delegate.updateContactDetails(singletonInstance.userProfile.getPubKey())
|
||||
|
||||
self.events.on(SIGNAL_MESSAGE_DELETION) do(e: Args):
|
||||
let args = MessageDeletedArgs(e)
|
||||
self.events.on(SIGNAL_MESSAGE_REMOVED) do(e: Args):
|
||||
let args = MessageRemovedArgs(e)
|
||||
if(self.chatId != args.chatId):
|
||||
return
|
||||
self.delegate.onMessageDeleted(args.messageId, args.deletedBy)
|
||||
self.delegate.onMessageRemoved(args.messageId, args.deletedBy)
|
||||
|
||||
self.events.on(SIGNAL_MESSAGES_DELETED) do(e: Args):
|
||||
let args = MessagesDeletedArgs(e)
|
||||
if self.chatId in args.deletedMessages:
|
||||
self.delegate.onMessagesDeleted(args.deletedMessages[self.chatId])
|
||||
|
||||
self.events.on(SIGNAL_MESSAGE_EDITED) do(e: Args):
|
||||
let args = MessageEditedArgs(e)
|
||||
|
@ -296,7 +301,7 @@ proc deleteMessage*(self: Controller, messageId: string) =
|
|||
|
||||
proc editMessage*(self: Controller, messageId: string, contentType: int, updatedMsg: string) =
|
||||
self.messageService.editMessage(messageId, contentType, updatedMsg)
|
||||
|
||||
|
||||
proc getSearchedMessageId*(self: Controller): string =
|
||||
return self.searchedMessageId
|
||||
|
||||
|
|
|
@ -123,7 +123,10 @@ method getNumberOfPinnedMessages*(self: AccessInterface): int {.base.} =
|
|||
method deleteMessage*(self: AccessInterface, messageId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onMessageDeleted*(self: AccessInterface, messageId, deletedBy: string) {.base.} =
|
||||
method onMessageRemoved*(self: AccessInterface, messageId, removedBy: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onMessagesDeleted*(self: AccessInterface, messageIds: seq[string]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method editMessage*(self: AccessInterface, messageId: string, contentType: int, updatedMsg: string) {.base.} =
|
||||
|
|
|
@ -378,7 +378,7 @@ proc currentUserWalletContainsAddress(self: Module, address: string): bool =
|
|||
return false
|
||||
|
||||
method reevaluateViewLoadingState*(self: Module) =
|
||||
self.view.setLoading(not self.initialMessagesLoaded or
|
||||
self.view.setLoading(not self.initialMessagesLoaded or
|
||||
not self.firstUnseenMessageState.initialized or
|
||||
self.firstUnseenMessageState.fetching or
|
||||
self.view.getMessageSearchOngoing())
|
||||
|
@ -564,16 +564,20 @@ method updateContactDetails*(self: Module, contactId: string) =
|
|||
method deleteMessage*(self: Module, messageId: string) =
|
||||
self.controller.deleteMessage(messageId)
|
||||
|
||||
method onMessageDeleted*(self: Module, messageId, deletedBy: string) =
|
||||
var deletedByValue = deletedBy
|
||||
if deletedBy == "":
|
||||
# deletedBy is empty if it was deleted by the sender
|
||||
method onMessageRemoved*(self: Module, messageId, removedBy: string) =
|
||||
var removedByValue = removedBy
|
||||
if removedBy == "":
|
||||
# removedBy is empty if it was removed by the sender
|
||||
let messageItem = self.view.model().getItemWithMessageId(messageId)
|
||||
if messageItem.id == "":
|
||||
return
|
||||
deletedByValue = messageItem.senderId
|
||||
var deletedByContactDetails = self.controller.getContactDetails(deletedByValue)
|
||||
self.view.model().messageDeleted(messageId, deletedByValue, deletedByContactDetails)
|
||||
removedByValue = messageItem.senderId
|
||||
var removedByContactDetails = self.controller.getContactDetails(removedByValue)
|
||||
self.view.model().messageRemoved(messageId, removedByValue, removedByContactDetails)
|
||||
|
||||
method onMessagesDeleted*(self: Module, messageIds: seq[string]) =
|
||||
for messageId in messageIds:
|
||||
self.view.model().removeItem(messageId)
|
||||
|
||||
method editMessage*(self: Module, messageId: string, contentType: int, updatedMsg: string) =
|
||||
self.controller.editMessage(messageId, contentType, updatedMsg)
|
||||
|
@ -730,7 +734,7 @@ proc updateItemsByAlbum(self: Module, items: var seq[Item], message: MessageDto)
|
|||
for j in 0 ..< item.albumMessageIds.len:
|
||||
if item.albumMessageIds[j] == message.id:
|
||||
return true
|
||||
|
||||
|
||||
var albumImages = item.albumMessageImages
|
||||
var albumMessagesIds = item.albumMessageIds
|
||||
albumMessagesIds.add(message.id)
|
||||
|
@ -770,21 +774,21 @@ proc updateLinkPreviewsContacts(self: Module, item: Item, requestFromMailserver:
|
|||
|
||||
if not requestFromMailserver:
|
||||
continue
|
||||
|
||||
|
||||
debug "updateLinkPreviewsContacts: contact not found, requesting from mailserver", contactId
|
||||
item.linkPreviewModel.onContactDataRequested(contactId)
|
||||
self.controller.requestContactInfo(contactId)
|
||||
|
||||
|
||||
proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserver: bool) =
|
||||
for communityId, url in item.linkPreviewModel.getCommunityLinks().pairs:
|
||||
let community = self.controller.getCommunityById(communityId)
|
||||
|
||||
|
||||
if community.id != "":
|
||||
item.linkPreviewModel.setCommunityInfo(community)
|
||||
|
||||
|
||||
if not requestFromMailserver:
|
||||
continue
|
||||
|
||||
|
||||
debug "updateLinkPreviewsCommunites: requesting from mailserver", communityId
|
||||
let urlData = self.controller.parseSharedUrl(url)
|
||||
item.linkPreviewModel.onCommunityInfoRequested(communityId)
|
||||
|
|
|
@ -600,8 +600,8 @@ proc leaveCommunity*(self: Controller) =
|
|||
proc removeUserFromCommunity*(self: Controller, pubKey: string) =
|
||||
self.communityService.asyncRemoveUserFromCommunity(self.sectionId, pubKey)
|
||||
|
||||
proc banUserFromCommunity*(self: Controller, pubKey: string) =
|
||||
self.communityService.asyncBanUserFromCommunity(self.sectionId, pubKey)
|
||||
proc banUserFromCommunity*(self: Controller, pubKey: string, deleteAllMessages: bool) =
|
||||
self.communityService.asyncBanUserFromCommunity(self.sectionId, pubKey, deleteAllMessages)
|
||||
|
||||
proc unbanUserFromCommunity*(self: Controller, pubKey: string) =
|
||||
self.communityService.asyncUnbanUserFromCommunity(self.sectionId, pubKey)
|
||||
|
|
|
@ -279,7 +279,7 @@ method leaveCommunity*(self: AccessInterface) {.base.} =
|
|||
method removeUserFromCommunity*(self: AccessInterface, pubKey: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method banUserFromCommunity*(self: AccessInterface, pubKey: string) {.base.} =
|
||||
method banUserFromCommunity*(self: AccessInterface, pubKey: string, deleteAllMessages: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method editCommunity*(self: AccessInterface, name: string, description, introMessage, outroMessage: string,
|
||||
|
|
|
@ -1097,8 +1097,8 @@ method leaveCommunity*(self: Module) =
|
|||
method removeUserFromCommunity*(self: Module, pubKey: string) =
|
||||
self.controller.removeUserFromCommunity(pubKey)
|
||||
|
||||
method banUserFromCommunity*(self: Module, pubKey: string) =
|
||||
self.controller.banUserFromCommunity(pubkey)
|
||||
method banUserFromCommunity*(self: Module, pubKey: string, deleteAllMessages: bool) =
|
||||
self.controller.banUserFromCommunity(pubkey, deleteAllMessages)
|
||||
|
||||
method unbanUserFromCommunity*(self: Module, pubKey: string) =
|
||||
self.controller.unbanUserFromCommunity(pubkey)
|
||||
|
|
|
@ -298,8 +298,8 @@ QtObject:
|
|||
proc removeUserFromCommunity*(self: View, pubKey: string) {.slot.} =
|
||||
self.delegate.removeUserFromCommunity(pubKey)
|
||||
|
||||
proc banUserFromCommunity*(self: View, pubKey: string) {.slot.} =
|
||||
self.delegate.banUserFromCommunity(pubKey)
|
||||
proc banUserFromCommunity*(self: View, pubKey: string, deleteAllMessages: bool) {.slot.} =
|
||||
self.delegate.banUserFromCommunity(pubKey, deleteAllMessages)
|
||||
|
||||
proc editCommunity*(self: View, name: string, description: string, introMessage: string, outroMessage: string, access: int,
|
||||
color: string, tags: string, logoJsonData: string, bannerJsonData: string, historyArchiveSupportEnabled: bool,
|
||||
|
|
|
@ -498,7 +498,7 @@ QtObject:
|
|||
self.countChanged()
|
||||
self.updateMessagesWhenQuotedMessageDeleted(messageId)
|
||||
|
||||
proc messageDeleted*(self: Model, messageId: string, deletedBy: string, deletedByContactDetails: ContactDetails) =
|
||||
proc messageRemoved*(self: Model, messageId: string, deletedBy: string, deletedByContactDetails: ContactDetails) =
|
||||
let i = self.findIndexForMessageId(messageId)
|
||||
if(i == -1):
|
||||
return
|
||||
|
@ -846,7 +846,7 @@ QtObject:
|
|||
albumImages.add(messageImage)
|
||||
item.albumMessageImages = albumImages
|
||||
item.albumMessageIds = albumMessagesIds
|
||||
|
||||
|
||||
let index = self.createIndex(i, 0, nil)
|
||||
defer: index.delete
|
||||
self.dataChanged(index, index, @[ModelRole.AlbumMessageImages.int])
|
||||
|
|
|
@ -30,6 +30,8 @@ type ActivityCenterNotificationType* {.pure.}= enum
|
|||
ShareAccounts = 18
|
||||
CommunityTokenReceived = 19
|
||||
FirstCommunityTokenReceived = 20
|
||||
CommunityBanned = 21
|
||||
CommunityUnbanned = 22
|
||||
|
||||
type ActivityCenterGroup* {.pure.}= enum
|
||||
All = 0,
|
||||
|
@ -174,7 +176,9 @@ proc activityCenterNotificationTypesByGroup*(group: ActivityCenterGroup) : seq[i
|
|||
ActivityCenterNotificationType.OwnershipLost.int,
|
||||
ActivityCenterNotificationType.ShareAccounts.int,
|
||||
ActivityCenterNotificationType.CommunityTokenReceived.int,
|
||||
ActivityCenterNotificationType.FirstCommunityTokenReceived.int
|
||||
ActivityCenterNotificationType.FirstCommunityTokenReceived.int,
|
||||
ActivityCenterNotificationType.CommunityBanned.int,
|
||||
ActivityCenterNotificationType.CommunityUnbanned.int
|
||||
]
|
||||
of ActivityCenterGroup.Mentions:
|
||||
return @[ActivityCenterNotificationType.Mention.int]
|
||||
|
@ -186,7 +190,9 @@ proc activityCenterNotificationTypesByGroup*(group: ActivityCenterGroup) : seq[i
|
|||
ActivityCenterNotificationType.CommunityInvitation.int,
|
||||
ActivityCenterNotificationType.CommunityRequest.int,
|
||||
ActivityCenterNotificationType.CommunityMembershipRequest.int,
|
||||
ActivityCenterNotificationType.CommunityKicked.int
|
||||
ActivityCenterNotificationType.CommunityKicked.int,
|
||||
ActivityCenterNotificationType.CommunityBanned.int,
|
||||
ActivityCenterNotificationType.CommunityUnbanned.int
|
||||
]
|
||||
of ActivityCenterGroup.Admin:
|
||||
return @[ActivityCenterNotificationType.CommunityMembershipRequest.int]
|
||||
|
|
|
@ -240,9 +240,9 @@ proc toChannelMember*(jsonObj: JsonNode, memberId: string, joined: bool): ChatMe
|
|||
if(jsonObj.getProp("roles", rolesObj)):
|
||||
for roleObj in rolesObj:
|
||||
roles.add(roleObj.getInt)
|
||||
|
||||
|
||||
result.role = MemberRole.None
|
||||
if roles.contains(MemberRole.Owner.int):
|
||||
if roles.contains(MemberRole.Owner.int):
|
||||
result.role = MemberRole.Owner
|
||||
elif roles.contains(MemberRole.Admin.int):
|
||||
result.role = MemberRole.Admin
|
||||
|
|
|
@ -108,7 +108,7 @@ const SIGNAL_CHAT_UPDATE* = "chatUpdate"
|
|||
const SIGNAL_CHAT_LEFT* = "channelLeft"
|
||||
const SIGNAL_SENDING_FAILED* = "messageSendingFailed"
|
||||
const SIGNAL_SENDING_SUCCESS* = "messageSendingSuccess"
|
||||
const SIGNAL_MESSAGE_DELETED* = "messageDeleted"
|
||||
const SIGNAL_MESSAGE_REMOVE* = "messageRemove"
|
||||
const SIGNAL_CHAT_MUTED* = "chatMuted"
|
||||
const SIGNAL_CHAT_UNMUTED* = "chatUnmuted"
|
||||
const SIGNAL_CHAT_HISTORY_CLEARED* = "chatHistoryCleared"
|
||||
|
@ -271,7 +271,7 @@ QtObject:
|
|||
return i
|
||||
i.inc()
|
||||
return -1
|
||||
|
||||
|
||||
proc chatsWithCategoryHaveUnreadMessages*(self: Service, communityId: string, categoryId: string): bool =
|
||||
if communityId == "" or categoryId == "":
|
||||
return false
|
||||
|
@ -336,7 +336,7 @@ QtObject:
|
|||
self.channelGroups[channelGroupId].chats[index] = self.chats[chat.id]
|
||||
|
||||
proc updateMissingFieldsInCommunityChat(self: Service, channelGroupId: string, newChat: ChatDto): ChatDto =
|
||||
|
||||
|
||||
if not self.channelGroups.contains(channelGroupId):
|
||||
warn "unknown channel group", channelGroupId
|
||||
return
|
||||
|
@ -359,11 +359,11 @@ QtObject:
|
|||
# We need to update missing fields in the chats seq before saving
|
||||
let newChats = channelGroup.chats.mapIt(self.updateMissingFieldsInCommunityChat(channelGroup.id, it))
|
||||
newChannelGroup.chats = newChats
|
||||
|
||||
|
||||
self.channelGroups[channelGroup.id] = newChannelGroup
|
||||
for chat in newChannelGroup.chats:
|
||||
self.updateOrAddChat(chat)
|
||||
|
||||
|
||||
proc updateChannelMembers*(self: Service, channel: ChatDto) =
|
||||
if not self.chats.hasKey(channel.id):
|
||||
return
|
||||
|
@ -412,7 +412,8 @@ QtObject:
|
|||
|
||||
proc processUpdateForTransaction*(self: Service, messageId: string, response: RpcResponse[JsonNode]) =
|
||||
var (chats, _) = self.processMessageUpdateAfterSend(response)
|
||||
self.events.emit(SIGNAL_MESSAGE_DELETED, MessageArgs(id: messageId, channel: chats[0].id))
|
||||
# TODO: Signal is not handled anywhere
|
||||
self.events.emit(SIGNAL_MESSAGE_REMOVE, MessageArgs(id: messageId, channel: chats[0].id))
|
||||
|
||||
proc emitUpdate(self: Service, response: RpcResponse[JsonNode]) =
|
||||
var (chats, _) = self.parseChatResponse(response)
|
||||
|
@ -502,10 +503,10 @@ QtObject:
|
|||
error "Error deleting channel", chatId, msg = e.msg
|
||||
return
|
||||
|
||||
proc sendImages*(self: Service,
|
||||
chatId: string,
|
||||
imagePathsAndDataJson: string,
|
||||
msg: string,
|
||||
proc sendImages*(self: Service,
|
||||
chatId: string,
|
||||
imagePathsAndDataJson: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview] = @[]): string =
|
||||
|
|
|
@ -110,6 +110,7 @@ type
|
|||
AsyncCommunityMemberActionTaskArg = ref object of QObjectTaskArg
|
||||
communityId: string
|
||||
pubKey: string
|
||||
deleteAllMessages: bool
|
||||
|
||||
const asyncRemoveUserFromCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncCommunityMemberActionTaskArg](argEncoded)
|
||||
|
@ -131,14 +132,15 @@ const asyncRemoveUserFromCommunityTask: Task = proc(argEncoded: string) {.gcsafe
|
|||
const asyncBanUserFromCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncCommunityMemberActionTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_go.banUserFromCommunity(arg.communityId, arg.pubKey)
|
||||
let response = status_go.banUserFromCommunity(arg.communityId, arg.pubKey, arg.deleteAllMessages)
|
||||
let tpl: tuple[communityId: string, pubKey: string, response: RpcResponse[JsonNode], error: string] = (arg.communityId, arg.pubKey, response, "")
|
||||
arg.finish(tpl)
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
"communityId": arg.communityId,
|
||||
"pubKey": arg.pubKey
|
||||
"pubKey": arg.pubKey,
|
||||
"deleteAllMessages": arg.deleteAllMessages
|
||||
})
|
||||
|
||||
const asyncUnbanUserFromCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
|
|
|
@ -2059,13 +2059,14 @@ QtObject:
|
|||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc asyncBanUserFromCommunity*(self: Service, communityId, pubKey: string) =
|
||||
proc asyncBanUserFromCommunity*(self: Service, communityId, pubKey: string, deleteAllMessages: bool) =
|
||||
let arg = AsyncCommunityMemberActionTaskArg(
|
||||
tptr: cast[ByteAddress](asyncBanUserFromCommunityTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncCommunityMemberActionCompleted",
|
||||
communityId: communityId,
|
||||
pubKey: pubKey,
|
||||
deleteAllMessages: deleteAllMessages
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ const SIGNAL_MESSAGES_MARKED_AS_READ* = "messagesMarkedAsRead"
|
|||
const SIGNAL_MESSAGE_REACTION_ADDED* = "messageReactionAdded"
|
||||
const SIGNAL_MESSAGE_REACTION_REMOVED* = "messageReactionRemoved"
|
||||
const SIGNAL_MESSAGE_REACTION_FROM_OTHERS* = "messageReactionFromOthers"
|
||||
const SIGNAL_MESSAGE_DELETION* = "messageDeleted"
|
||||
const SIGNAL_MESSAGE_REMOVED* = "messageRemoved"
|
||||
const SIGNAL_MESSAGES_DELETED* = "messagesDeleted"
|
||||
const SIGNAL_MESSAGE_DELIVERED* = "messageDelivered"
|
||||
const SIGNAL_MESSAGE_EDITED* = "messageEdited"
|
||||
const SIGNAL_ENVELOPE_SENT* = "envelopeSent"
|
||||
|
@ -111,11 +112,14 @@ type
|
|||
reactionId*: string
|
||||
reactionFrom*: string
|
||||
|
||||
MessageDeletedArgs* = ref object of Args
|
||||
MessageRemovedArgs* = ref object of Args
|
||||
chatId*: string
|
||||
messageId*: string
|
||||
deletedBy*: string
|
||||
|
||||
MessagesDeletedArgs* = ref object of Args
|
||||
deletedMessages*: Table[string, seq[string]]
|
||||
|
||||
MessageDeliveredArgs* = ref object of Args
|
||||
chatId*: string
|
||||
messageId*: string
|
||||
|
@ -348,10 +352,14 @@ QtObject:
|
|||
self.numOfPinnedMessagesPerChat[chatId] = self.getNumOfPinnedMessages(chatId) - 1
|
||||
self.events.emit(SIGNAL_MESSAGE_UNPINNED, data)
|
||||
|
||||
proc handleDeletedMessagesUpdate(self: Service, deletedMessages: seq[RemovedMessageDto]) =
|
||||
for dm in deletedMessages:
|
||||
let data = MessageDeletedArgs(chatId: dm.chatId, messageId: dm.messageId, deletedBy: dm.deletedBy)
|
||||
self.events.emit(SIGNAL_MESSAGE_DELETION, data)
|
||||
proc handleRemovedMessagesUpdate(self: Service, removedMessages: seq[RemovedMessageDto]) =
|
||||
for rm in removedMessages:
|
||||
let data = MessageRemovedArgs(chatId: rm.chatId, messageId: rm.messageId, deletedBy: rm.deletedBy)
|
||||
self.events.emit(SIGNAL_MESSAGE_REMOVED, data)
|
||||
|
||||
proc handleDeletedMessagesUpdate(self: Service, deletedMessages: Table[string, seq[string]]) =
|
||||
let data = MessagesDeletedArgs(deletedMessages: deletedMessages)
|
||||
self.events.emit(SIGNAL_MESSAGES_DELETED, data)
|
||||
|
||||
proc handleEmojiReactionsUpdate(self: Service, emojiReactions: seq[ReactionDto]) =
|
||||
for r in emojiReactions:
|
||||
|
@ -416,6 +424,9 @@ QtObject:
|
|||
# Handling pinned messages updates
|
||||
if (receivedData.pinnedMessages.len > 0):
|
||||
self.handlePinnedMessagesUpdate(receivedData.pinnedMessages)
|
||||
# Handling removed messages updates
|
||||
if (receivedData.removedMessages.len > 0):
|
||||
self.handleRemovedMessagesUpdate(receivedData.removedMessages)
|
||||
# Handling deleted messages updates
|
||||
if (receivedData.deletedMessages.len > 0):
|
||||
self.handleDeletedMessagesUpdate(receivedData.deletedMessages)
|
||||
|
@ -430,12 +441,12 @@ QtObject:
|
|||
self.events.on(SignalType.DiscordCommunityImportFinished.event) do(e: Args):
|
||||
var receivedData = DiscordCommunityImportFinishedSignal(e)
|
||||
self.handleMessagesReload(receivedData.communityId)
|
||||
|
||||
|
||||
self.events.on(SignalType.DiscordChannelImportFinished.event) do(e: Args):
|
||||
var receivedData = DiscordChannelImportFinishedSignal(e)
|
||||
self.resetMessageCursor(receivedData.channelId)
|
||||
self.asyncLoadMoreMessagesForChat(receivedData.channelId)
|
||||
|
||||
|
||||
self.events.on(SIGNAL_CHAT_LEFT) do(e: Args):
|
||||
var chatArg = ChatArgs(e)
|
||||
self.resetMessageCursor(chatArg.chatId)
|
||||
|
@ -637,7 +648,7 @@ QtObject:
|
|||
messageId: responseObj["messageId"].getStr,
|
||||
error: responseObj["error"].getStr,
|
||||
)
|
||||
|
||||
|
||||
if signalData.error == "":
|
||||
signalData.message = responseObj["message"].toMessageDto()
|
||||
|
||||
|
@ -942,7 +953,7 @@ QtObject:
|
|||
if responseObj.kind != JObject:
|
||||
warn "expected response is not a json object", methodName = "onAsyncUnfurlUrlsFinished"
|
||||
return
|
||||
|
||||
|
||||
let errMessage = responseObj["error"].getStr
|
||||
if errMessage != "":
|
||||
error "asyncUnfurlUrls failed", errMessage
|
||||
|
@ -1057,28 +1068,28 @@ proc deleteMessage*(self: Service, messageId: string) =
|
|||
try:
|
||||
let response = status_go.deleteMessageAndSend(messageId)
|
||||
|
||||
var deletesMessagesObj: JsonNode
|
||||
if(not response.result.getProp("removedMessages", deletesMessagesObj) or deletesMessagesObj.kind != JArray):
|
||||
error "error: ", procName="deleteMessage", errDesription = "no messages deleted or it's not an array"
|
||||
var removesMessagesObj: JsonNode
|
||||
if(not response.result.getProp("removedMessages", removesMessagesObj) or removesMessagesObj.kind != JArray):
|
||||
error "error: ", procName="removeMessage", errDesription = "no messages remove or it's not an array"
|
||||
return
|
||||
|
||||
let deletedMessagesArr = deletesMessagesObj.getElems()
|
||||
if(deletedMessagesArr.len == 0): # an array is returned
|
||||
error "error: ", procName="deleteMessage", errDesription = "array has no message to delete"
|
||||
let removedMessagesArr = removesMessagesObj.getElems()
|
||||
if(removedMessagesArr.len == 0): # an array is returned
|
||||
error "error: ", procName="removeMessage", errDesription = "array has no message to remove"
|
||||
return
|
||||
|
||||
let deletedMessageObj = deletedMessagesArr[0]
|
||||
let removedMessageObj = removedMessagesArr[0]
|
||||
var chat_Id, message_Id: string
|
||||
if not deletedMessageObj.getProp("chatId", chat_Id) or not deletedMessageObj.getProp("messageId", message_Id):
|
||||
error "error: ", procName="deleteMessage", errDesription = "there is no set chat id or message id in response"
|
||||
if not removedMessageObj.getProp("chatId", chat_Id) or not removedMessageObj.getProp("messageId", message_Id):
|
||||
error "error: ", procName="removeMessage", errDesription = "there is no set chat id or message id in response"
|
||||
return
|
||||
|
||||
let data = MessageDeletedArgs(
|
||||
let data = MessageRemovedArgs(
|
||||
chatId: chat_Id,
|
||||
messageId: message_Id,
|
||||
deletedBy: singletonInstance.userProfile.getPubKey(),
|
||||
)
|
||||
self.events.emit(SIGNAL_MESSAGE_DELETION, data)
|
||||
self.events.emit(SIGNAL_MESSAGE_REMOVED, data)
|
||||
|
||||
except Exception as e:
|
||||
error "error: ", procName="deleteMessage", errName = e.name, errDesription = e.msg
|
||||
|
|
|
@ -86,9 +86,9 @@ proc sendChatMessage*(
|
|||
}
|
||||
])
|
||||
|
||||
proc sendImages*(chatId: string,
|
||||
images: var seq[string],
|
||||
msg: string,
|
||||
proc sendImages*(chatId: string,
|
||||
images: var seq[string],
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string,
|
||||
linkPreviews: seq[LinkPreview],
|
||||
|
|
|
@ -460,10 +460,11 @@ proc declineRequestToJoinCommunity*(requestId: string): RpcResponse[JsonNode] {.
|
|||
"id": requestId
|
||||
}])
|
||||
|
||||
proc banUserFromCommunity*(communityId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
proc banUserFromCommunity*(communityId: string, pubKey: string, deleteAllMessages: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return callPrivateRPC("banUserFromCommunity".prefix, %*[{
|
||||
"communityId": communityId,
|
||||
"user": pubKey
|
||||
"user": pubKey,
|
||||
"deleteAllMessages": deleteAllMessages,
|
||||
}])
|
||||
|
||||
proc unbanUserFromCommunity*(communityId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
|
|
|
@ -327,8 +327,8 @@ QtObject {
|
|||
chatCommunitySectionModule.removeUserFromCommunity(pubKey);
|
||||
}
|
||||
|
||||
function banUserFromCommunity(pubKey) {
|
||||
chatCommunitySectionModule.banUserFromCommunity(pubKey);
|
||||
function banUserFromCommunity(pubKey, deleteAllMessages) {
|
||||
chatCommunitySectionModule.banUserFromCommunity(pubKey, deleteAllMessages);
|
||||
}
|
||||
|
||||
function unbanUserFromCommunity(pubKey) {
|
||||
|
|
|
@ -22,7 +22,7 @@ SettingsPage {
|
|||
|
||||
signal membershipRequestsClicked()
|
||||
signal kickUserClicked(string id)
|
||||
signal banUserClicked(string id)
|
||||
signal banUserClicked(string id, bool deleteAllMessages)
|
||||
signal unbanUserClicked(string id)
|
||||
signal acceptRequestToJoin(string id)
|
||||
signal declineRequestToJoin(string id)
|
||||
|
@ -193,11 +193,7 @@ SettingsPage {
|
|||
|
||||
communityName: root.communityName
|
||||
|
||||
onAccepted: {
|
||||
if (mode === KickBanPopup.Mode.Kick)
|
||||
root.kickUserClicked(userId)
|
||||
else
|
||||
root.banUserClicked(userId)
|
||||
}
|
||||
onBanUserClicked: root.banUserClicked(userId, deleteAllMessages)
|
||||
onKickUserClicked: root.kickUserClicked(userId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import QtQuick 2.15
|
||||
import QtQml.Models 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
|
@ -15,6 +17,9 @@ StatusDialog {
|
|||
property string communityName: ""
|
||||
property int mode: KickBanPopup.Mode.Kick
|
||||
|
||||
signal banUserClicked(bool deleteAllMessages)
|
||||
signal kickUserClicked()
|
||||
|
||||
enum Mode {
|
||||
Kick, Ban
|
||||
}
|
||||
|
@ -25,17 +30,40 @@ StatusDialog {
|
|||
? qsTr("Kick %1").arg(root.username)
|
||||
: qsTr("Ban %1").arg(root.username)
|
||||
|
||||
contentItem: StatusBaseText {
|
||||
contentItem: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
text: root.mode === KickBanPopup.Mode.Kick
|
||||
? qsTr("Are you sure you kick <b>%1</b> from %2?")
|
||||
.arg(root.username).arg(root.communityName)
|
||||
: qsTr("Are you sure you ban <b>%1</b> from %2?")
|
||||
.arg(root.username).arg(root.communityName)
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
text: root.mode === KickBanPopup.Mode.Kick
|
||||
? qsTr("Are you sure you want to kick <b>%1</b> from %2?")
|
||||
.arg(root.username).arg(root.communityName)
|
||||
: qsTr("Are you sure you want to ban <b>%1</b> from %2? This means that they will be kicked from this community and banned from re-joining.")
|
||||
.arg(root.username).arg(root.communityName)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: root.mode === KickBanPopup.Mode.Ban
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Delete all messages posted by the user")
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
}
|
||||
|
||||
StatusSwitch {
|
||||
id: deleteAllMessagesSwitch
|
||||
|
||||
checked: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
rightButtons: ObjectModel {
|
||||
|
@ -51,14 +79,17 @@ StatusDialog {
|
|||
? "CommunityMembers_KickModal_KickButton"
|
||||
: "CommunityMembers_BanModal_BanButton"
|
||||
|
||||
text: root.mode === KickBanPopup.Mode.Kick ? qsTr("Kick")
|
||||
: qsTr("Ban")
|
||||
text: root.mode === KickBanPopup.Mode.Kick ? qsTr("Kick %1").arg(root.username)
|
||||
: qsTr("Ban %1").arg(root.username)
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: {
|
||||
root.accept()
|
||||
root.mode === KickBanPopup.Mode.Kick ? root.kickUserClicked()
|
||||
: root.banUserClicked(deleteAllMessagesSwitch.checked)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: deleteAllMessagesSwitch.checked = false
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ Item {
|
|||
property bool invitationPending: root.store.isMyCommunityRequestPending(communityData.id)
|
||||
|
||||
property bool joiningCommunityInProgress: false
|
||||
|
||||
onShowJoinButtonChanged: invitationPending = root.store.isMyCommunityRequestPending(communityData.id)
|
||||
}
|
||||
|
||||
ColumnHeaderPanel {
|
||||
|
|
|
@ -273,7 +273,7 @@ StatusSectionLayout {
|
|||
communityName: root.community.name
|
||||
|
||||
onKickUserClicked: root.rootStore.removeUserFromCommunity(id)
|
||||
onBanUserClicked: root.rootStore.banUserFromCommunity(id)
|
||||
onBanUserClicked: root.rootStore.banUserFromCommunity(id, deleteAllMessages)
|
||||
onUnbanUserClicked: root.rootStore.unbanUserFromCommunity(id)
|
||||
onAcceptRequestToJoin: root.rootStore.acceptRequestToJoinCommunity(id, root.community.id)
|
||||
onDeclineRequestToJoin: root.rootStore.declineRequestToJoinCommunity(id, root.community.id)
|
||||
|
|
|
@ -140,6 +140,10 @@ Popup {
|
|||
return ownerTokenReceivedNotificationComponent
|
||||
case ActivityCenterStore.ActivityCenterNotificationType.ShareAccounts:
|
||||
return shareAccountsNotificationComponent
|
||||
case ActivityCenterStore.ActivityCenterNotificationType.CommunityBanned:
|
||||
return communityBannedNotificationComponent
|
||||
case ActivityCenterStore.ActivityCenterNotificationType.CommunityUnbanned:
|
||||
return communityUnbannedNotificationComponent
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
@ -236,6 +240,32 @@ Popup {
|
|||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: communityBannedNotificationComponent
|
||||
|
||||
ActivityNotificationCommunityBanUnban {
|
||||
banned: true
|
||||
filteredIndex: parent.filteredIndex
|
||||
notification: parent.notification
|
||||
store: root.store
|
||||
activityCenterStore: root.activityCenterStore
|
||||
onCloseActivityCenter: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: communityUnbannedNotificationComponent
|
||||
|
||||
ActivityNotificationCommunityBanUnban {
|
||||
banned: false
|
||||
filteredIndex: parent.filteredIndex
|
||||
notification: parent.notification
|
||||
store: root.store
|
||||
activityCenterStore: root.activityCenterStore
|
||||
onCloseActivityCenter: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: contactRemovedComponent
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ QtObject {
|
|||
OwnershipDeclined = 17,
|
||||
ShareAccounts = 18,
|
||||
CommunityTokenReceived = 19,
|
||||
FirstCommunityTokenReceived = 20
|
||||
FirstCommunityTokenReceived = 20,
|
||||
CommunityBanned = 21,
|
||||
CommunityUnbanned = 22
|
||||
}
|
||||
|
||||
enum ActivityCenterReadType {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.controls 1.0
|
||||
import utils 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
ActivityNotificationBase {
|
||||
id: root
|
||||
property bool banned: true
|
||||
|
||||
bodyComponent: RowLayout {
|
||||
width: parent.width
|
||||
height: 50
|
||||
readonly property var community: notification ?
|
||||
root.store.getCommunityDetailsAsJson(notification.communityId) :
|
||||
null
|
||||
|
||||
StatusSmartIdenticon {
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 40
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.topMargin: 2
|
||||
|
||||
asset {
|
||||
width: 24
|
||||
height: width
|
||||
name: "communities"
|
||||
color: root.banned ? "red" : "green"
|
||||
bgWidth: 40
|
||||
bgHeight: 40
|
||||
bgColor: Theme.palette.getColor(asset.color, 0.1)
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: root.banned ? qsTr("You were banned from") : qsTr("You've been unbanned from")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.italic: true
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
CommunityBadge {
|
||||
communityName: community ? community.name : ""
|
||||
communityImage: community ? community.image : ""
|
||||
communityColor: community ? community.color : "black"
|
||||
onCommunityNameClicked: root.store.setActiveCommunity(notification.communityId)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumWidth: 190
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
ctaComponent: root.banned ? undefined : visitCommunityCta
|
||||
|
||||
Component {
|
||||
id: visitCommunityCta
|
||||
StatusLinkText {
|
||||
text: qsTr("Visit Community")
|
||||
onClicked: {
|
||||
root.store.setActiveCommunity(notification.communityId)
|
||||
root.closeActivityCenter()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 9b17fd66734f810d465a1e463451260c0c0fd762
|
||||
Subproject commit 3959948c4c5ab560ae528c2d331241f2cc94fed1
|
Loading…
Reference in New Issue