@ -1,10 +1,13 @@
import classNames from 'classnames' ;
import classNames from 'classnames' ;
import { isEmpty } from 'lodash' ;
import { isEmpty } from 'lodash' ;
import moment from 'moment' ;
import moment from 'moment' ;
import React , { createContext, useCallback, useContext , useLayoutEffect , useState } from 'react' ;
import React , { useCallback, useLayoutEffect , useState } from 'react' ;
import { InView } from 'react-intersection-observer' ;
import { InView } from 'react-intersection-observer' ;
import { useSelector } from 'react-redux' ;
import { useSelector } from 'react-redux' ;
import styled from 'styled-components' ;
import styled from 'styled-components' ;
import { useScrollToLoadedMessage } from '../../../../contexts/ScrollToLoadedMessage' ;
import { useIsDetailMessageView } from '../../../../contexts/isDetailViewContext' ;
import { IsMessageVisibleContext } from '../../../../contexts/isMessageVisibleContext' ;
import { MessageModelType , MessageRenderingProps } from '../../../../models/messageType' ;
import { MessageModelType , MessageRenderingProps } from '../../../../models/messageType' ;
import { StateType } from '../../../../state/reducer' ;
import { StateType } from '../../../../state/reducer' ;
import {
import {
@ -19,7 +22,6 @@ import {
} from '../../../../state/selectors/conversations' ;
} from '../../../../state/selectors/conversations' ;
import { useSelectedIsPrivate } from '../../../../state/selectors/selectedConversation' ;
import { useSelectedIsPrivate } from '../../../../state/selectors/selectedConversation' ;
import { canDisplayImage } from '../../../../types/Attachment' ;
import { canDisplayImage } from '../../../../types/Attachment' ;
import { ScrollToLoadedMessageContext } from '../../SessionMessagesListContainer' ;
import { MessageAttachment } from './MessageAttachment' ;
import { MessageAttachment } from './MessageAttachment' ;
import { MessageAvatar } from './MessageAvatar' ;
import { MessageAvatar } from './MessageAvatar' ;
import { MessageHighlighter } from './MessageHighlighter' ;
import { MessageHighlighter } from './MessageHighlighter' ;
@ -34,7 +36,6 @@ export type MessageContentSelectorProps = Pick<
type Props = {
type Props = {
messageId : string ;
messageId : string ;
isDetailView? : boolean ;
} ;
} ;
// TODO not too sure what is this doing? It is not preventDefault()
// TODO not too sure what is this doing? It is not preventDefault()
@ -76,13 +77,13 @@ const StyledMessageOpaqueContent = styled(MessageHighlighter)<{
$ { props = > props . selected && ` box-shadow: var(--drop-shadow); ` }
$ { props = > props . selected && ` box-shadow: var(--drop-shadow); ` }
` ;
` ;
export const IsMessageVisibleContext = createContext ( false ) ;
const StyledAvatarContainer = styled . div `
const StyledAvatarContainer = styled . div `
align - self : flex - end ;
align - self : flex - end ;
` ;
` ;
export const MessageContent = ( props : Props ) = > {
export const MessageContent = ( props : Props ) = > {
const isDetailView = useIsDetailMessageView ( ) ;
const [ highlight , setHighlight ] = useState ( false ) ;
const [ highlight , setHighlight ] = useState ( false ) ;
const [ didScroll , setDidScroll ] = useState ( false ) ;
const [ didScroll , setDidScroll ] = useState ( false ) ;
const contentProps = useSelector ( ( state : StateType ) = >
const contentProps = useSelector ( ( state : StateType ) = >
@ -91,9 +92,9 @@ export const MessageContent = (props: Props) => {
const isDeleted = useMessageIsDeleted ( props . messageId ) ;
const isDeleted = useMessageIsDeleted ( props . messageId ) ;
const [ isMessageVisible , setMessageIsVisible ] = useState ( false ) ;
const [ isMessageVisible , setMessageIsVisible ] = useState ( false ) ;
const scrollToLoadedMessage = use Context( ScrollToLoadedMessageContext ) ;
const scrollToLoadedMessage = use ScrollToLoadedMessage( ) ;
const selectedIsPrivate = useSelectedIsPrivate ( ) ;
const selectedIsPrivate = useSelectedIsPrivate ( ) ;
const hideAvatar = useHideAvatarInMsgList ( props . messageId );
const hideAvatar = useHideAvatarInMsgList ( props . messageId , isDetailView );
const [ imageBroken , setImageBroken ] = useState ( false ) ;
const [ imageBroken , setImageBroken ] = useState ( false ) ;
@ -153,8 +154,7 @@ export const MessageContent = (props: Props) => {
const toolTipTitle = moment ( serverTimestamp || timestamp ) . format ( 'llll' ) ;
const toolTipTitle = moment ( serverTimestamp || timestamp ) . format ( 'llll' ) ;
const isDetailViewAndSupportsAttachmentCarousel =
const isDetailViewAndSupportsAttachmentCarousel = isDetailView && canDisplayImage ( attachments ) ;
props . isDetailView && canDisplayImage ( attachments ) ;
return (
return (
< StyledMessageContent
< StyledMessageContent
@ -164,14 +164,11 @@ export const MessageContent = (props: Props) => {
title = { toolTipTitle }
title = { toolTipTitle }
msgDirection = { direction }
msgDirection = { direction }
>
>
{ hideAvatar ? null : (
< StyledAvatarContainer >
< StyledAvatarContainer >
< MessageAvatar
< MessageAvatar messageId = { props . messageId } isPrivate = { selectedIsPrivate } / >
messageId = { props . messageId }
hideAvatar = { hideAvatar }
isPrivate = { selectedIsPrivate }
isDetailView = { props . isDetailView }
/ >
< / StyledAvatarContainer >
< / StyledAvatarContainer >
) }
< InView
< InView
id = { ` inview-content- ${ props . messageId } ` }
id = { ` inview-content- ${ props . messageId } ` }
@ -184,6 +181,7 @@ export const MessageContent = (props: Props) => {
display : 'flex' ,
display : 'flex' ,
flexDirection : 'column' ,
flexDirection : 'column' ,
gap : 'var(--margins-xs)' ,
gap : 'var(--margins-xs)' ,
maxWidth : '100%' ,
} }
} }
>
>
< IsMessageVisibleContext.Provider value = { isMessageVisible } >
< IsMessageVisibleContext.Provider value = { isMessageVisible } >