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.
		
		
		
		
		
			
		
			
				
	
	
		
			97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
| import classNames from 'classnames';
 | |
| import React, { useCallback } from 'react';
 | |
| import { useDispatch, useSelector } from 'react-redux';
 | |
| import _ from 'underscore';
 | |
| import { replyToMessage } from '../../../../interactions/conversationInteractions';
 | |
| import { MessageRenderingProps, QuoteClickOptions } from '../../../../models/messageType';
 | |
| import { toggleSelectedMessageId } from '../../../../state/ducks/conversations';
 | |
| import {
 | |
|   getMessageContentWithStatusesSelectorProps,
 | |
|   isMessageSelectionMode,
 | |
| } from '../../../../state/selectors/conversations';
 | |
| 
 | |
| import { MessageAuthorText } from './MessageAuthorText';
 | |
| import { MessageContent } from './MessageContent';
 | |
| import { MessageContextMenu } from './MessageContextMenu';
 | |
| import { MessageStatus } from './MessageStatus';
 | |
| 
 | |
| export type MessageContentWithStatusSelectorProps = Pick<
 | |
|   MessageRenderingProps,
 | |
|   'direction' | 'isDeleted' | 'isTrustedForAttachmentDownload'
 | |
| > & { hasAttachments: boolean };
 | |
| 
 | |
| type Props = {
 | |
|   messageId: string;
 | |
|   onQuoteClick: (quote: QuoteClickOptions) => void;
 | |
|   ctxMenuID: string;
 | |
|   isDetailView?: boolean;
 | |
| };
 | |
| 
 | |
| export const MessageContentWithStatuses = (props: Props) => {
 | |
|   const contentProps = useSelector(state =>
 | |
|     getMessageContentWithStatusesSelectorProps(state as any, props.messageId)
 | |
|   );
 | |
|   const dispatch = useDispatch();
 | |
| 
 | |
|   const multiSelectMode = useSelector(isMessageSelectionMode);
 | |
| 
 | |
|   const onClickOnMessageOuterContainer = useCallback(
 | |
|     (event: React.MouseEvent<HTMLDivElement>) => {
 | |
|       if (multiSelectMode && messageId) {
 | |
|         event.preventDefault();
 | |
|         event.stopPropagation();
 | |
|         dispatch(toggleSelectedMessageId(messageId));
 | |
|       }
 | |
|     },
 | |
|     [window.contextMenuShown, props?.messageId, multiSelectMode, props?.isDetailView]
 | |
|   );
 | |
| 
 | |
|   const onDoubleClickReplyToMessage = (e: React.MouseEvent<HTMLDivElement>) => {
 | |
|     const currentSelection = window.getSelection();
 | |
|     const currentSelectionString = currentSelection?.toString() || undefined;
 | |
| 
 | |
|     // if multiple word are selected, consider that this double click was actually NOT used to reply to
 | |
|     // but to select
 | |
|     if (
 | |
|       !currentSelectionString ||
 | |
|       currentSelectionString.length === 0 ||
 | |
|       !currentSelectionString.includes(' ')
 | |
|     ) {
 | |
|       void replyToMessage(messageId);
 | |
|       currentSelection?.empty();
 | |
|       e.preventDefault();
 | |
|       return;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const { messageId, onQuoteClick, ctxMenuID, isDetailView } = props;
 | |
|   if (!contentProps) {
 | |
|     return null;
 | |
|   }
 | |
|   const { direction, isDeleted, hasAttachments, isTrustedForAttachmentDownload } = contentProps;
 | |
|   const isIncoming = direction === 'incoming';
 | |
| 
 | |
|   return (
 | |
|     <div
 | |
|       className={classNames('module-message', `module-message--${direction}`)}
 | |
|       role="button"
 | |
|       onClick={onClickOnMessageOuterContainer}
 | |
|       onDoubleClickCapture={onDoubleClickReplyToMessage}
 | |
|       style={{ width: hasAttachments && isTrustedForAttachmentDownload ? 'min-content' : 'auto' }}
 | |
|     >
 | |
|       <MessageStatus messageId={messageId} isCorrectSide={isIncoming} />
 | |
|       <div>
 | |
|         <MessageAuthorText messageId={messageId} />
 | |
| 
 | |
|         <MessageContent
 | |
|           messageId={messageId}
 | |
|           isDetailView={isDetailView}
 | |
|           onQuoteClick={onQuoteClick}
 | |
|         />
 | |
|       </div>
 | |
|       <MessageStatus messageId={messageId} isCorrectSide={!isIncoming} />
 | |
|       {!isDeleted && <MessageContextMenu messageId={messageId} contextMenuId={ctxMenuID} />}
 | |
|     </div>
 | |
|   );
 | |
| };
 |