refactor: reduce calls to getMessageById and remove calls for reactions

Fixes #9859

getMessageById was called way too often, because each time a contact was updated, we called it on every message that contained a mention. Now we only call it on messages that contain a mention from that specific user.

Also, we called emojiReactionsByChatIDMessageID as part of that service call, but only the pinned message used it, so I removed it from the service function. This means that the pinned messages will no longer have the emoji reactions. I could add them back if we really want, but IMO, it's not really necessary. You can just click on the message and see it in the chat instead.

I removed the call to `getMessageById` in the activity center as well, since we can get the replied message info from the MessageDto directly now.

I also removed some dead code in the messages module.
This commit is contained in:
Jonathan Rainville 2023-03-13 14:52:25 -04:00
parent cc1a89efef
commit 0ebc81594a
7 changed files with 53 additions and 134 deletions

View File

@ -146,7 +146,7 @@ proc getOneToOneChatNameAndImage*(self: Controller, chatId: string):
return self.chatService.getOneToOneChatNameAndImage(chatId) return self.chatService.getOneToOneChatNameAndImage(chatId)
proc getMessageById*(self: Controller, chatId, messageId: string): MessageDto = proc getMessageById*(self: Controller, chatId, messageId: string): MessageDto =
let (message, _, err) = self.messageService.getDetailsForMessage(chatId, messageId) let (message, err) = self.messageService.fetchMessageByMessageId(chatId, messageId)
if(err.len > 0): if(err.len > 0):
return MessageDto() return MessageDto()
return message return message

View File

