UNPKG

communication-react-19

Version:

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

137 lines 8.86 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import React, { useCallback, useMemo } from 'react'; import { noMessageStatusStyle, useChatMessageRenderStyles } from '../../styles/MessageThread.styles'; import { mergeStyles } from '@fluentui/react'; import { mergeClasses } from '@fluentui/react-components'; import { createStyleFromV8Style } from '../../styles/v8StyleShim'; import { ChatMyMessageComponent } from './ChatMyMessageComponent'; import { ChatMyMessage as FluentChatMyMessage } from '@fluentui-contrib/react-chat'; import { getFluentUIAttachedValue, removeFluentUIKeyboardNavigationStyles } from '../../utils/ChatMessageComponentUtils'; /** * The component for rendering a chat message using Fluent UI components * and handling default and custom renderers. * This component handles rendering for chat message body, avatar and message status. * The chat message body, avatar and message status should be shown for both default and custom renderers. * * @private */ export const FluentChatMyMessageComponent = (props) => { const { message, styles, shouldOverlapAvatarAndMessage, onRenderMessage, onRenderAvatar, showMessageStatus, onRenderMessageStatus, participantCount, readCount, onActionButtonClick, /* @conditional-compile-remove(date-time-customization) */ onDisplayDateTimeString, inlineImageOptions, /* @conditional-compile-remove(mention) */ mentionOptions, userId, defaultStatusRenderer, statusToRender, actionsForAttachment, onRenderAttachmentDownloads, /* @conditional-compile-remove(rich-text-editor) */ isRichTextEditorEnabled, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste, /* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImagesWithProgress, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onRemoveInlineImage, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onInsertInlineImage } = props; const chatMessageRenderStyles = useChatMessageRenderStyles(); // To rerender the defaultChatMessageRenderer if app running across days(every new day chat time stamp // needs to be regenerated), the dependency on "new Date().toDateString()"" is added. const defaultChatMessageRenderer = useCallback((messageProps) => { if (messageProps.message.messageType === 'chat' || /* @conditional-compile-remove(data-loss-prevention) */ messageProps.message.messageType === 'blocked') { return (React.createElement(ChatMyMessageComponent, Object.assign({}, messageProps, { onRenderAttachmentDownloads: onRenderAttachmentDownloads, strings: messageProps.strings, message: messageProps.message, userId: userId, remoteParticipantsCount: participantCount ? participantCount - 1 : 0, shouldOverlapAvatarAndMessage: shouldOverlapAvatarAndMessage, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus, messageStatus: messageProps.message.status, onActionButtonClick: onActionButtonClick, /* @conditional-compile-remove(date-time-customization) */ onDisplayDateTimeString: onDisplayDateTimeString, inlineImageOptions: inlineImageOptions, /* @conditional-compile-remove(mention) */ mentionOptions: mentionOptions, actionsForAttachment: actionsForAttachment, /* @conditional-compile-remove(rich-text-editor) */ isRichTextEditorEnabled: isRichTextEditorEnabled, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste: onPaste, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onRemoveInlineImage: onRemoveInlineImage, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onInsertInlineImage: onInsertInlineImage, /* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImagesWithProgress: inlineImagesWithProgress }))); } return React.createElement(React.Fragment, null); }, [ onActionButtonClick, onRenderAvatar, participantCount, shouldOverlapAvatarAndMessage, showMessageStatus, userId, /* @conditional-compile-remove(date-time-customization) */ onDisplayDateTimeString, inlineImageOptions, /* @conditional-compile-remove(mention) */ mentionOptions, onRenderAttachmentDownloads, actionsForAttachment, // eslint-disable-next-line react-hooks/exhaustive-deps new Date().toDateString(), /* @conditional-compile-remove(rich-text-editor) */ isRichTextEditorEnabled, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onRemoveInlineImage, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onInsertInlineImage, /* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImagesWithProgress ]); const messageRenderer = useCallback((messageProps) => { return onRenderMessage === undefined ? defaultChatMessageRenderer(Object.assign({}, messageProps)) : onRenderMessage(messageProps, defaultChatMessageRenderer); }, [defaultChatMessageRenderer, onRenderMessage]); const messageStatusRenderer = useCallback((onRenderMessageStatus, defaultStatusRenderer, showMessageStatus, participantCount, readCount) => { return showMessageStatus && statusToRender ? (onRenderMessageStatus ? (onRenderMessageStatus({ status: message.status })) : (defaultStatusRenderer(message, participantCount !== null && participantCount !== void 0 ? participantCount : 0, readCount !== null && readCount !== void 0 ? readCount : 0, message.status))) : (React.createElement("div", { className: mergeStyles(noMessageStatusStyle) })); }, [message, statusToRender]); const attached = useMemo(() => { return getFluentUIAttachedValue(message.attached); }, [message.attached]); const myMessageRootProps = useMemo(() => { return { // myChatItemMessageContainer used in className and style prop as style prop can't handle CSS selectors className: mergeClasses(chatMessageRenderStyles.rootMyMessage, chatMessageRenderStyles.rootCommon, mergeStyles(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer)), style: (styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer) !== undefined ? createStyleFromV8Style(styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer) : {}, role: 'none' }; }, [chatMessageRenderStyles.rootCommon, chatMessageRenderStyles.rootMyMessage, styles === null || styles === void 0 ? void 0 : styles.myChatItemMessageContainer]); const setMessageContainerRef = useCallback((node) => { removeFluentUIKeyboardNavigationStyles(node); }, []); const myMessageBodyProps = useMemo(() => { return { className: mergeClasses(chatMessageRenderStyles.bodyCommon, chatMessageRenderStyles.bodyMyMessage), ref: setMessageContainerRef }; }, [chatMessageRenderStyles.bodyCommon, chatMessageRenderStyles.bodyMyMessage, setMessageContainerRef]); const myMessageStatusIcon = useMemo(() => { var _a; return (React.createElement("div", { className: mergeStyles({ paddingLeft: '0.25rem' }, (styles === null || styles === void 0 ? void 0 : styles.messageStatusContainer) ? styles.messageStatusContainer((_a = message.mine) !== null && _a !== void 0 ? _a : false) : '') }, message.status ? messageStatusRenderer(onRenderMessageStatus, defaultStatusRenderer, showMessageStatus, participantCount, readCount) : undefined)); }, [ defaultStatusRenderer, message.mine, message.status, messageStatusRenderer, onRenderMessageStatus, participantCount, readCount, showMessageStatus, styles ]); // Fluent UI message components are used here as for default message renderer, // timestamp and author name should be shown but they aren't shown for custom renderer. // More investigations are needed to check if this can be simplified with states. // Status and avatar should be shown for both custom and default renderers. return (React.createElement(FluentChatMyMessage, { attached: attached, root: myMessageRootProps, body: myMessageBodyProps, statusIcon: myMessageStatusIcon }, messageRenderer(Object.assign({}, props)))); }; //# sourceMappingURL=FluentChatMyMessageComponent.js.map