fix: SES-585 when the app is not focused message quotes now load correectly

we now look up the existing messages in memory if not found in the quote lookup map, we also allow jumping to messages quoted but not yet stored in memory
pull/2757/head
William Grant 2 years ago
parent 16b394dbee
commit b91388a672

@ -10,6 +10,7 @@ import {
} from '../../../../state/selectors/conversations'; } from '../../../../state/selectors/conversations';
import { Quote } from './quote/Quote'; import { Quote } from './quote/Quote';
import { ToastUtils } from '../../../../session/utils'; import { ToastUtils } from '../../../../session/utils';
import { Data } from '../../../../data/data';
// tslint:disable: use-simple-attributes // tslint:disable: use-simple-attributes
@ -41,8 +42,6 @@ export const MessageQuote = (props: Props) => {
quote.referencedMessageNotFound || !quote?.author || !quote.id || !quote.convoId quote.referencedMessageNotFound || !quote?.author || !quote.id || !quote.convoId
); );
const quoteText = quote?.text || null;
const onQuoteClick = useCallback( const onQuoteClick = useCallback(
async (event: React.MouseEvent<HTMLDivElement>) => { async (event: React.MouseEvent<HTMLDivElement>) => {
event.preventDefault(); event.preventDefault();
@ -59,16 +58,38 @@ export const MessageQuote = (props: Props) => {
return; return;
} }
let conversationKey = String(quote.convoId);
let messageIdToNavigateTo = String(quote.id);
let quoteNotFoundInDB = false;
// If the quote is not found in memory, we try to find it in the DB
if (quoteNotFound && quote.id && quote.author) {
const quotedMessagesCollection = await Data.getMessagesBySenderAndSentAt([
{ timestamp: Number(quote.id), source: quote.author },
]);
if (quotedMessagesCollection?.length) {
const quotedMessage = quotedMessagesCollection.at(0);
// If found, we navigate to the quoted message which also refreshes the message quote component
if (quotedMessage) {
conversationKey = String(quotedMessage.get('conversationId'));
messageIdToNavigateTo = String(quotedMessage.id);
} else {
quoteNotFoundInDB = true;
}
}
}
// For simplicity's sake, we show the 'not found' toast no matter what if we were // For simplicity's sake, we show the 'not found' toast no matter what if we were
// not able to find the referenced message when the quote was received or if the conversation no longer exists. // not able to find the referenced message when the quote was received or if the conversation no longer exists.
if (quoteNotFound) { if (quoteNotFoundInDB) {
ToastUtils.pushOriginalNotFound(); ToastUtils.pushOriginalNotFound();
return; return;
} }
void openConversationToSpecificMessage({ void openConversationToSpecificMessage({
conversationKey: String(quote.convoId), conversationKey,
messageIdToNavigateTo: String(quote.id), messageIdToNavigateTo,
shouldHighlightMessage: true, shouldHighlightMessage: true,
}); });
}, },
@ -78,7 +99,7 @@ export const MessageQuote = (props: Props) => {
return ( return (
<Quote <Quote
onClick={onQuoteClick} onClick={onQuoteClick}
text={quoteText} text={quote?.text}
attachment={quote?.attachment} attachment={quote?.attachment}
isIncoming={direction === 'incoming'} isIncoming={direction === 'incoming'}
author={quote.author} author={quote.author}

@ -44,12 +44,12 @@ const StyledQuoteTextContent = styled.div`
`; `;
export type QuoteProps = { export type QuoteProps = {
attachment?: QuotedAttachmentType;
author: string; author: string;
isFromMe: boolean; isFromMe: boolean;
isIncoming: boolean; isIncoming: boolean;
referencedMessageNotFound: boolean; referencedMessageNotFound: boolean;
text: string | null; text?: string;
attachment?: QuotedAttachmentType;
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void; onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
}; };

@ -569,11 +569,18 @@ function handleMessageExpiredOrDeleted(
const messageInStoreIndex = state?.messages.findIndex(m => m.propsForMessage.id === messageId); const messageInStoreIndex = state?.messages.findIndex(m => m.propsForMessage.id === messageId);
const editedQuotes = { ...state.quotes }; const editedQuotes = { ...state.quotes };
if (messageInStoreIndex >= 0) { if (messageInStoreIndex >= 0) {
// we cannot edit the array directly, so slice the first part, and slice the second part,
// keeping the index removed out
const editedMessages = [
...state.messages.slice(0, messageInStoreIndex),
...state.messages.slice(messageInStoreIndex + 1),
];
// Check if the message is quoted somewhere, and if so, remove it from the quotes // Check if the message is quoted somewhere, and if so, remove it from the quotes
const msgProps = state.messages[messageInStoreIndex].propsForMessage; const msgProps = state.messages[messageInStoreIndex].propsForMessage;
const { timestamp, sender } = msgProps; const { timestamp, sender } = msgProps;
if (timestamp && sender) { if (timestamp && sender) {
const message2Delete = lookupQuote(editedQuotes, timestamp, sender); const message2Delete = lookupQuote(editedQuotes, editedMessages, timestamp, sender);
window.log.debug( window.log.debug(
`Deleting quote {${timestamp}-${sender}} ${JSON.stringify(message2Delete)}` `Deleting quote {${timestamp}-${sender}} ${JSON.stringify(message2Delete)}`
); );
@ -582,13 +589,6 @@ function handleMessageExpiredOrDeleted(
delete editedQuotes[`${timestamp}-${sender}`]; delete editedQuotes[`${timestamp}-${sender}`];
} }
// we cannot edit the array directly, so slice the first part, and slice the second part,
// keeping the index removed out
const editedMessages = [
...state.messages.slice(0, messageInStoreIndex),
...state.messages.slice(messageInStoreIndex + 1),
];
// FIXME two other thing we have to do: // FIXME two other thing we have to do:
// * update the last message text if the message deleted was the last one // * update the last message text if the message deleted was the last one
// * update the unread count of the convo if the message was the one counted as an unread // * update the unread count of the convo if the message was the one counted as an unread
@ -1166,8 +1166,27 @@ export async function openConversationToSpecificMessage(args: {
*/ */
export function lookupQuote( export function lookupQuote(
quotes: QuoteLookupType, quotes: QuoteLookupType,
messages: Array<MessageModelPropsWithoutConvoProps>,
timestamp: number, timestamp: number,
author: string author: string
): MessageModelPropsWithoutConvoProps | undefined { ): MessageModelPropsWithoutConvoProps | undefined {
return quotes[`${timestamp}-${author}`]; let sourceMessage = quotes[`${timestamp}-${author}`];
// NOTE If a quote is processed but we haven't triggered a render, the quote might not be in the lookup map yet so we check the messages in memory.
if (!sourceMessage) {
const quotedMessages = messages.filter(message => {
const msgProps = message.propsForMessage;
return msgProps.timestamp === timestamp && msgProps.sender === author;
});
if (quotedMessages?.length) {
for (const quotedMessage of quotedMessages) {
if (quotedMessage) {
sourceMessage = quotedMessage;
}
}
}
}
return sourceMessage;
} }

@ -983,10 +983,12 @@ export const getMessageLinkPreviewProps = createSelector(getMessagePropsByMessag
// tslint:disable: cyclomatic-complexity // tslint:disable: cyclomatic-complexity
export const getMessageQuoteProps = createSelector( export const getMessageQuoteProps = createSelector(
getConversationLookup, getConversationLookup,
getMessagesOfSelectedConversation,
getConversationQuotes, getConversationQuotes,
getMessagePropsByMessageId, getMessagePropsByMessageId,
( (
conversationLookup, conversationLookup,
messagesProps,
quotesProps, quotesProps,
msgModel msgModel
): { direction: MessageModelType; quote: PropsForQuote } | undefined => { ): { direction: MessageModelType; quote: PropsForQuote } | undefined => {
@ -1001,7 +1003,9 @@ export const getMessageQuoteProps = createSelector(
return undefined; return undefined;
} }
let { id, author } = msgProps.quote; const id = msgProps.quote.id;
let author = msgProps.quote.author;
if (!id || !author) { if (!id || !author) {
return undefined; return undefined;
} }
@ -1017,6 +1021,7 @@ export const getMessageQuoteProps = createSelector(
const quoteNotFound = { const quoteNotFound = {
direction, direction,
quote: { quote: {
id,
author, author,
isFromMe, isFromMe,
referencedMessageNotFound: true, referencedMessageNotFound: true,
@ -1027,7 +1032,7 @@ export const getMessageQuoteProps = createSelector(
return quoteNotFound; return quoteNotFound;
} }
const sourceMessage = lookupQuote(quotesProps, Number(id), author); const sourceMessage = lookupQuote(quotesProps, messagesProps, Number(id), author);
if (!sourceMessage) { if (!sourceMessage) {
return quoteNotFound; return quoteNotFound;
} }

Loading…
Cancel
Save