You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			112 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
| import { isEmpty, toNumber } from 'lodash';
 | |
| import React from 'react';
 | |
| import { useSelector } from 'react-redux';
 | |
| import { Data } from '../../../../data/data';
 | |
| import { MessageRenderingProps } from '../../../../models/messageType';
 | |
| import { ToastUtils } from '../../../../session/utils';
 | |
| import { openConversationToSpecificMessage } from '../../../../state/ducks/conversations';
 | |
| import { StateType } from '../../../../state/reducer';
 | |
| import { useMessageDirection } from '../../../../state/selectors';
 | |
| import {
 | |
|   getMessageQuoteProps,
 | |
|   isMessageDetailView,
 | |
| } from '../../../../state/selectors/conversations';
 | |
| import { Quote } from './quote/Quote';
 | |
| 
 | |
| type Props = {
 | |
|   messageId: string;
 | |
| };
 | |
| 
 | |
| export type MessageQuoteSelectorProps = Pick<MessageRenderingProps, 'quote' | 'direction'>;
 | |
| 
 | |
| export const MessageQuote = (props: Props) => {
 | |
|   const selected = useSelector((state: StateType) => getMessageQuoteProps(state, props.messageId));
 | |
|   const direction = useMessageDirection(props.messageId);
 | |
|   const isMessageDetailViewMode = useSelector(isMessageDetailView);
 | |
| 
 | |
|   if (!selected || isEmpty(selected)) {
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   const quote = selected ? selected.quote : undefined;
 | |
| 
 | |
|   if (!quote || isEmpty(quote)) {
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   const quoteNotFound = Boolean(
 | |
|     quote.referencedMessageNotFound || !quote?.author || !quote.id || !quote.convoId
 | |
|   );
 | |
| 
 | |
|   const onQuoteClick = async (event: React.MouseEvent<HTMLDivElement>) => {
 | |
|     event.preventDefault();
 | |
|     event.stopPropagation();
 | |
| 
 | |
|     if (!quote) {
 | |
|       ToastUtils.pushOriginalNotFound();
 | |
|       window.log.warn('onQuoteClick: quote not valid');
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (isMessageDetailViewMode) {
 | |
|       // trying to scroll while in the container while the message detail view is shown has unknown effects
 | |
|       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) {
 | |
|       // 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,
 | |
|         },
 | |
|       ]);
 | |
| 
 | |
|       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;
 | |
|         }
 | |
|       } else {
 | |
|         quoteNotFoundInDB = true;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // 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.
 | |
|     if (quoteNotFoundInDB) {
 | |
|       ToastUtils.pushOriginalNotFound();
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     void openConversationToSpecificMessage({
 | |
|       conversationKey,
 | |
|       messageIdToNavigateTo,
 | |
|       shouldHighlightMessage: true,
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <Quote
 | |
|       // eslint-disable-next-line @typescript-eslint/no-misused-promises
 | |
|       onClick={onQuoteClick}
 | |
|       text={quote?.text}
 | |
|       attachment={quote?.attachment}
 | |
|       isIncoming={direction === 'incoming'}
 | |
|       author={quote.author}
 | |
|       referencedMessageNotFound={quoteNotFound}
 | |
|       isFromMe={Boolean(quote.isFromMe)}
 | |
|     />
 | |
|   );
 | |
| };
 |