import { IStyle , mergeStyles } from '@fluentui/react' ; import { Chat , Text , ComponentSlotStyle } from '@fluentui/react-northstar' ; import { _formatString } from '@internal/acs-ui-common' ; import React , { useCallback , useRef , useState } from 'react' ; import { chatMessageEditedTagStyle , chatMessageDateStyle } from '../styles/ChatMessageComponent.styles' ; import { formatTimeForChatMessage , formatTimestampForChatMessage } from '../utils/Datetime' ; import { useIdentifiers } from '../../identifiers/IdentifierProvider' ; import { useTheme } from '../../theming' ; import { ChatMessageActionFlyout } from './ChatMessageActionsFlyout' ; import { ChatMessageContent } from './ChatMessageContent' ; import { ChatMessage } from '../../types/ChatMessage' ; import { MessageThreadStrings } from '../MessageThread' ; import { chatMessageActionMenuProps } from './ChatMessageActionMenu' ; type ChatMessageComponentAsMessageBubbleProps = { message : ChatMessage ; messageContainerStyle ? : ComponentSlotStyle ; showDate ? : boolean ; disableEditing ? : boolean ; onEditClick : ( ) => void ; onRemoveClick ? : ( ) => void ; strings : MessageThreadStrings ; } ; private export const ChatMessageComponentAsMessageBubble = ( props ) : JSX . Element => { const ids = useIdentifiers ( ) ; const theme = useTheme ( ) ; const { message , onRemoveClick , disableEditing , showDate , messageContainerStyle , strings , onEditClick } = props ; const [ wasInteractionByTouch , setWasInteractionByTouch ] = useState ( false ) ; const messageRef = useRef < HTMLDivElement | null > ( null ) ; const messageActionButtonRef = useRef < HTMLElement | null > ( null ) ; const [ chatMessageActionFlyoutTarget , setChatMessageActionFlyoutTarget ] = useState < React . MutableRefObject < HTMLElement | null > | undefined > ( undefined ) ; const chatActionsEnabled = ! disableEditing && message . status !== 'sending' && ! ! message . mine ; const actionMenuProps = wasInteractionByTouch ? undefined : chatMessageActionMenuProps ( { enabled : chatActionsEnabled , menuButtonRef : messageActionButtonRef , forceShow : chatMessageActionFlyoutTarget === messageActionButtonRef , onActionButtonClick : ( ) => { setChatMessageActionFlyoutTarget ( messageActionButtonRef ) ; } , theme } ) ; const onActionFlyoutDismiss = useCallback ( ( ) : void => { setChatMessageActionFlyoutTarget ( undefined ) ; } , [ setChatMessageActionFlyoutTarget ] ) ; const chatMessage = ( < > < div ref = { messageRef } > < Chat . Message className = { mergeStyles ( messageContainerStyle as IStyle ) } styles = { messageContainerStyle } content = { < ChatMessageContent message = { message } liveAuthorIntro = { strings . liveAuthorIntro } / > } author = { < Text className = { chatMessageDateStyle } > { message . senderDisplayName } < /Text>} mine={message.mine} timestamp={<Text data-ui-id={ids.messageTimestamp}> { message . createdOn ? showDate ? formatTimestampForChatMessage ( message . createdOn , new Date ( ) , strings ) : formatTimeForChatMessage ( message . createdOn ) : undefined } < /Text>} details={message.editedOn ? <div className={chatMessageEditedTagStyle(theme)}>{strings.editedTag}</div > : undefined } positionActionMenu = { false } actionMenu = { actionMenuProps } onTouchStart = { ( ) => setWasInteractionByTouch ( true ) } onPointerDown = { ( ) => setWasInteractionByTouch ( false ) } onKeyDown = { ( ) => setWasInteractionByTouch ( false ) } onClick = { ( ) => wasInteractionByTouch && setChatMessageActionFlyoutTarget ( messageRef ) } /> < /div> { chatActionsEnabled && ( < ChatMessageActionFlyout hidden = { ! chatMessageActionFlyoutTarget } target = { chatMessageActionFlyoutTarget } increaseFlyoutItemSize = { wasInteractionByTouch } onDismiss = { onActionFlyoutDismiss } onEditClick = { onEditClick } onRemoveClick = { onRemoveClick } strings = { strings } / > ) } < />); return chatMessage ; } ;