@ -133,46 +133,45 @@ proc createMessageItemFromDto(self: Module, message: MessageDto, chatDetails: Ch
)) ))
method convertToItems*( method convertToItems*(
self: Module, self: Module,
activityCenterNotifications: seq[ActivityCenterNotificationDto] activityCenterNotifications: seq[ActivityCenterNotificationDto]
): seq[notification_item.Item] = ): seq[notification_item.Item] =
result = activityCenterNotifications.map( result = activityCenterNotifications.map(
proc(n: ActivityCenterNotificationDto): notification_item.Item = proc(notification: ActivityCenterNotificationDto): notification_item.Item =
var messageItem = msg_item_qobj.newMessageItem(nil) var messageItem = msg_item_qobj.newMessageItem(nil)
var repliedMessageItem = msg_item_qobj.newMessageItem(nil) var repliedMessageItem = msg_item_qobj.newMessageItem(nil)
let chatDetails = self.controller.getChatDetails(n.chatId) let chatDetails = self.controller.getChatDetails(notification.chatId)
# default section id is `Chat` section # default section id is `Chat` section
let sectionId = if(chatDetails.communityId.len > 0): let sectionId = if(chatDetails.communityId.len > 0):
chatDetails.communityId chatDetails.communityId
else: else:
singletonInstance.userProfile.getPubKey() singletonInstance.userProfile.getPubKey()
if (n.message.id != ""): if (notification.message.id != ""):
# If there is a message in the Notification, transfer it to a MessageItem (QObject) # If there is a message in the Notification, transfer it to a MessageItem (QObject)
messageItem = self.createMessageItemFromDto(n.message, chatDetails) messageItem = self.createMessageItemFromDto(notification.message, chatDetails)
if (n.notificationType == ActivityCenterNotificationType.Reply and n.message.responseTo != ""): if (notification.notificationType == ActivityCenterNotificationType.Reply and notification.message.responseTo != ""):
let repliedMessage = self.controller.getMessageById(n.chatId, n.message.responseTo) repliedMessageItem = self.createMessageItemFromDto(notification.replyMessage, chatDetails)
repliedMessageItem = self.createMessageItemFromDto(repliedMessage, chatDetails)
if (n.notificationType == ActivityCenterNotificationType.ContactVerification): if (notification.notificationType == ActivityCenterNotificationType.ContactVerification):
repliedMessageItem = self.createMessageItemFromDto(n.replyMessage, chatDetails) repliedMessageItem = self.createMessageItemFromDto(notification.replyMessage, chatDetails)
return notification_item.initItem( return notification_item.initItem(
n.id, notification.id,
n.chatId, notification.chatId,
n.communityId, notification.communityId,
n.membershipStatus, notification.membershipStatus,
n.verificationStatus, notification.verificationStatus,
sectionId, sectionId,
n.name, notification.name,
n.author, notification.author,
n.notificationType, notification.notificationType,
n.timestamp, notification.timestamp,
n.read, notification.read,
n.dismissed, notification.dismissed,
n.accepted, notification.accepted,
messageItem, messageItem,
repliedMessageItem, repliedMessageItem,
chatDetails.chatType chatDetails.chatType

View File

@ -201,9 +201,9 @@ proc belongsToCommunity*(self: Controller): bool =
proc unpinMessage*(self: Controller, messageId: string) = proc unpinMessage*(self: Controller, messageId: string) =
self.messageService.pinUnpinMessage(self.chatId, messageId, false) self.messageService.pinUnpinMessage(self.chatId, messageId, false)
proc getMessageDetails*(self: Controller, messageId: string): proc getMessageById*(self: Controller, messageId: string):
tuple[message: MessageDto, reactions: seq[ReactionDto], error: string] = tuple[message: MessageDto, error: string] =
return self.messageService.getDetailsForMessage(self.chatId, messageId) return self.messageService.fetchMessageByMessageId(self.chatId, messageId)
proc isUsersListAvailable*(self: Controller): bool = proc isUsersListAvailable*(self: Controller): bool =
return self.isUsersListAvailable return self.isUsersListAvailable

View File

@ -261,9 +261,9 @@ proc getRenderedText*(self: Controller, parsedTextArray: seq[ParsedText], commun
proc replacePubKeysWithDisplayNames*(self: Controller, message: string): string = proc replacePubKeysWithDisplayNames*(self: Controller, message: string): string =
return self.messageService.replacePubKeysWithDisplayNames(message) return self.messageService.replacePubKeysWithDisplayNames(message)
proc getMessageDetails*(self: Controller, messageId: string): proc getMessageById*(self: Controller, messageId: string):
tuple[message: MessageDto, reactions: seq[ReactionDto], error: string] = tuple[message: MessageDto, error: string] =
return self.messageService.getDetailsForMessage(self.chatId, messageId) return self.messageService.fetchMessageByMessageId(self.chatId, messageId)
proc deleteMessage*(self: Controller, messageId: string) = proc deleteMessage*(self: Controller, messageId: string) =
self.messageService.deleteMessage(messageId) self.messageService.deleteMessage(messageId)

View File

@ -1,4 +1,4 @@
import NimQml, chronicles import NimQml, chronicles, sequtils
import io_interface import io_interface
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
import view, controller import view, controller
@ -529,7 +529,7 @@ method getNumberOfPinnedMessages*(self: Module): int =
method updateContactDetails*(self: Module, contactId: string) = method updateContactDetails*(self: Module, contactId: string) =
let updatedContact = self.controller.getContactDetails(contactId) let updatedContact = self.controller.getContactDetails(contactId)
for item in self.view.model().modelContactUpdateIterator(contactId): for item in self.view.model().modelContactUpdateIterator(contactId):
if(item.senderId == contactId): if item.senderId == contactId:
item.senderDisplayName = updatedContact.defaultDisplayName item.senderDisplayName = updatedContact.defaultDisplayName
item.senderOptionalName = updatedContact.optionalName item.senderOptionalName = updatedContact.optionalName
item.senderIcon = updatedContact.icon item.senderIcon = updatedContact.icon
@ -537,13 +537,15 @@ method updateContactDetails*(self: Module, contactId: string) =
item.senderIsAdded = updatedContact.details.added item.senderIsAdded = updatedContact.details.added
item.senderTrustStatus = updatedContact.details.trustStatus item.senderTrustStatus = updatedContact.details.trustStatus
item.senderEnsVerified = updatedContact.details.ensVerified item.senderEnsVerified = updatedContact.details.ensVerified
if(item.quotedMessageAuthorDetails.details.id == contactId):
if item.quotedMessageAuthorDetails.details.id == contactId:
item.quotedMessageAuthorDetails = updatedContact item.quotedMessageAuthorDetails = updatedContact
item.quotedMessageAuthorDisplayName = updatedContact.defaultDisplayName item.quotedMessageAuthorDisplayName = updatedContact.defaultDisplayName
item.quotedMessageAuthorAvatar = updatedContact.icon item.quotedMessageAuthorAvatar = updatedContact.icon
if(item.messageContainsMentions):
let (message, _, err) = self.controller.getMessageDetails(item.id) if item.messageContainsMentions and item.mentionedUsersPks.anyIt(it == contactId):
if(err.len == 0): let (message, err) = self.controller.getMessageById(item.id)
if err == "":
let chatDetails = self.controller.getChatDetails() let chatDetails = self.controller.getChatDetails()
let communityChats = self.controller.getCommunityById(chatDetails.communityId).chats let communityChats = self.controller.getCommunityById(chatDetails.communityId).chats
item.messageText = self.controller.getRenderedText(message.parsedText, communityChats) item.messageText = self.controller.getRenderedText(message.parsedText, communityChats)
@ -646,78 +648,6 @@ method onChatMemberUpdated*(self: Module, publicKey: string, admin: bool, joined
method getMessages*(self: Module): seq[message_item.Item] = method getMessages*(self: Module): seq[message_item.Item] =
return self.view.model().items return self.view.model().items
method getMessageById*(self: Module, messageId: string): message_item.Item =
let (message, _, err) = self.controller.getMessageDetails(messageId)
if(err.len == 0):
let sender = self.controller.getContactDetails(message.`from`)
let chatDetails = self.controller.getChatDetails()
let communityChats = self.controller.getCommunityById(chatDetails.communityId).chats
let renderedMessageText = self.controller.getRenderedText(message.parsedText, communityChats)
var quotedMessageAuthorDetails = ContactDetails()
if message.quotedMessage.`from` != "":
if(message.`from` == message.quotedMessage.`from`):
quotedMessageAuthorDetails = sender
else:
quotedMessageAuthorDetails = self.controller.getContactDetails(message.quotedMessage.`from`)
var transactionContract = message.transactionParameters.contract
var transactionValue = message.transactionParameters.value
var isCurrentUser = sender.isCurrentUser
if(message.contentType.ContentType == ContentType.Transaction):
(transactionContract, transactionValue) = self.controller.getTransactionDetails(message)
if message.transactionParameters.fromAddress != "":
isCurrentUser = self.currentUserWalletContainsAddress(message.transactionParameters.fromAddress)
var item = initItem(
message.id,
message.communityId,
message.responseTo,
message.`from`,
sender.defaultDisplayName,
sender.optionalName,
sender.icon,
sender.colorHash,
(isCurrentUser and message.contentType.ContentType != ContentType.DiscordMessage),
sender.details.added,
message.outgoingStatus,
renderedMessageText,
message.text,
message.image,
message.containsContactMentions(),
message.seen,
timestamp = message.timestamp,
clock = message.clock,
message.contentType.ContentType,
message.messageType,
message.contactRequestState,
sticker = message.sticker.url,
message.sticker.pack,
message.links,
newTransactionParametersItem(message.transactionParameters.id,
message.transactionParameters.fromAddress,
message.transactionParameters.address,
transactionContract,
transactionValue,
message.transactionParameters.transactionHash,
message.transactionParameters.commandState,
message.transactionParameters.signature),
message.mentionedUsersPks(),
sender.details.trustStatus,
sender.details.ensVerified,
message.discordMessage,
resendError = "",
message.mentioned,
message.quotedMessage.`from`,
message.quotedMessage.text,
self.controller.getRenderedText(message.quotedMessage.parsedText, communityChats),
message.quotedMessage.contentType,
message.quotedMessage.deleted,
message.quotedMessage.discordMessage,
quotedMessageAuthorDetails,
)
return item
return nil
method onMailserverSynced*(self: Module, syncedFrom: int64) = method onMailserverSynced*(self: Module, syncedFrom: int64) =
let chatDto = self.controller.getChatDetails() let chatDto = self.controller.getChatDetails()
if (not chatDto.hasMoreMessagesToRequest(syncedFrom)): if (not chatDto.hasMoreMessagesToRequest(syncedFrom)):

View File

@ -151,8 +151,8 @@ method currentUserWalletContainsAddress(self: Module, address: string): bool =
return false return false
proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: string, item: var pinned_msg_item.Item): proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy: string, item: var pinned_msg_item.Item):
bool = bool =
let (message, reactions, err) = self.controller.getMessageDetails(messageId) let (message, err) = self.controller.getMessageById(messageId)
if(err.len > 0): if(err.len > 0):
return false return false
@ -223,17 +223,6 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy:
item.pinned = true item.pinned = true
item.pinnedBy = actionInitiatedBy item.pinnedBy = actionInitiatedBy
for r in reactions:
if(r.messageId == message.id):
var emojiIdAsEnum: pinned_msg_reaction_item.EmojiId
if(pinned_msg_reaction_item.toEmojiIdAsEnum(r.emojiId, emojiIdAsEnum)):
let userWhoAddedThisReaction = self.controller.getContactById(r.`from`)
let didIReactWithThisEmoji = userWhoAddedThisReaction.id == singletonInstance.userProfile.getPubKey()
item.addReaction(emojiIdAsEnum, didIReactWithThisEmoji, userWhoAddedThisReaction.id,
userWhoAddedThisReaction.userDefaultDisplayName(), r.id)
else:
error "wrong emoji id found when loading messages", methodName="buildPinnedMessageItem"
return true return true
method newPinnedMessagesLoaded*(self: Module, pinnedMessages: seq[PinnedMessageDto]) = method newPinnedMessagesLoaded*(self: Module, pinnedMessages: seq[PinnedMessageDto]) =
@ -343,15 +332,21 @@ method amIChatAdmin*(self: Module): bool =
method onContactDetailsUpdated*(self: Module, contactId: string) = method onContactDetailsUpdated*(self: Module, contactId: string) =
let updatedContact = self.controller.getContactDetails(contactId) let updatedContact = self.controller.getContactDetails(contactId)
for item in self.view.pinnedModel().modelContactUpdateIterator(contactId): for item in self.view.pinnedModel().modelContactUpdateIterator(contactId):
if(item.senderId == contactId): if item.senderId == contactId:
item.senderDisplayName = updatedContact.defaultDisplayName item.senderDisplayName = updatedContact.defaultDisplayName
item.senderOptionalName = updatedContact.optionalName item.senderOptionalName = updatedContact.optionalName
item.senderEnsVerified = updatedContact.details.ensVerified item.senderEnsVerified = updatedContact.details.ensVerified
item.senderIcon = updatedContact.icon item.senderIcon = updatedContact.icon
item.senderTrustStatus = updatedContact.details.trustStatus item.senderTrustStatus = updatedContact.details.trustStatus
if(item.messageContainsMentions):
let (message, _, err) = self.controller.getMessageDetails(item.id) if item.quotedMessageAuthorDetails.details.id == contactId:
if(err.len == 0): item.quotedMessageAuthorDetails = updatedContact
item.quotedMessageAuthorDisplayName = updatedContact.defaultDisplayName
item.quotedMessageAuthorAvatar = updatedContact.icon
if item.messageContainsMentions and item.mentionedUsersPks.anyIt(it == contactId):
let (message, err) = self.controller.getMessageById(item.id)
if err == "":
let chatDetails = self.controller.getChatDetails() let chatDetails = self.controller.getChatDetails()
let communityChats = self.controller.getCommunityById(chatDetails.communityId).chats let communityChats = self.controller.getCommunityById(chatDetails.communityId).chats
item.messageText = self.controller.getRenderedText(message.parsedText, communityChats) item.messageText = self.controller.getRenderedText(message.parsedText, communityChats)

View File

@ -499,8 +499,8 @@ QtObject:
except Exception as e: except Exception as e:
error "error: ", procName="pinUnpinMessage", errName = e.name, errDesription = e.msg error "error: ", procName="pinUnpinMessage", errName = e.name, errDesription = e.msg
proc getDetailsForMessage*(self: Service, chatId: string, messageId: string): proc fetchMessageByMessageId*(self: Service, chatId: string, messageId: string):
tuple[message: MessageDto, reactions: seq[ReactionDto], error: string] = tuple[message: MessageDto, error: string] =
try: try:
let msgResponse = status_go.fetchMessageByMessageId(messageId) let msgResponse = status_go.fetchMessageByMessageId(messageId)
if(msgResponse.error.isNil): if(msgResponse.error.isNil):
@ -509,14 +509,9 @@ QtObject:
if(result.message.id.len == 0): if(result.message.id.len == 0):
result.error = "message with id: " & messageId & " doesn't exist" result.error = "message with id: " & messageId & " doesn't exist"
return return
let reactionsResponse = status_go.fetchReactionsForMessageWithId(chatId, messageId)
if(reactionsResponse.error.isNil):
result.reactions = map(reactionsResponse.result.getElems(), proc(x: JsonNode): ReactionDto = x.toReactionDto())
except Exception as e: except Exception as e:
result.error = e.msg result.error = e.msg
error "error: ", procName="getDetailsForMessage", errName = e.name, errDesription = e.msg error "error: ", procName="fetchMessageByMessageId", errName = e.name, errDesription = e.msg
proc finishAsyncSearchMessagesWithError*(self: Service, chatId, errorMessage: string) = proc finishAsyncSearchMessagesWithError*(self: Service, chatId, errorMessage: string) =
error "error: ", procName="onAsyncSearchMessages", errDescription = errorMessage error "error: ", procName="onAsyncSearchMessages", errDescription = errorMessage