UNPKG

communication-react-19

Version:

React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)

84 lines 5.36 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Text, mergeStyles } from '@fluentui/react'; import { ChatMessage as FluentChatMessage } from '@fluentui-contrib/react-chat'; import React, { useCallback, useMemo } from 'react'; import { chatMessageDateStyle, chatMessageAuthorStyle, chatMessageDateFailedStyle } from '../../styles/ChatMessageComponent.styles'; import { useIdentifiers } from '../../../identifiers/IdentifierProvider'; import { useTheme } from '../../../theming'; import { useLocale } from '../../../localization'; import { createStyleFromV8Style } from '../../styles/v8StyleShim'; import { mergeClasses } from '@fluentui/react-components'; import { useChatMessageStyles, useChatMessageCommonStyles } from '../../styles/MessageThread.styles'; import { generateCustomizedTimestamp, generateDefaultTimestamp, getMessageBubbleContent, getMessageEditedDetails } from '../../utils/ChatMessageComponentUtils'; /* @conditional-compile-remove(file-sharing-acs) */ import { doesMessageContainMultipleAttachments } from '../../utils/ChatMessageComponentAsEditBoxUtils'; /** @private */ const MessageBubble = (props) => { const ids = useIdentifiers(); const theme = useTheme(); const locale = useLocale(); const { userId, message, showDate, messageContainerStyle, strings, onRenderAttachmentDownloads, inlineImageOptions, shouldOverlapAvatarAndMessage, actionsForAttachment, /* @conditional-compile-remove(mention) */ mentionDisplayOptions, onDisplayDateTimeString } = props; const formattedTimestamp = useMemo(() => { const defaultTimeStamp = message.createdOn ? generateDefaultTimestamp(message.createdOn, showDate, strings) : undefined; const customTimestamp = message.createdOn ? generateCustomizedTimestamp(message.createdOn, locale, onDisplayDateTimeString) : ''; return customTimestamp || defaultTimeStamp; }, [locale, message.createdOn, onDisplayDateTimeString, showDate, strings]); const getMessageDetails = useCallback(() => { return getMessageEditedDetails(message, theme, strings.editedTag); }, [strings.editedTag, theme, message]); const getContent = useCallback(() => { return getMessageBubbleContent(message, strings, userId, inlineImageOptions, /* @conditional-compile-remove(mention) */ mentionDisplayOptions, onRenderAttachmentDownloads, actionsForAttachment); }, [ actionsForAttachment, inlineImageOptions, /* @conditional-compile-remove(mention) */ mentionDisplayOptions, message, onRenderAttachmentDownloads, strings, userId ]); const isBlockedMessage = // eslint-disable-next-line no-constant-binary-expression false || /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked'; const chatMessageCommonStyles = useChatMessageCommonStyles(); /* @conditional-compile-remove(file-sharing-acs) */ const hasMultipleAttachments = useMemo(() => { return doesMessageContainMultipleAttachments(message); }, [message]); const chatMessageStyles = useChatMessageStyles(); const chatItemMessageContainerClassName = mergeClasses(chatMessageCommonStyles.body, chatMessageStyles.body, // disable placeholder functionality for GA releases as it might confuse users chatMessageCommonStyles.bodyWithPlaceholderImage, isBlockedMessage ? chatMessageCommonStyles.blocked : props.message.status === 'failed' ? chatMessageCommonStyles.failed : undefined, shouldOverlapAvatarAndMessage ? chatMessageStyles.avatarOverlap : chatMessageStyles.avatarNoOverlap, /* @conditional-compile-remove(file-sharing-acs) */ hasMultipleAttachments ? chatMessageStyles.multipleAttachments : undefined, message.attached === 'top' || message.attached === false ? chatMessageStyles.bodyWithAvatar : chatMessageStyles.bodyWithoutAvatar, // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors mergeStyles(messageContainerStyle)); const attached = message.attached === true ? 'center' : message.attached === 'bottom' ? 'bottom' : 'top'; const chatMessage = (React.createElement(React.Fragment, null, React.createElement("div", { key: props.message.messageId }, React.createElement(FluentChatMessage, { attached: attached, key: props.message.messageId, root: { className: chatMessageStyles.root }, author: React.createElement(Text, { className: chatMessageAuthorStyle }, message.senderDisplayName), body: { className: chatItemMessageContainerClassName, style: Object.assign({}, createStyleFromV8Style(messageContainerStyle)) }, "data-testid": "chat-composite-message", timestamp: React.createElement(Text, { className: props.message.status === 'failed' ? chatMessageDateFailedStyle(theme) : chatMessageDateStyle(theme), "data-testid": ids.messageTimestamp }, formattedTimestamp), details: getMessageDetails() }, getContent())))); return chatMessage; }; /** @private */ export const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble); //# sourceMappingURL=ChatMessageComponentAsMessageBubble.js.map