import classNames from 'classnames'; import React, { useCallback, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; import { replyToMessage } from '../../../../interactions/conversationInteractions'; import { MessageRenderingProps } from '../../../../models/messageType'; import { toggleSelectedMessageId } from '../../../../state/ducks/conversations'; import { updateReactListModal } from '../../../../state/ducks/modalDialog'; import { getMessageContentWithStatusesSelectorProps, isMessageSelectionMode, } from '../../../../state/selectors/conversations'; import { Reactions } from '../../../../util/reactions'; import { MessageAvatar } from '../message-content/MessageAvatar'; import { MessageAuthorText } from './MessageAuthorText'; import { MessageContent } from './MessageContent'; import { MessageContextMenu } from './MessageContextMenu'; import { MessageReactions, StyledMessageReactions } from './MessageReactions'; import { MessageStatus } from './MessageStatus'; export type MessageContentWithStatusSelectorProps = Pick< MessageRenderingProps, 'direction' | 'isDeleted' >; type Props = { messageId: string; ctxMenuID: string; isDetailView?: boolean; dataTestId?: string; enableReactions: boolean; }; // tslint:disable: use-simple-attributes const StyledMessageContentContainer = styled.div<{ direction: 'left' | 'right' }>` display: flex; flex-direction: column; justify-content: flex-start; align-items: ${props => (props.direction === 'left' ? 'flex-start' : 'flex-end')}; width: 100%; ${StyledMessageReactions} { margin-right: var(--margins-sm); } `; const StyledMessageWithAuthor = styled.div<{ isIncoming: boolean }>` max-width: ${props => (props.isIncoming ? '100%' : 'calc(100% - 17px)')}; `; 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) => { if (multiSelectMode && messageId) { event.preventDefault(); event.stopPropagation(); dispatch(toggleSelectedMessageId(messageId)); } }, [window.contextMenuShown, props?.messageId, multiSelectMode, props?.isDetailView] ); const onDoubleClickReplyToMessage = (e: React.MouseEvent) => { const currentSelection = window.getSelection(); const currentSelectionString = currentSelection?.toString() || undefined; if ((e.target as any).localName !== 'em-emoji-picker') { if ( !currentSelectionString || currentSelectionString.length === 0 || !/\s/.test(currentSelectionString) ) { // if multiple word are selected, consider that this double click was actually NOT used to reply to // but to select void replyToMessage(messageId); currentSelection?.empty(); e.preventDefault(); return; } } }; const { messageId, ctxMenuID, isDetailView, dataTestId, enableReactions } = props; if (!contentProps) { return null; } const { direction, isDeleted } = contentProps; const isIncoming = direction === 'incoming'; const [popupReaction, setPopupReaction] = useState(''); const handleMessageReaction = async (emoji: string) => { await Reactions.sendMessageReaction(messageId, emoji); }; const handlePopupClick = () => { dispatch(updateReactListModal({ reaction: popupReaction, messageId })); }; return ( { setPopupReaction(''); }} >
{!isDeleted && ( )}
{enableReactions && ( )}
); };