fix(desktop/chat): Notifies when the user is mentioned in edited message

Introduce new signal in message service: SIGNAL_MENTIONED_IN_EDITED_MESSAGE.
Keeping mentioned users public keys in message item/model.
When message is edited, message module sends request to message service to
check if the current user is mentioned and emit SIGNAL_MENTIONED_IN_EDITED_MESSAGE.

Fixes #4475
This commit is contained in:
Michal Iskierko 2022-03-18 16:51:23 +01:00 committed by Michał Iskierko
parent 8e8e09308b
commit fd04833610
11 changed files with 78 additions and 13 deletions

View File

@ -107,6 +107,7 @@ method convertToItems*(
n.message.sticker.pack,
n.message.links,
newTransactionParametersItem("","","","","","",-1,""),
n.message.mentionedUsersPks
))
return notification_item.initItem(

View File

@ -261,3 +261,7 @@ proc joinGroupChat*(self: Controller) =
proc leaveChat*(self: Controller) =
self.chatService.leaveChat(self.chatId)
method checkEditedMessageForMentions*(self: Controller, chatId: string,
editedMessage: MessageDto, oldMentions: seq[string]) =
self.messageService.checkEditedMessageForMentions(chatId, editedMessage, oldMentions)

View File

@ -94,6 +94,7 @@ proc createFetchMoreMessagesItem(self: Module): Item =
stickerPack = -1,
@[],
newTransactionParametersItem("","","","","","",-1,""),
@[]
)
proc createChatIdentifierItem(self: Module): Item =
@ -131,6 +132,7 @@ proc createChatIdentifierItem(self: Module): Item =
stickerPack = -1,
@[],
newTransactionParametersItem("","","","","","",-1,""),
@[]
)
proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module): bool =
@ -202,7 +204,8 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
m.transactionParameters.transactionHash,
m.transactionParameters.commandState,
m.transactionParameters.signature),
)
m.mentionedUsersPks()
)
for r in reactions:
if(r.messageId == m.id):
@ -290,6 +293,7 @@ method messageAdded*(self: Module, message: MessageDto) =
message.transactionParameters.transactionHash,
message.transactionParameters.commandState,
message.transactionParameters.signature),
message.mentionedUsersPks
)
self.view.model().insertItemBasedOnTimestamp(item)
@ -413,14 +417,24 @@ method editMessage*(self: Module, messageId: string, updatedMsg: string) =
self.controller.editMessage(messageId, updatedMsg)
method onMessageEdited*(self: Module, message: MessageDto) =
let itemBeforeChange = self.view.model().getItemWithMessageId(message.id)
if(itemBeforeChange.isNil):
return
let mentionedUsersPks = itemBeforeChange.mentionedUsersPks
let renderedMessageText = self.controller.getRenderedText(message.parsedText)
self.view.model().updateEditedMsg(
message.id,
renderedMessageText,
message.containsContactMentions(),
message.links
message.links,
message.mentionedUsersPks
)
# ask service to send SIGNAL_MENTIONED_IN_EDITED_MESSAGE signal if there is a new user's mention
self.controller.checkEditedMessageForMentions(self.getChatId(), message, mentionedUsersPks)
let messagesIds = self.view.model().findIdsOfTheMessagesWhichRespondedToMessageWithId(message.id)
for msgId in messagesIds:
# refreshing an item calling `self.view.model().refreshItemWithId(msgId)` doesn't work from some very weird reason

View File

@ -185,7 +185,8 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy:
transactionValue,
m.transactionParameters.transactionHash,
m.transactionParameters.commandState,
m.transactionParameters.signature)
m.transactionParameters.signature),
m.mentionedUsersPks
)
item.pinned = true
item.pinnedBy = actionInitiatedBy

View File

@ -61,6 +61,10 @@ proc init*(self: Controller) =
self.delegate.onNewMessagesReceived(args.chatId, args.unviewedMessagesCount, args.unviewedMentionsCount,
args.messages)
self.events.on(message_service.SIGNAL_MENTIONED_IN_EDITED_MESSAGE) do(e: Args):
let args = MessageEditedArgs(e)
self.delegate.onMeMentionedInEditedMessage(args.chatId, args.message)
self.events.on(chat_service.SIGNAL_CHAT_MUTED) do(e:Args):
let args = chat_service.ChatArgs(e)
self.delegate.onChatMuted(args.chatId)

View File

