diff --git a/ts/components/conversation/message/message-content/MessageQuote.tsx b/ts/components/conversation/message/message-content/MessageQuote.tsx index e6889fb2b..fc196f39e 100644 --- a/ts/components/conversation/message/message-content/MessageQuote.tsx +++ b/ts/components/conversation/message/message-content/MessageQuote.tsx @@ -64,8 +64,13 @@ export const MessageQuote = (props: Props) => { // If the quote is not found in memory, we try to find it in the DB if (quoteNotFound && quote.id && quote.author) { + // We always look for the quote by sentAt timestamp, for opengroups, closed groups and session chats + // this will return an array of sent messages by id that we have locally. const quotedMessagesCollection = await Data.getMessagesBySenderAndSentAt([ - { timestamp: toNumber(quote.id), source: quote.author }, + { + timestamp: toNumber(quote.id), + source: quote.author, + }, ]); if (quotedMessagesCollection?.length) { diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts index 4f7b16610..004f72327 100644 --- a/ts/receiver/queuedJob.ts +++ b/ts/receiver/queuedJob.ts @@ -16,6 +16,7 @@ import { getHideMessageRequestBannerOutsideRedux } from '../state/selectors/user import { GoogleChrome } from '../util'; import { LinkPreviews } from '../util/linkPreviews'; import { ReleasedFeatures } from '../util/releaseFeature'; +import { PropsForMessageWithoutConvoProps, lookupQuote } from '../state/ducks/conversations'; function contentTypeSupported(type: string): boolean { const Chrome = GoogleChrome; @@ -48,26 +49,48 @@ async function copyFromQuotedMessage( const id = _.toNumber(quoteId); - // We always look for the quote by sentAt timestamp, for opengroups, closed groups and session chats - // this will return an array of sent message by id we have locally. - - const collection = await Data.getMessagesBySentAt(id); - // we now must make sure this is the sender we expect - const found = collection.find(message => { - return Boolean(author === message.get('source')); - }); + // First we try to look for the quote in memory + const stateConversations = window.inboxStore?.getState().conversations; + const { messages, quotes } = stateConversations; + let quotedMessage: PropsForMessageWithoutConvoProps | MessageModel | undefined = lookupQuote( + quotes, + messages, + id, + quote.author + )?.propsForMessage; + + // If the quote is not found in memory, we try to find it in the DB + if (!quotedMessage) { + // We always look for the quote by sentAt timestamp, for opengroups, closed groups and session chats + // this will return an array of sent messages by id that we have locally. + const quotedMessagesCollection = await Data.getMessagesBySenderAndSentAt([ + { + timestamp: id, + source: quote.author, + }, + ]); + + if (quotedMessagesCollection?.length) { + quotedMessage = quotedMessagesCollection.at(0); + } + } - if (!found) { + if (!quotedMessage) { window?.log?.warn(`We did not found quoted message ${id} with author ${author}.`); quoteLocal.referencedMessageNotFound = true; msg.set({ quote: quoteLocal }); return; } + const isMessageModelType = Boolean((quotedMessage as MessageModel).get !== undefined); + window?.log?.info(`Found quoted message id: ${id}`); quoteLocal.referencedMessageNotFound = false; // NOTE we send the entire body to be consistent with the other platforms - quoteLocal.text = found.get('body') || ''; + quoteLocal.text = + (isMessageModelType + ? (quotedMessage as MessageModel).get('body') + : (quotedMessage as PropsForMessageWithoutConvoProps).text) || ''; // no attachments, just save the quote with the body if ( @@ -81,7 +104,10 @@ async function copyFromQuotedMessage( firstAttachment.thumbnail = null; - const queryAttachments = found.get('attachments') || []; + const queryAttachments = + (isMessageModelType + ? (quotedMessage as MessageModel).get('attachments') + : (quotedMessage as PropsForMessageWithoutConvoProps).attachments) || []; if (queryAttachments.length > 0) { const queryFirst = queryAttachments[0]; @@ -95,7 +121,10 @@ async function copyFromQuotedMessage( } } - const queryPreview = found.get('preview') || []; + const queryPreview = + (isMessageModelType + ? (quotedMessage as MessageModel).get('preview') + : (quotedMessage as PropsForMessageWithoutConvoProps).previews) || []; if (queryPreview.length > 0) { const queryFirst = queryPreview[0]; const { image } = queryFirst; diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index e480a448a..5108cdfd0 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -1161,6 +1161,7 @@ export async function openConversationToSpecificMessage(args: { /** * Look for quote matching the timestamp and author in the quote lookup map * @param quotes - the lookup map of the selected conversations quotes + * @param messages - the messages in memory for the selected conversation * @param author - the pubkey of the quoted author * @param timestamp - usually the id prop on the quote object of a message * @returns - the message model if found, undefined otherwise