@ -267,3 +267,6 @@ method reorderCommunityCategories*(self: AccessInterface, categoryId: string, po
method reorderCommunityChat*(self: AccessInterface, categoryId: string, chatId: string, position: int): string =
raise newException(ValueError, "No implementation available")
method onMeMentionedInEditedMessage*(self: AccessInterface, chatId: string, editedMessage : MessageDto) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -357,8 +357,7 @@ proc updateParentBadgeNotifications(self: Module) =
sectionHasUnreadMessages = sectionHasUnreadMessages or sectionNotificationCount > 0
self.delegate.onNotificationsUpdated(self.controller.getMySectionId(), sectionHasUnreadMessages, sectionNotificationCount)
proc updateBadgeNotifications(self: Module, chatId: string, unviewedMessagesCount: int, unviewedMentionsCount: int) =
let hasUnreadMessages = unviewedMessagesCount > 0
proc updateBadgeNotifications(self: Module, chatId: string, hasUnreadMessages: bool, unviewedMentionsCount: int) =
# update model of this module (appropriate chat from the chats list (chats model))
self.view.chatsModel().updateNotificationsForItemOrSubItemById(chatId, hasUnreadMessages, unviewedMentionsCount)
# update child module
@ -371,7 +370,7 @@ method onActiveSectionChange*(self: Module, sectionId: string) =
if(sectionId != self.controller.getMySectionId()):
return
self.updateBadgeNotifications(self.controller.getActiveChatId(), unviewedMessagesCount=0, unviewedMentionsCount=0)
self.updateBadgeNotifications(self.controller.getActiveChatId(), hasUnreadMessages=false, unviewedMentionsCount=0)
self.delegate.onActiveChatChange(self.controller.getMySectionId(), self.controller.getActiveChatId())
method chatsModel*(self: Module): chats_model.Model =
@ -583,7 +582,7 @@ method onChatUnmuted*(self: Module, chatId: string) =
self.view.chatsModel().muteUnmuteItemOrSubItemById(chatId, false)
method onMarkAllMessagesRead*(self: Module, chatId: string) =
self.updateBadgeNotifications(chatId, unviewedMessagesCount=0, unviewedMentionsCount=0)
self.updateBadgeNotifications(chatId, hasUnreadMessages=false, unviewedMentionsCount=0)
method markAllMessagesRead*(self: Module, chatId: string) =
self.controller.markAllMessagesRead(chatId)
@ -650,7 +649,8 @@ method onNewMessagesReceived*(self: Module, chatId: string, unviewedMessagesCoun
messages: seq[MessageDto]) =
if(self.controller.getMySectionId() != self.delegate.getActiveSectionId() or
self.controller.getActiveChatId() != chatId):
self.updateBadgeNotifications(chatId, unviewedMessagesCount, unviewedMentionsCount)
let hasUnreadMessages = unviewedMessagesCount > 0
self.updateBadgeNotifications(chatId, hasUnreadMessages, unviewedMentionsCount)
# Prepare bubble notification
let myPK = singletonInstance.userProfile.getPubKey()
@ -665,6 +665,13 @@ method onNewMessagesReceived*(self: Module, chatId: string, unviewedMessagesCoun
singletonInstance.globalEvents.showNormalMessageNotification(contactDetails.displayName, plainText,
self.controller.getMySectionId(), chatId, m.id)
method onMeMentionedInEditedMessage*(self: Module, chatId: string, editedMessage : MessageDto) =
if(editedMessage.communityId.len == 0 and self.controller.getMySectionId() != conf.CHAT_SECTION_ID or
editedMessage.communityId.len > 0 and self.controller.getMySectionId() != editedMessage.communityId):
return
var (sectionHasUnreadMessages, sectionNotificationCount) = self.view.chatsModel().getAllNotifications()
self.updateBadgeNotifications(chatId, sectionHasUnreadMessages, sectionNotificationCount + 1)
method addGroupMembers*(self: Module, communityID: string, chatId: string, pubKeys: string) =
self.controller.addGroupMembers(communityID, chatId, self.convertPubKeysToJson(pubKeys))

View File

@ -36,6 +36,7 @@ type
isEdited: bool
links: seq[string]
transactionParameters: TransactionParametersItem
mentionedUsersPks: seq[string]
proc initItem*(
id,
@ -61,6 +62,7 @@ proc initItem*(
stickerPack: int,
links: seq[string],
transactionParameters: TransactionParametersItem,
mentionedUsersPks: seq[string],
): Item =
result = Item()
result.id = id
@ -90,6 +92,7 @@ proc initItem*(
result.isEdited = false
result.links = links
result.transactionParameters = transactionParameters
result.mentionedUsersPks = mentionedUsersPks
result.gapFrom = 0
result.gapTo = 0
@ -118,6 +121,7 @@ proc `$`*(self: Item): string =
isEdited:{$self.isEdited},
links:{$self.links},
transactionParameters:{$self.transactionParameters},
mentionedUsersPks:{$self.mentionedUsersPks},
)"""
proc id*(self: Item): string {.inline.} =
@ -238,6 +242,12 @@ proc links*(self: Item): seq[string] {.inline.} =
proc `links=`*(self: Item, links: seq[string]) {.inline.} =
self.links = links
proc mentionedUsersPks*(self: Item): seq[string] {.inline.} =
self.mentionedUsersPks
proc `mentionedUsersPks=`*(self: Item, mentionedUsersPks: seq[string]) {.inline.} =
self.mentionedUsersPks = mentionedUsersPks
proc transactionParameters*(self: Item): TransactionParametersItem {.inline.} =
self.transactionParameters
@ -270,7 +280,8 @@ proc toJsonNode*(self: Item): JsonNode =
"pinnedBy": self.pinnedBy,
"editMode": self.editMode,
"isEdited": self.isEdited,
"links": self.links
"links": self.links,
"mentionedUsersPks": self.mentionedUsersPks
}
proc editMode*(self: Item): bool {.inline.} =

View File

@ -35,6 +35,7 @@ type
IsEdited
Links
TransactionParameters
MentionedUsersPks
QtObject:
type
@ -107,6 +108,7 @@ QtObject:
ModelRole.IsEdited.int: "isEdited",
ModelRole.Links.int: "links",
ModelRole.TransactionParameters.int: "transactionParameters",
ModelRole.MentionedUsersPks.int: "mentionedUsersPks"
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -189,6 +191,8 @@ QtObject:
"commandState": item.transactionParameters.commandState,
"signature": item.transactionParameters.signature
}))
of ModelRole.MentionedUsersPks:
result = newQVariant(item.mentionedUsersPks.join(" "))
proc findIndexForMessageId*(self: Model, messageId: string): int =
for i in 0 ..< self.items.len:
@ -384,7 +388,8 @@ QtObject:
messageId: string,
updatedMsg: string,
messageContainsMentions: bool,
links: seq[string]
links: seq[string],
mentionedUsersPks: seq[string]
) =
let ind = self.findIndexForMessageId(messageId)
if(ind == -1):
@ -394,13 +399,15 @@ QtObject:
self.items[ind].messageContainsMentions = messageContainsMentions
self.items[ind].isEdited = true
self.items[ind].links = links
self.items[ind].mentionedUsersPks = mentionedUsersPks
let index = self.createIndex(ind, 0, nil)
self.dataChanged(index, index, @[
ModelRole.MessageText.int,
ModelRole.MessageContainsMentions.int,
ModelRole.IsEdited.int,
ModelRole.Links.int
ModelRole.Links.int,
ModelRole.MentionedUsersPks.int
])
proc clear*(self: Model) =

View File

@ -181,4 +181,10 @@ proc isUserWithPkMentioned*(self: MessageDto, publicKey: string): bool =
for child in pText.children:
if (child.type == PARSED_TEXT_CHILD_TYPE_MENTION and child.literal.contains(publicKey)):
return true
return false
return false
proc mentionedUsersPks*(self: MessageDto): seq[string] =
for pText in self.parsedText:
for child in pText.children:
if (child.type == PARSED_TEXT_CHILD_TYPE_MENTION):
result.add(child.literal)

View File

@ -48,6 +48,7 @@ const SIGNAL_MESSAGE_REACTION_FROM_OTHERS* = "messageReactionFromOthers"
const SIGNAL_MESSAGE_DELETION* = "messageDeleted"
const SIGNAL_MESSAGE_EDITED* = "messageEdited"
const SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED* = "messageLinkPreviewDataLoaded"
const SIGNAL_MENTIONED_IN_EDITED_MESSAGE* = "mentionedInEditedMessage"
include async_tasks
@ -707,4 +708,10 @@ proc editMessage*(self: Service, messageId: string, msg: string) =
error "error: ", procName="editMessage", errName = e.name, errDesription = e.msg
proc getWalletAccounts*(self: Service): seq[wallet_account_service.WalletAccountDto] =
return self.walletAccountService.getWalletAccounts()
return self.walletAccountService.getWalletAccounts()
proc checkEditedMessageForMentions*(self: Service, chatId: string, editedMessage: MessageDto, oldMentions: seq[string]) =
let myPubKey = singletonInstance.userProfile.getPubKey()
if not oldMentions.contains(myPubKey) and editedMessage.mentionedUsersPks().contains(myPubKey):
let data = MessageEditedArgs(chatId: chatId, message: editedMessage)
self.events.emit(SIGNAL_MENTIONED_IN_EDITED_MESSAGE, data)