@azure/communication-react 1.13.1-alpha-202402280012 → 1.14.0-alpha-202403010014
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/communication-react.d.ts +1 -1
- package/dist/dist-cjs/communication-react/index.js +161 -66
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/common.d.ts +5 -0
- package/dist/dist-esm/acs-ui-common/src/common.js +7 -0
- package/dist/dist-esm/acs-ui-common/src/common.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.d.ts +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js +12 -2
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.d.ts +1 -0
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.js +33 -17
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js +4 -4
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +6 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MentionRenderer.js +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MentionRenderer.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js +1 -1
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ImageOverlay.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/ImageOverlay.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/Survey/TagsSurvey/TagsSurvey.js +4 -4
- package/dist/dist-esm/react-components/src/components/Survey/TagsSurvey/TagsSurvey.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils.d.ts +0 -6
- package/dist/dist-esm/react-components/src/components/utils.js +0 -8
- package/dist/dist-esm/react-components/src/components/utils.js.map +1 -1
- package/dist/dist-esm/react-components/src/localization/locales/utils.js +2 -2
- package/dist/dist-esm/react-components/src/localization/locales/utils.js.map +1 -1
- package/dist/dist-esm/react-components/src/types/ChatMessage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +3 -7
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallingSoundSubscriber.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallingSoundSubscriber.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallReadinessModal.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallReadinessModal.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/hooks/useHandlers.js +15 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/hooks/useHandlers.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js +9 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js +8 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatComposite.js +6 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/ChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/hooks/useHandlers.js +3 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/hooks/useHandlers.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CustomButton.d.ts +10 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CustomButton.js +5 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CustomButton.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/CaptionLanguageSettingsDrawer.d.ts +21 -0
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/CaptionLanguageSettingsDrawer.js +43 -0
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/CaptionLanguageSettingsDrawer.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js +4 -3
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/SpokenLanguageSettingsDrawer.d.ts +21 -0
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/{CaptionSettingsDrawer.js → SpokenLanguageSettingsDrawer.js} +4 -3
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/SpokenLanguageSettingsDrawer.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/common/ModalLocalAndRemotePIP.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/MoreButton.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/PeoplePaneContent.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/common/PeoplePaneContent.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Survey.js +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Survey.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/styles/Survey.styles.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/styles/Survey.styles.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/utils.js +5 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/utils.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/CaptionSettingsDrawer.d.ts +0 -21
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/CaptionSettingsDrawer.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Text, mergeStyles, IStyle } from '@fluentui/react';\nimport { ChatMessage as FluentChatMessage, ChatMyMessage } from '@fluentui-contrib/react-chat';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useRef, useState } from 'react';\nimport {\n chatMessageEditedTagStyle,\n chatMessageDateStyle,\n chatMessageFailedTagStyle,\n chatMessageAuthorStyle\n} from '../styles/ChatMessageComponent.styles';\nimport { formatTimeForChatMessage, formatTimestampForChatMessage } from '../utils/Datetime';\nimport { useIdentifiers } from '../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../theming';\nimport { ChatMessageActionFlyout } from './ChatMessageActionsFlyout';\nimport { ChatMessageContent } from './ChatMessageContent';\n/* @conditional-compile-remove(image-overlay) */\nimport { InlineImageOptions } from './ChatMessageContent';\nimport { ChatMessage } from '../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessageContent } from './ChatMessageContent';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types/ChatMessage';\nimport { MessageThreadStrings } from '../MessageThread';\nimport { chatMessageActionMenuProps } from './ChatMessageActionMenu';\nimport { ComponentSlotStyle, OnRenderAvatarCallback } from '../../types';\n/* @conditional-compile-remove(file-sharing) */\nimport { FileDownloadHandler } from '../FileDownloadCards';\nimport { _FileDownloadCards } from '../FileDownloadCards';\nimport { ComponentLocale, useLocale } from '../../localization';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions } from '../MentionPopover';\nimport { createStyleFromV8Style } from '../styles/v8StyleShim';\nimport { MessageStatus } from '@internal/acs-ui-common';\nimport { mergeClasses } from '@fluentui/react-components';\nimport {\n useChatMessageStyles,\n useChatMyMessageStyles,\n useChatMessageCommonStyles\n} from '../styles/MessageThread.styles';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n messageContainerStyle?: ComponentSlotStyle;\n /** Styles for message status indicator container. */\n messageStatusContainer?: (mine: boolean) => IStyle;\n showDate?: boolean;\n disableEditing?: boolean;\n onEditClick: () => void;\n onRemoveClick?: () => void;\n onResendClick?: () => void;\n strings: MessageThreadStrings;\n userId: string;\n messageStatus?: string;\n /**\n * Whether the status indicator for each message is displayed or not.\n */\n showMessageStatus?: boolean;\n messageStatusRenderer?: (status: MessageStatus) => JSX.Element | null;\n /**\n * Whether to overlap avatar and message when the view is width constrained.\n */\n shouldOverlapAvatarAndMessage: boolean;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n remoteParticipantsCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (readBy: { id: string; displayName: string }[]) => void\n ) => void;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to display suggestions in the mention scenario.\n * @internal\n */\n mentionDisplayOptions?: MentionDisplayOptions;\n /* @conditional-compile-remove(image-overlay) */\n /**\n * Optional callback called when an inline image is clicked.\n * @beta\n */\n inlineImageOptions?: InlineImageOptions;\n};\n\nconst generateDefaultTimestamp = (\n createdOn: Date,\n showDate: boolean | undefined,\n strings: MessageThreadStrings\n): string => {\n const formattedTimestamp = showDate\n ? formatTimestampForChatMessage(createdOn, new Date(), strings)\n : formatTimeForChatMessage(createdOn);\n\n return formattedTimestamp;\n};\n\n// onDisplayDateTimeString from props overwrite onDisplayDateTimeString from locale\nconst generateCustomizedTimestamp = (\n props: ChatMessageComponentAsMessageBubbleProps,\n createdOn: Date,\n locale: ComponentLocale\n): string => {\n /* @conditional-compile-remove(date-time-customization) */\n return props.onDisplayDateTimeString\n ? props.onDisplayDateTimeString(createdOn)\n : locale.onDisplayDateTimeString\n ? locale.onDisplayDateTimeString(createdOn)\n : '';\n\n return '';\n};\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n onRemoveClick,\n onResendClick,\n disableEditing,\n showDate,\n messageContainerStyle,\n strings,\n onEditClick,\n remoteParticipantsCount = 0,\n onRenderAvatar,\n showMessageStatus,\n messageStatus,\n /* @conditional-compile-remove(file-sharing) */\n fileDownloadHandler,\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions,\n shouldOverlapAvatarAndMessage\n } = props;\n\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn ? generateCustomizedTimestamp(props, message.createdOn, locale) : '';\n\n const formattedTimestamp = customTimestamp || defaultTimeStamp;\n\n // Track if the action menu was opened by touch - if so we increase the touch targets for the items\n const [wasInteractionByTouch, setWasInteractionByTouch] = useState(false);\n // `focused` state is used for show/hide actionMenu\n const [focused, setFocused] = React.useState<boolean>(false);\n\n // The chat message action flyout should target the Chat.Message action menu if clicked,\n // or target the chat message if opened via touch press.\n // Undefined indicates the flyout menu should not be being shown.\n const messageRef = useRef<HTMLDivElement | null>(null);\n const messageActionButtonRef = useRef<HTMLDivElement | null>(null);\n const [chatMessageActionFlyoutTarget, setChatMessageActionFlyoutTarget] = useState<\n React.MutableRefObject<HTMLElement | null> | undefined\n >(undefined);\n\n const chatActionsEnabled =\n !disableEditing &&\n message.status !== 'sending' &&\n !!message.mine &&\n /* @conditional-compile-remove(data-loss-prevention) */ message.messageType !== 'blocked';\n const [messageReadBy, setMessageReadBy] = useState<{ id: string; displayName: string }[]>([]);\n\n const actionMenuProps = chatMessageActionMenuProps({\n ariaLabel: strings.actionMenuMoreOptions ?? '',\n enabled: chatActionsEnabled,\n menuButtonRef: messageActionButtonRef,\n menuExpanded: chatMessageActionFlyoutTarget === messageActionButtonRef,\n onActionButtonClick: () => {\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n setChatMessageActionFlyoutTarget(messageActionButtonRef);\n }\n },\n theme\n });\n\n const onActionFlyoutDismiss = useCallback((): void => {\n // When the flyout dismiss is called, since we control if the action flyout is visible\n // or not we need to set the target to undefined here to actually hide the action flyout\n setChatMessageActionFlyoutTarget(undefined);\n }, [setChatMessageActionFlyoutTarget]);\n\n const defaultOnRenderFileDownloads = useCallback(() => {\n /* @conditional-compile-remove(file-sharing) */\n return (\n <_FileDownloadCards\n userId={userId}\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing)*/\n fileMetadata={(message as ChatMessage).files || []}\n /* @conditional-compile-remove(file-sharing) */\n downloadHandler={fileDownloadHandler}\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing)*/\n strings={{ downloadFile: strings.downloadFile, fileCardGroupMessage: strings.fileCardGroupMessage }}\n />\n );\n }, [\n userId,\n message,\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing)*/\n strings,\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing)*/\n fileDownloadHandler\n ]);\n\n const editedOn = 'editedOn' in message ? message.editedOn : undefined;\n const getMessageDetails = useCallback(() => {\n if (messageStatus === 'failed') {\n return <div className={chatMessageFailedTagStyle(theme)}>{strings.failToSendTag}</div>;\n } else if (message.messageType === 'chat' && editedOn) {\n return <div className={chatMessageEditedTagStyle(theme)}>{strings.editedTag}</div>;\n }\n return undefined;\n }, [editedOn, message.messageType, messageStatus, strings.editedTag, strings.failToSendTag, theme]);\n\n const getContent = useCallback(() => {\n /* @conditional-compile-remove(data-loss-prevention) */\n if (message.messageType === 'blocked') {\n return (\n <div tabIndex={0}>\n <BlockedMessageContent message={message} strings={strings} />\n </div>\n );\n }\n return (\n <div tabIndex={0} className=\"ui-chat__message__content\">\n <ChatMessageContent\n message={message}\n strings={strings}\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions={props.mentionDisplayOptions}\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions={inlineImageOptions}\n />\n {\n /* @conditional-compile-remove(file-sharing) */ props.onRenderFileDownloads\n ? props.onRenderFileDownloads(userId, message)\n : defaultOnRenderFileDownloads()\n }\n </div>\n );\n }, [\n defaultOnRenderFileDownloads,\n /* @conditional-compile-remove(image-overlay) */ inlineImageOptions,\n message,\n props,\n strings,\n userId\n ]);\n\n const isBlockedMessage =\n false || /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked';\n const chatMyMessageStyles = useChatMyMessageStyles();\n const chatMessageCommonStyles = useChatMessageCommonStyles();\n\n const chatMessageStyles = useChatMessageStyles();\n const chatItemMessageContainerClassName = mergeClasses(\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n chatMessageStyles.body,\n // disable placeholder functionality for GA releases as it might confuse users\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n chatMessageStyles.bodyWithPlaceholderImage,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n shouldOverlapAvatarAndMessage ? chatMessageStyles.avatarOverlap : chatMessageStyles.avatarNoOverlap,\n message.attached === 'top' || message.attached === false\n ? chatMessageStyles.bodyWithAvatar\n : chatMessageStyles.bodyWithoutAvatar,\n mergeStyles(messageContainerStyle)\n );\n\n const attached = message.attached === true ? 'center' : message.attached === 'bottom' ? 'bottom' : 'top';\n const chatMessage = (\n <>\n <div key={props.message.messageId}>\n {message.mine ? (\n <ChatMyMessage\n attached={attached}\n key={props.message.messageId}\n body={{\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n className: mergeClasses(\n chatMyMessageStyles.body,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n attached !== 'top' ? chatMyMessageStyles.bodyAttached : undefined,\n mergeStyles(messageContainerStyle)\n ),\n style: { ...createStyleFromV8Style(messageContainerStyle) },\n ref: messageRef\n }}\n root={{\n className: chatMyMessageStyles.root,\n onBlur: (e) => {\n // `focused` controls is focused the whole `ChatMessage` or any of its children. When we're navigating\n // with keyboard the focused element will be changed and there is no way to use `:focus` selector\n if (chatMessageActionFlyoutTarget?.current) {\n // doesn't dismiss action button if flyout is open, otherwise, narrator's focus will stay on the closed action menu\n return;\n }\n const shouldPreserveFocusState = e.currentTarget.contains(e.relatedTarget);\n setFocused(shouldPreserveFocusState);\n },\n onFocus: () => {\n // react onFocus is called even when nested component receives focus (i.e. it bubbles)\n // so when focus moves within actionMenu, the `focus` state in chatMessage remains true, and keeps actionMenu visible\n setFocused(true);\n },\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n role: 'none',\n tabIndex: -1\n }}\n data-ui-id=\"chat-composite-message\"\n author={\n <Text className={chatMessageDateStyle} tabIndex={0}>\n {message.senderDisplayName}\n </Text>\n }\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp} tabIndex={0}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n actions={{\n children: actionMenuProps?.children,\n className: mergeClasses(\n chatMyMessageStyles.menu,\n // Make actions menu visible when the message is focused or the flyout is shown\n focused || chatMessageActionFlyoutTarget?.current\n ? chatMyMessageStyles.menuVisible\n : chatMyMessageStyles.menuHidden,\n attached !== 'top' ? chatMyMessageStyles.menuAttached : undefined\n )\n }}\n onTouchStart={() => setWasInteractionByTouch(true)}\n onPointerDown={() => setWasInteractionByTouch(false)}\n onKeyDown={() => setWasInteractionByTouch(false)}\n onClick={() => {\n if (!wasInteractionByTouch) {\n return;\n }\n // If the message was touched via touch we immediately open the menu\n // flyout (when using mouse the 3-dot menu that appears on hover\n // must be clicked to open the flyout).\n // In doing so here we set the target of the flyout to be the message and\n // not the 3-dot menu button to position the flyout correctly.\n setChatMessageActionFlyoutTarget(messageRef);\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n }\n }}\n >\n {getContent()}\n </ChatMyMessage>\n ) : (\n <FluentChatMessage\n attached={attached}\n key={props.message.messageId}\n root={{\n className: chatMessageStyles.root,\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n tabIndex: -1,\n role: 'none'\n }}\n author={<Text className={chatMessageAuthorStyle}>{message.senderDisplayName}</Text>}\n body={{\n className: chatItemMessageContainerClassName,\n style: { ...createStyleFromV8Style(messageContainerStyle) }\n }}\n data-ui-id=\"chat-composite-message\"\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n >\n {getContent()}\n </FluentChatMessage>\n )}\n </div>\n {chatActionsEnabled && (\n <ChatMessageActionFlyout\n hidden={!chatMessageActionFlyoutTarget}\n target={chatMessageActionFlyoutTarget}\n increaseFlyoutItemSize={wasInteractionByTouch}\n onDismiss={onActionFlyoutDismiss}\n onEditClick={onEditClick}\n onRemoveClick={onRemoveClick}\n onResendClick={onResendClick}\n strings={strings}\n messageReadBy={messageReadBy}\n messageStatus={messageStatus ?? 'failed'}\n remoteParticipantsCount={remoteParticipantsCount}\n onRenderAvatar={onRenderAvatar}\n showMessageStatus={showMessageStatus}\n />\n )}\n </>\n );\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n"]}
|
1
|
+
{"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Text, mergeStyles, IStyle } from '@fluentui/react';\nimport { ChatMessage as FluentChatMessage, ChatMyMessage } from '@fluentui-contrib/react-chat';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useRef, useState } from 'react';\nimport {\n chatMessageEditedTagStyle,\n chatMessageDateStyle,\n chatMessageFailedTagStyle,\n chatMessageAuthorStyle\n} from '../styles/ChatMessageComponent.styles';\nimport { formatTimeForChatMessage, formatTimestampForChatMessage } from '../utils/Datetime';\nimport { useIdentifiers } from '../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../theming';\nimport { ChatMessageActionFlyout } from './ChatMessageActionsFlyout';\nimport { ChatMessageContent } from './ChatMessageContent';\n/* @conditional-compile-remove(image-overlay) */\nimport { InlineImageOptions } from './ChatMessageContent';\nimport { ChatMessage } from '../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessageContent } from './ChatMessageContent';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types/ChatMessage';\nimport { MessageThreadStrings } from '../MessageThread';\nimport { chatMessageActionMenuProps } from './ChatMessageActionMenu';\nimport { ComponentSlotStyle, OnRenderAvatarCallback } from '../../types';\n/* @conditional-compile-remove(file-sharing) */\nimport { FileDownloadHandler } from '../FileDownloadCards';\nimport { _FileDownloadCards } from '../FileDownloadCards';\nimport { ComponentLocale, useLocale } from '../../localization';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions } from '../MentionPopover';\nimport { createStyleFromV8Style } from '../styles/v8StyleShim';\nimport { MessageStatus } from '@internal/acs-ui-common';\nimport { mergeClasses } from '@fluentui/react-components';\nimport {\n useChatMessageStyles,\n useChatMyMessageStyles,\n useChatMessageCommonStyles\n} from '../styles/MessageThread.styles';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n messageContainerStyle?: ComponentSlotStyle;\n /** Styles for message status indicator container. */\n messageStatusContainer?: (mine: boolean) => IStyle;\n showDate?: boolean;\n disableEditing?: boolean;\n onEditClick: () => void;\n onRemoveClick?: () => void;\n onResendClick?: () => void;\n strings: MessageThreadStrings;\n userId: string;\n messageStatus?: string;\n /**\n * Whether the status indicator for each message is displayed or not.\n */\n showMessageStatus?: boolean;\n messageStatusRenderer?: (status: MessageStatus) => JSX.Element | null;\n /**\n * Whether to overlap avatar and message when the view is width constrained.\n */\n shouldOverlapAvatarAndMessage: boolean;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /* @conditional-compile-remove(file-sharing) */\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n remoteParticipantsCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (readBy: { id: string; displayName: string }[]) => void\n ) => void;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to display suggestions in the mention scenario.\n * @internal\n */\n mentionDisplayOptions?: MentionDisplayOptions;\n /* @conditional-compile-remove(image-overlay) */\n /**\n * Optional callback called when an inline image is clicked.\n * @beta\n */\n inlineImageOptions?: InlineImageOptions;\n};\n\nconst generateDefaultTimestamp = (\n createdOn: Date,\n showDate: boolean | undefined,\n strings: MessageThreadStrings\n): string => {\n const formattedTimestamp = showDate\n ? formatTimestampForChatMessage(createdOn, new Date(), strings)\n : formatTimeForChatMessage(createdOn);\n\n return formattedTimestamp;\n};\n\n// onDisplayDateTimeString from props overwrite onDisplayDateTimeString from locale\nconst generateCustomizedTimestamp = (\n props: ChatMessageComponentAsMessageBubbleProps,\n createdOn: Date,\n locale: ComponentLocale\n): string => {\n /* @conditional-compile-remove(date-time-customization) */\n return props.onDisplayDateTimeString\n ? props.onDisplayDateTimeString(createdOn)\n : locale.onDisplayDateTimeString\n ? locale.onDisplayDateTimeString(createdOn)\n : '';\n\n return '';\n};\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n onRemoveClick,\n onResendClick,\n disableEditing,\n showDate,\n messageContainerStyle,\n strings,\n onEditClick,\n remoteParticipantsCount = 0,\n onRenderAvatar,\n showMessageStatus,\n messageStatus,\n /* @conditional-compile-remove(file-sharing) */\n fileDownloadHandler,\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions,\n shouldOverlapAvatarAndMessage\n } = props;\n\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn ? generateCustomizedTimestamp(props, message.createdOn, locale) : '';\n\n const formattedTimestamp = customTimestamp || defaultTimeStamp;\n\n // Track if the action menu was opened by touch - if so we increase the touch targets for the items\n const [wasInteractionByTouch, setWasInteractionByTouch] = useState(false);\n // `focused` state is used for show/hide actionMenu\n const [focused, setFocused] = React.useState<boolean>(false);\n\n // The chat message action flyout should target the Chat.Message action menu if clicked,\n // or target the chat message if opened via touch press.\n // Undefined indicates the flyout menu should not be being shown.\n const messageRef = useRef<HTMLDivElement | null>(null);\n const messageActionButtonRef = useRef<HTMLDivElement | null>(null);\n const [chatMessageActionFlyoutTarget, setChatMessageActionFlyoutTarget] = useState<\n React.MutableRefObject<HTMLElement | null> | undefined\n >(undefined);\n\n const chatActionsEnabled =\n !disableEditing &&\n message.status !== 'sending' &&\n !!message.mine &&\n /* @conditional-compile-remove(data-loss-prevention) */ message.messageType !== 'blocked';\n const [messageReadBy, setMessageReadBy] = useState<{ id: string; displayName: string }[]>([]);\n\n const actionMenuProps = chatMessageActionMenuProps({\n ariaLabel: strings.actionMenuMoreOptions ?? '',\n enabled: chatActionsEnabled,\n menuButtonRef: messageActionButtonRef,\n menuExpanded: chatMessageActionFlyoutTarget === messageActionButtonRef,\n onActionButtonClick: () => {\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n setChatMessageActionFlyoutTarget(messageActionButtonRef);\n }\n },\n theme\n });\n\n const onActionFlyoutDismiss = useCallback((): void => {\n // When the flyout dismiss is called, since we control if the action flyout is visible\n // or not we need to set the target to undefined here to actually hide the action flyout\n setChatMessageActionFlyoutTarget(undefined);\n }, [setChatMessageActionFlyoutTarget]);\n\n const defaultOnRenderFileDownloads = useCallback(() => {\n /* @conditional-compile-remove(file-sharing) */\n return (\n <_FileDownloadCards\n userId={userId}\n /* @conditional-compile-remove(file-sharing) */\n fileMetadata={(message as ChatMessage).files || []}\n /* @conditional-compile-remove(file-sharing) */\n downloadHandler={fileDownloadHandler}\n /* @conditional-compile-remove(file-sharing) */\n strings={{ downloadFile: strings.downloadFile, fileCardGroupMessage: strings.fileCardGroupMessage }}\n />\n );\n }, [\n userId,\n message,\n /* @conditional-compile-remove(file-sharing) */\n strings,\n /* @conditional-compile-remove(file-sharing) */\n fileDownloadHandler\n ]);\n\n const editedOn = 'editedOn' in message ? message.editedOn : undefined;\n const getMessageDetails = useCallback(() => {\n if (messageStatus === 'failed') {\n return <div className={chatMessageFailedTagStyle(theme)}>{strings.failToSendTag}</div>;\n } else if (message.messageType === 'chat' && editedOn) {\n return <div className={chatMessageEditedTagStyle(theme)}>{strings.editedTag}</div>;\n }\n return undefined;\n }, [editedOn, message.messageType, messageStatus, strings.editedTag, strings.failToSendTag, theme]);\n\n const getContent = useCallback(() => {\n /* @conditional-compile-remove(data-loss-prevention) */\n if (message.messageType === 'blocked') {\n return (\n <div tabIndex={0}>\n <BlockedMessageContent message={message} strings={strings} />\n </div>\n );\n }\n return (\n <div tabIndex={0} className=\"ui-chat__message__content\">\n <ChatMessageContent\n message={message}\n strings={strings}\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions={props.mentionDisplayOptions}\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions={inlineImageOptions}\n />\n {\n /* @conditional-compile-remove(file-sharing) */ props.onRenderFileDownloads\n ? props.onRenderFileDownloads(userId, message)\n : defaultOnRenderFileDownloads()\n }\n </div>\n );\n }, [\n defaultOnRenderFileDownloads,\n /* @conditional-compile-remove(image-overlay) */ inlineImageOptions,\n message,\n props,\n strings,\n userId\n ]);\n\n const isBlockedMessage =\n false || /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked';\n const chatMyMessageStyles = useChatMyMessageStyles();\n const chatMessageCommonStyles = useChatMessageCommonStyles();\n\n const chatMessageStyles = useChatMessageStyles();\n const chatItemMessageContainerClassName = mergeClasses(\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n chatMessageStyles.body,\n // disable placeholder functionality for GA releases as it might confuse users\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n chatMessageStyles.bodyWithPlaceholderImage,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n shouldOverlapAvatarAndMessage ? chatMessageStyles.avatarOverlap : chatMessageStyles.avatarNoOverlap,\n message.attached === 'top' || message.attached === false\n ? chatMessageStyles.bodyWithAvatar\n : chatMessageStyles.bodyWithoutAvatar,\n mergeStyles(messageContainerStyle)\n );\n\n const attached = message.attached === true ? 'center' : message.attached === 'bottom' ? 'bottom' : 'top';\n const chatMessage = (\n <>\n <div key={props.message.messageId}>\n {message.mine ? (\n <ChatMyMessage\n attached={attached}\n key={props.message.messageId}\n body={{\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n className: mergeClasses(\n chatMyMessageStyles.body,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n attached !== 'top' ? chatMyMessageStyles.bodyAttached : undefined,\n mergeStyles(messageContainerStyle)\n ),\n style: { ...createStyleFromV8Style(messageContainerStyle) },\n ref: messageRef\n }}\n root={{\n className: chatMyMessageStyles.root,\n onBlur: (e) => {\n // `focused` controls is focused the whole `ChatMessage` or any of its children. When we're navigating\n // with keyboard the focused element will be changed and there is no way to use `:focus` selector\n if (chatMessageActionFlyoutTarget?.current) {\n // doesn't dismiss action button if flyout is open, otherwise, narrator's focus will stay on the closed action menu\n return;\n }\n const shouldPreserveFocusState = e.currentTarget.contains(e.relatedTarget);\n setFocused(shouldPreserveFocusState);\n },\n onFocus: () => {\n // react onFocus is called even when nested component receives focus (i.e. it bubbles)\n // so when focus moves within actionMenu, the `focus` state in chatMessage remains true, and keeps actionMenu visible\n setFocused(true);\n },\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n role: 'none',\n tabIndex: -1\n }}\n data-ui-id=\"chat-composite-message\"\n author={\n <Text className={chatMessageDateStyle} tabIndex={0}>\n {message.senderDisplayName}\n </Text>\n }\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp} tabIndex={0}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n actions={{\n children: actionMenuProps?.children,\n className: mergeClasses(\n chatMyMessageStyles.menu,\n // Make actions menu visible when the message is focused or the flyout is shown\n focused || chatMessageActionFlyoutTarget?.current\n ? chatMyMessageStyles.menuVisible\n : chatMyMessageStyles.menuHidden,\n attached !== 'top' ? chatMyMessageStyles.menuAttached : undefined\n )\n }}\n onTouchStart={() => setWasInteractionByTouch(true)}\n onPointerDown={() => setWasInteractionByTouch(false)}\n onKeyDown={() => setWasInteractionByTouch(false)}\n onClick={() => {\n if (!wasInteractionByTouch) {\n return;\n }\n // If the message was touched via touch we immediately open the menu\n // flyout (when using mouse the 3-dot menu that appears on hover\n // must be clicked to open the flyout).\n // In doing so here we set the target of the flyout to be the message and\n // not the 3-dot menu button to position the flyout correctly.\n setChatMessageActionFlyoutTarget(messageRef);\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n }\n }}\n >\n {getContent()}\n </ChatMyMessage>\n ) : (\n <FluentChatMessage\n attached={attached}\n key={props.message.messageId}\n root={{\n className: chatMessageStyles.root,\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n tabIndex: -1,\n role: 'none'\n }}\n author={<Text className={chatMessageAuthorStyle}>{message.senderDisplayName}</Text>}\n body={{\n className: chatItemMessageContainerClassName,\n style: { ...createStyleFromV8Style(messageContainerStyle) }\n }}\n data-ui-id=\"chat-composite-message\"\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n >\n {getContent()}\n </FluentChatMessage>\n )}\n </div>\n {chatActionsEnabled && (\n <ChatMessageActionFlyout\n hidden={!chatMessageActionFlyoutTarget}\n target={chatMessageActionFlyoutTarget}\n increaseFlyoutItemSize={wasInteractionByTouch}\n onDismiss={onActionFlyoutDismiss}\n onEditClick={onEditClick}\n onRemoveClick={onRemoveClick}\n onResendClick={onResendClick}\n strings={strings}\n messageReadBy={messageReadBy}\n messageStatus={messageStatus ?? 'failed'}\n remoteParticipantsCount={remoteParticipantsCount}\n onRenderAvatar={onRenderAvatar}\n showMessageStatus={showMessageStatus}\n />\n )}\n </>\n );\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n"]}
|
@@ -109,13 +109,16 @@ const processHtmlToReact = (props) => {
|
|
109
109
|
if (domNode instanceof DOMElement && domNode.attribs) {
|
110
110
|
// Transform custom rendering of mentions
|
111
111
|
/* @conditional-compile-remove(mention) */
|
112
|
-
if (
|
112
|
+
if (domNode.name === 'msft-mention') {
|
113
113
|
const { id } = domNode.attribs;
|
114
114
|
const mention = {
|
115
115
|
id: id,
|
116
|
-
displayText: (
|
116
|
+
displayText: (_a = domNode.children[0].nodeValue) !== null && _a !== void 0 ? _a : ''
|
117
117
|
};
|
118
|
-
|
118
|
+
if ((_b = props.mentionDisplayOptions) === null || _b === void 0 ? void 0 : _b.onRenderMention) {
|
119
|
+
return props.mentionDisplayOptions.onRenderMention(mention, defaultOnMentionRender);
|
120
|
+
}
|
121
|
+
return defaultOnMentionRender(mention);
|
119
122
|
}
|
120
123
|
// Transform inline images
|
121
124
|
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { _formatString } from '@internal/acs-ui-common';\nimport parse, { HTMLReactParserOptions, Element as DOMElement } from 'html-react-parser';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { attributesToProps } from 'html-react-parser';\nimport Linkify from 'react-linkify';\nimport { ChatMessage } from '../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types/ChatMessage';\nimport { Link } from '@fluentui/react';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions, Mention } from '../MentionPopover';\n\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { FontIcon, Stack } from '@fluentui/react';\nimport { MessageThreadStrings } from '../MessageThread';\nimport LiveMessage from '../Announcer/LiveMessage';\n/* @conditional-compile-remove(mention) */\nimport { defaultOnMentionRender } from './MentionRenderer';\nimport DOMPurify from 'dompurify';\n\ntype ChatMessageContentProps = {\n message: ChatMessage;\n strings: MessageThreadStrings;\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions?: MentionDisplayOptions;\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions?: InlineImageOptions;\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\ntype BlockedMessageContentProps = {\n message: BlockedMessage;\n strings: MessageThreadStrings;\n};\n\ntype MessageContentWithLiveAriaProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n liveMessage: string;\n ariaLabel?: string;\n content: JSX.Element;\n};\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * InlineImage's state, as reflected in the UI.\n *\n * @beta\n */\nexport interface InlineImage {\n /** ID of the message that the inline image is belonged to */\n messageId: string;\n /** Attributes of the inline image */\n imgAttrs: React.ImgHTMLAttributes<HTMLImageElement>;\n}\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Options to display inline image in the inline image scenario.\n *\n * @beta\n */\nexport interface InlineImageOptions {\n /**\n * Optional callback to render an inline image of in a message.\n */\n onRenderInlineImage?: (\n inlineImage: InlineImage,\n defaultOnRender: (inlineImage: InlineImage) => JSX.Element\n ) => JSX.Element;\n}\n\n/** @private */\nexport const ChatMessageContent = (props: ChatMessageContentProps): JSX.Element => {\n switch (props.message.contentType) {\n case 'text':\n return MessageContentAsText(props);\n case 'html':\n return MessageContentAsRichTextHTML(props);\n case 'richtext/html':\n return MessageContentAsRichTextHTML(props);\n default:\n console.warn('unknown message content type');\n return <></>;\n }\n};\n\nconst MessageContentWithLiveAria = (props: MessageContentWithLiveAriaProps): JSX.Element => {\n return (\n <div data-ui-status={props.message.status} role=\"text\" aria-label={props.ariaLabel}>\n <LiveMessage message={props.liveMessage} ariaLive=\"polite\" />\n {props.content}\n </div>\n );\n};\n\nconst MessageContentAsRichTextHTML = (props: ChatMessageContentProps): JSX.Element => {\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={generateLiveMessage(props)}\n ariaLabel={messageContentAriaText(props)}\n content={processHtmlToReact(props)}\n />\n );\n};\n\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={generateLiveMessage(props)}\n ariaLabel={messageContentAriaText(props)}\n content={\n <Linkify\n componentDecorator={(decoratedHref: string, decoratedText: string, key: number) => {\n return (\n <Link target=\"_blank\" href={decoratedHref} key={key}>\n {decoratedText}\n </Link>\n );\n }}\n >\n {props.message.content}\n </Linkify>\n }\n />\n );\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\n/**\n * @private\n */\nexport const BlockedMessageContent = (props: BlockedMessageContentProps): JSX.Element => {\n const Icon: JSX.Element = <FontIcon iconName={'DataLossPreventionProhibited'} />;\n const blockedMessage =\n props.message.warningText === undefined ? props.strings.blockedWarningText : props.message.warningText;\n const blockedMessageLink = props.message.link;\n const blockedMessageLinkText = blockedMessageLink\n ? props.message.linkText ?? props.strings.blockedWarningLinkText\n : '';\n\n const liveAuthor =\n props.message.mine || props.message.senderDisplayName === undefined ? '' : props.message.senderDisplayName;\n const liveBlockedWarningText = `${liveAuthor} ${blockedMessage} ${blockedMessageLinkText}`;\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={liveBlockedWarningText}\n ariaLabel={liveBlockedWarningText}\n content={\n <Stack horizontal wrap>\n {Icon}\n {blockedMessage && <p>{blockedMessage}</p>}\n {blockedMessageLink && (\n <Link target={'_blank'} href={blockedMessageLink}>\n {blockedMessageLinkText}\n </Link>\n )}\n </Stack>\n }\n />\n );\n};\n\n// https://stackoverflow.com/questions/28899298/extract-the-text-out-of-html-string-using-javascript\nconst extractContent = (s: string): string => {\n const span = document.createElement('span');\n span.innerHTML = s;\n return span.textContent || span.innerText;\n};\n\nconst generateLiveMessage = (props: ChatMessageContentProps): string => {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n\n return `${props.message.editedOn ? props.strings.editedTag : ''} ${\n props.message.mine ? '' : liveAuthor\n } ${extractContent(props.message.content || '')} `;\n};\n\nconst messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n if (props.message.content) {\n // Replace all <img> tags with 'image' for aria.\n const parsedContent = DOMPurify.sanitize(props.message.content, {\n ALLOWED_TAGS: ['img'],\n RETURN_DOM_FRAGMENT: true\n });\n\n parsedContent.childNodes.forEach((child) => {\n if (child.nodeName.toLowerCase() !== 'img') {\n return;\n }\n const imageTextNode = document.createElement('div');\n imageTextNode.innerHTML = 'image ';\n parsedContent.replaceChild(imageTextNode, child);\n });\n\n // Strip all html tags from the content for aria.\n const message = DOMPurify.sanitize(parsedContent, { ALLOWED_TAGS: [] });\n\n return props.message.mine\n ? _formatString(props.strings.messageContentMineAriaText, {\n message: message\n })\n : _formatString(props.strings.messageContentAriaText, {\n author: `${props.message.senderDisplayName}`,\n message: message\n });\n }\n return undefined;\n};\n\n/* @conditional-compile-remove(image-overlay) */\nconst defaultOnRenderInlineImage = (inlineImage: InlineImage): JSX.Element => {\n return (\n <img key={inlineImage.imgAttrs.id} tabIndex={0} data-ui-id={inlineImage.imgAttrs.id} {...inlineImage.imgAttrs} />\n );\n};\n\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const options: HTMLReactParserOptions = {\n transform(reactNode, domNode) {\n if (domNode instanceof DOMElement && domNode.attribs) {\n // Transform custom rendering of mentions\n /* @conditional-compile-remove(mention) */\n if (props.mentionDisplayOptions?.onRenderMention && domNode.name === 'msft-mention') {\n const { id } = domNode.attribs;\n const mention: Mention = {\n id: id,\n displayText: (domNode.children[0] as unknown as Text).nodeValue ?? ''\n };\n return props.mentionDisplayOptions.onRenderMention(mention, defaultOnMentionRender);\n }\n\n // Transform inline images\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (\n domNode.name &&\n domNode.name === 'img' &&\n domNode.attribs &&\n domNode.attribs.id &&\n props.message.inlineImages?.find((metadata) => {\n return metadata.id === domNode.attribs.id;\n })\n ) {\n domNode.attribs['aria-label'] = domNode.attribs.name;\n const imgProps = attributesToProps(domNode.attribs);\n /* @conditional-compile-remove(image-overlay) */\n const inlineImageProps: InlineImage = { messageId: props.message.messageId, imgAttrs: imgProps };\n\n /* @conditional-compile-remove(image-overlay) */\n return props.inlineImageOptions?.onRenderInlineImage\n ? props.inlineImageOptions.onRenderInlineImage(inlineImageProps, defaultOnRenderInlineImage)\n : defaultOnRenderInlineImage(inlineImageProps);\n\n return <img key={imgProps.id as string} {...imgProps} />;\n }\n }\n // Pass through the original node\n return reactNode as unknown as JSX.Element;\n }\n };\n return <>{parse(props.message.content ?? '', options)}</>;\n};\n"]}
|
1
|
+
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React from 'react';\nimport { _formatString } from '@internal/acs-ui-common';\nimport parse, { HTMLReactParserOptions, Element as DOMElement } from 'html-react-parser';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { attributesToProps } from 'html-react-parser';\nimport Linkify from 'react-linkify';\nimport { ChatMessage } from '../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types/ChatMessage';\nimport { Link } from '@fluentui/react';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions, Mention } from '../MentionPopover';\n\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { FontIcon, Stack } from '@fluentui/react';\nimport { MessageThreadStrings } from '../MessageThread';\nimport LiveMessage from '../Announcer/LiveMessage';\n/* @conditional-compile-remove(mention) */\nimport { defaultOnMentionRender } from './MentionRenderer';\nimport DOMPurify from 'dompurify';\n\ntype ChatMessageContentProps = {\n message: ChatMessage;\n strings: MessageThreadStrings;\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions?: MentionDisplayOptions;\n /* @conditional-compile-remove(image-overlay) */\n inlineImageOptions?: InlineImageOptions;\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\ntype BlockedMessageContentProps = {\n message: BlockedMessage;\n strings: MessageThreadStrings;\n};\n\ntype MessageContentWithLiveAriaProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n liveMessage: string;\n ariaLabel?: string;\n content: JSX.Element;\n};\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * InlineImage's state, as reflected in the UI.\n *\n * @beta\n */\nexport interface InlineImage {\n /** ID of the message that the inline image is belonged to */\n messageId: string;\n /** Attributes of the inline image */\n imgAttrs: React.ImgHTMLAttributes<HTMLImageElement>;\n}\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Options to display inline image in the inline image scenario.\n *\n * @beta\n */\nexport interface InlineImageOptions {\n /**\n * Optional callback to render an inline image of in a message.\n */\n onRenderInlineImage?: (\n inlineImage: InlineImage,\n defaultOnRender: (inlineImage: InlineImage) => JSX.Element\n ) => JSX.Element;\n}\n\n/** @private */\nexport const ChatMessageContent = (props: ChatMessageContentProps): JSX.Element => {\n switch (props.message.contentType) {\n case 'text':\n return MessageContentAsText(props);\n case 'html':\n return MessageContentAsRichTextHTML(props);\n case 'richtext/html':\n return MessageContentAsRichTextHTML(props);\n default:\n console.warn('unknown message content type');\n return <></>;\n }\n};\n\nconst MessageContentWithLiveAria = (props: MessageContentWithLiveAriaProps): JSX.Element => {\n return (\n <div data-ui-status={props.message.status} role=\"text\" aria-label={props.ariaLabel}>\n <LiveMessage message={props.liveMessage} ariaLive=\"polite\" />\n {props.content}\n </div>\n );\n};\n\nconst MessageContentAsRichTextHTML = (props: ChatMessageContentProps): JSX.Element => {\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={generateLiveMessage(props)}\n ariaLabel={messageContentAriaText(props)}\n content={processHtmlToReact(props)}\n />\n );\n};\n\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={generateLiveMessage(props)}\n ariaLabel={messageContentAriaText(props)}\n content={\n <Linkify\n componentDecorator={(decoratedHref: string, decoratedText: string, key: number) => {\n return (\n <Link target=\"_blank\" href={decoratedHref} key={key}>\n {decoratedText}\n </Link>\n );\n }}\n >\n {props.message.content}\n </Linkify>\n }\n />\n );\n};\n\n/* @conditional-compile-remove(data-loss-prevention) */\n/**\n * @private\n */\nexport const BlockedMessageContent = (props: BlockedMessageContentProps): JSX.Element => {\n const Icon: JSX.Element = <FontIcon iconName={'DataLossPreventionProhibited'} />;\n const blockedMessage =\n props.message.warningText === undefined ? props.strings.blockedWarningText : props.message.warningText;\n const blockedMessageLink = props.message.link;\n const blockedMessageLinkText = blockedMessageLink\n ? props.message.linkText ?? props.strings.blockedWarningLinkText\n : '';\n\n const liveAuthor =\n props.message.mine || props.message.senderDisplayName === undefined ? '' : props.message.senderDisplayName;\n const liveBlockedWarningText = `${liveAuthor} ${blockedMessage} ${blockedMessageLinkText}`;\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={liveBlockedWarningText}\n ariaLabel={liveBlockedWarningText}\n content={\n <Stack horizontal wrap>\n {Icon}\n {blockedMessage && <p>{blockedMessage}</p>}\n {blockedMessageLink && (\n <Link target={'_blank'} href={blockedMessageLink}>\n {blockedMessageLinkText}\n </Link>\n )}\n </Stack>\n }\n />\n );\n};\n\n// https://stackoverflow.com/questions/28899298/extract-the-text-out-of-html-string-using-javascript\nconst extractContent = (s: string): string => {\n const span = document.createElement('span');\n span.innerHTML = s;\n return span.textContent || span.innerText;\n};\n\nconst generateLiveMessage = (props: ChatMessageContentProps): string => {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n\n return `${props.message.editedOn ? props.strings.editedTag : ''} ${\n props.message.mine ? '' : liveAuthor\n } ${extractContent(props.message.content || '')} `;\n};\n\nconst messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n if (props.message.content) {\n // Replace all <img> tags with 'image' for aria.\n const parsedContent = DOMPurify.sanitize(props.message.content, {\n ALLOWED_TAGS: ['img'],\n RETURN_DOM_FRAGMENT: true\n });\n\n parsedContent.childNodes.forEach((child) => {\n if (child.nodeName.toLowerCase() !== 'img') {\n return;\n }\n const imageTextNode = document.createElement('div');\n imageTextNode.innerHTML = 'image ';\n parsedContent.replaceChild(imageTextNode, child);\n });\n\n // Strip all html tags from the content for aria.\n const message = DOMPurify.sanitize(parsedContent, { ALLOWED_TAGS: [] });\n\n return props.message.mine\n ? _formatString(props.strings.messageContentMineAriaText, {\n message: message\n })\n : _formatString(props.strings.messageContentAriaText, {\n author: `${props.message.senderDisplayName}`,\n message: message\n });\n }\n return undefined;\n};\n\n/* @conditional-compile-remove(image-overlay) */\nconst defaultOnRenderInlineImage = (inlineImage: InlineImage): JSX.Element => {\n return (\n <img key={inlineImage.imgAttrs.id} tabIndex={0} data-ui-id={inlineImage.imgAttrs.id} {...inlineImage.imgAttrs} />\n );\n};\n\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const options: HTMLReactParserOptions = {\n transform(reactNode, domNode) {\n if (domNode instanceof DOMElement && domNode.attribs) {\n // Transform custom rendering of mentions\n /* @conditional-compile-remove(mention) */\n if (domNode.name === 'msft-mention') {\n const { id } = domNode.attribs;\n const mention: Mention = {\n id: id,\n displayText: (domNode.children[0] as unknown as Text).nodeValue ?? ''\n };\n if (props.mentionDisplayOptions?.onRenderMention) {\n return props.mentionDisplayOptions.onRenderMention(mention, defaultOnMentionRender);\n }\n return defaultOnMentionRender(mention);\n }\n\n // Transform inline images\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n if (\n domNode.name &&\n domNode.name === 'img' &&\n domNode.attribs &&\n domNode.attribs.id &&\n props.message.inlineImages?.find((metadata) => {\n return metadata.id === domNode.attribs.id;\n })\n ) {\n domNode.attribs['aria-label'] = domNode.attribs.name;\n const imgProps = attributesToProps(domNode.attribs);\n /* @conditional-compile-remove(image-overlay) */\n const inlineImageProps: InlineImage = { messageId: props.message.messageId, imgAttrs: imgProps };\n\n /* @conditional-compile-remove(image-overlay) */\n return props.inlineImageOptions?.onRenderInlineImage\n ? props.inlineImageOptions.onRenderInlineImage(inlineImageProps, defaultOnRenderInlineImage)\n : defaultOnRenderInlineImage(inlineImageProps);\n\n return <img key={imgProps.id as string} {...imgProps} />;\n }\n }\n // Pass through the original node\n return reactNode as unknown as JSX.Element;\n }\n };\n return <>{parse(props.message.content ?? '', options)}</>;\n};\n"]}
|
@@ -10,6 +10,6 @@ import React from 'react';
|
|
10
10
|
export const defaultOnMentionRender = (mention) => {
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
12
12
|
const MsftMention = 'msft-mention';
|
13
|
-
return React.createElement(MsftMention, { id: mention.id }, mention.displayText);
|
13
|
+
return (React.createElement(MsftMention, { id: mention.id, key: Math.random().toString() }, mention.displayText));
|
14
14
|
};
|
15
15
|
//# sourceMappingURL=MentionRenderer.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MentionRenderer.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/MentionRenderer.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAgB,EAAe,EAAE;IACtE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,cAAqB,CAAC;IAC1C,OAAO,oBAAC,WAAW,IAAC,EAAE,EAAE,OAAO,CAAC,EAAE,
|
1
|
+
{"version":3,"file":"MentionRenderer.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/MentionRenderer.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAgB,EAAe,EAAE;IACtE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,cAAqB,CAAC;IAC1C,OAAO,CACL,oBAAC,WAAW,IAAC,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,IACvD,OAAO,CAAC,WAAW,CACR,CACf,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport React from 'react';\nimport { Mention } from '../MentionPopover';\n\n/**\n * Provides the default implementation for rendering an Mention in a message thread\n * @param mention - The mention to render\n *\n * @private\n */\nexport const defaultOnMentionRender = (mention: Mention): JSX.Element => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const MsftMention = 'msft-mention' as any;\n return (\n <MsftMention id={mention.id} key={Math.random().toString()}>\n {mention.displayText}\n </MsftMention>\n );\n};\n"]}
|
@@ -107,7 +107,7 @@ const DownloadIconTrampoline = () => {
|
|
107
107
|
return React.createElement(Icon, { iconName: "EditBoxCancel", style: actionIconStyle });
|
108
108
|
};
|
109
109
|
const useLocaleStringsTrampoline = () => {
|
110
|
-
/* @conditional-compile-remove(file-sharing)
|
110
|
+
/* @conditional-compile-remove(file-sharing) */
|
111
111
|
return useLocale().strings.messageThread;
|
112
112
|
return { downloadFile: '', fileCardGroupMessage: '' };
|
113
113
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FileDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/FileDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, IconButton, Spinner, SpinnerSize, TooltipHost } from '@fluentui/react';\nimport React, { useCallback, useState } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(file-sharing) */\nimport { useLocale } from '../localization';\nimport { _FileCard } from './FileCard';\nimport { _FileCardGroup } from './FileCardGroup';\nimport { iconButtonClassName } from './styles/IconButton.styles';\nimport { _formatString } from '@internal/acs-ui-common';\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * Represents the type of attachment\n * @beta\n */\nexport type ChatAttachmentType =\n | 'unknown'\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'inlineImage'\n | /* @conditional-compile-remove(file-sharing) */ 'file';\n\n/**\n * Metadata containing basic information about the uploaded file.\n *\n * @beta\n */\nexport interface FileMetadata {\n /* @conditional-compile-remove(file-sharing) */\n attachmentType: 'file';\n /**\n * Extension hint, useful for rendering a specific icon.\n * An unknown or empty extension will be rendered as a generic icon.\n * Example: `pdf`\n */\n extension: string;\n /**\n * Unique ID of the file.\n */\n /* @conditional-compile-remove(file-sharing) */\n id: string;\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Download URL for the file.\n */\n url: string;\n /* @conditional-compile-remove(file-sharing) */\n /*\n * Optional dictionary of meta data associated with the file.\n */\n payload?: Record<string, string>;\n}\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * Metadata for rendering images inline with a message.\n * This does not include images attached as files.\n * @beta\n */\nexport interface InlineImageMetadata {\n /*\n * Type of the attachment\n */\n attachmentType: 'inlineImage';\n /**\n * Unique ID of the attachment.\n */\n id: string;\n /*\n * Preview URL for low resolution version.\n */\n previewUrl?: string;\n /**\n * Download URL for the full resolution version.\n */\n url: string;\n /**\n * Optional fetched Image source fot the full resolution version.\n */\n fullSizeImageSrc?: string;\n}\n\n/**\n * Metadata containing information about the uploaded file.\n * @beta\n */\nexport type AttachmentMetadata =\n | FileMetadata\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ InlineImageMetadata;\n\n/**\n * Strings of _FileDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _FileDownloadCardsStrings {\n /** Aria label to notify user when focus is on file download button. */\n downloadFile: string;\n fileCardGroupMessage: string;\n}\n\n/**\n * @beta\n * A file download error returned via a {@link FileDownloadHandler}.\n * This error message is used to render an error message in the UI.\n */\nexport interface FileDownloadError {\n /** The error message to display in the UI */\n errorMessage: string;\n}\n\n/**\n * @beta\n *\n * A callback function for handling file downloads.\n * The function needs to return a promise that resolves to a file download URL.\n * If the promise is rejected, the {@link Error.message} will be used to display an error message to the user.\n *\n * @example\n * ```ts\n * const fileDownloadHandler: FileDownloadHandler = async (userId, fileData) => {\n * if (isUnauthorizedUser(userId)) {\n * return { errorMessage: 'You don’t have permission to download this file.' };\n * } else {\n * return new URL(fileData.url);\n * }\n * }\n *\n * const App = () => (\n * <ChatComposite\n * ...\n * fileSharing={{\n * fileDownloadHandler: fileDownloadHandler\n * }}\n * />\n * )\n *\n * ```\n * @param userId - The user ID of the user downloading the file.\n * @param fileMetadata - The {@link AttachmentMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (\n userId: string,\n fileMetadata: AttachmentMetadata\n) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCardsProps {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that includes file metadata\n */\n fileMetadata?: AttachmentMetadata[];\n /**\n * A function of type {@link FileDownloadHandler} for handling file downloads.\n * If the function is not specified, the file's `url` will be opened in a new tab to\n * initiate the download.\n */\n downloadHandler?: FileDownloadHandler;\n /**\n * Optional callback that runs if downloadHandler returns {@link FileDownloadError}.\n */\n onDownloadErrorMessage?: (errMsg: string) => void;\n /**\n * Optional aria label strings for file download cards\n */\n strings?: _FileDownloadCardsStrings;\n}\n\nconst fileDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _FileDownloadCards = (props: _FileDownloadCardsProps): JSX.Element => {\n const { userId, fileMetadata } = props;\n const [showSpinner, setShowSpinner] = useState(false);\n const localeStrings = useLocaleStringsTrampoline();\n\n const downloadFileButtonString = useMemo(\n () => () => {\n return props.strings?.downloadFile ?? localeStrings.downloadFile;\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const isFileSharingAttachment = useCallback((attachment: AttachmentMetadata): boolean => {\n /* @conditional-compile-remove(file-sharing) */\n return attachment.attachmentType === 'file';\n return false;\n }, []);\n\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n const isShowDownloadIcon = useCallback((attachment: AttachmentMetadata): boolean => {\n /* @conditional-compile-remove(file-sharing) */\n return attachment.attachmentType === 'file' && attachment.payload?.teamsFileAttachment !== 'true';\n return true;\n }, []);\n\n const fileCardGroupDescription = useMemo(\n () => () => {\n const fileGroupLocaleString = props.strings?.fileCardGroupMessage ?? localeStrings.fileCardGroupMessage;\n /* @conditional-compile-remove(file-sharing) */\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.filter(isFileSharingAttachment).length ?? 0}`\n });\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.length ?? 0}`\n });\n },\n [props.strings?.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata, isFileSharingAttachment]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId: string, file: AttachmentMetadata) => {\n if (!props.downloadHandler) {\n window.open(file.url, '_blank', 'noopener,noreferrer');\n } else {\n setShowSpinner(true);\n try {\n const response = await props.downloadHandler(userId, file);\n setShowSpinner(false);\n if (response instanceof URL) {\n window.open(response.toString(), '_blank', 'noopener,noreferrer');\n } else {\n props.onDownloadErrorMessage && props.onDownloadErrorMessage(response.errorMessage);\n }\n } finally {\n setShowSpinner(false);\n }\n }\n },\n [props]\n );\n if (\n !fileMetadata ||\n fileMetadata.length === 0 ||\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !fileMetadata.some(isFileSharingAttachment)\n ) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup ariaLabel={fileCardGroupDescription()}>\n {fileMetadata &&\n fileMetadata\n .filter((attachment) => {\n /* @conditional-compile-remove(file-sharing) */\n return isFileSharingAttachment(attachment);\n return true;\n })\n .map((file) => file as unknown as FileMetadata)\n .map((file) => (\n <TooltipHost content={downloadFileButtonString()} key={file.name}>\n <_FileCard\n fileName={file.name}\n key={file.name}\n fileExtension={file.extension}\n actionIcon={\n showSpinner ? (\n <Spinner size={SpinnerSize.medium} aria-live={'polite'} role={'status'} />\n ) : true &&\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ isShowDownloadIcon(\n file as unknown as AttachmentMetadata\n ) ? (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n ) : undefined\n }\n actionHandler={() => fileDownloadHandler(userId, file as unknown as AttachmentMetadata)}\n />\n </TooltipHost>\n ))}\n </_FileCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst DownloadIconTrampoline = (): JSX.Element => {\n // @conditional-compile-remove(file-sharing)\n return <Icon data-ui-id=\"file-download-card-download-icon\" iconName=\"DownloadFile\" style={actionIconStyle} />;\n // Return _some_ available icon, as the real icon is beta-only.\n return <Icon iconName=\"EditBoxCancel\" style={actionIconStyle} />;\n};\n\nconst useLocaleStringsTrampoline = (): _FileDownloadCardsStrings => {\n /* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing)*/\n return useLocale().strings.messageThread;\n return { downloadFile: '', fileCardGroupMessage: '' };\n};\n"]}
|
1
|
+
{"version":3,"file":"FileDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/FileDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, IconButton, Spinner, SpinnerSize, TooltipHost } from '@fluentui/react';\nimport React, { useCallback, useState } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(file-sharing) */\nimport { useLocale } from '../localization';\nimport { _FileCard } from './FileCard';\nimport { _FileCardGroup } from './FileCardGroup';\nimport { iconButtonClassName } from './styles/IconButton.styles';\nimport { _formatString } from '@internal/acs-ui-common';\n\n/* @conditional-compile-remove(file-sharing) @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * Represents the type of attachment\n * @beta\n */\nexport type ChatAttachmentType =\n | 'unknown'\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'inlineImage'\n | /* @conditional-compile-remove(file-sharing) */ 'file';\n\n/**\n * Metadata containing basic information about the uploaded file.\n *\n * @beta\n */\nexport interface FileMetadata {\n /* @conditional-compile-remove(file-sharing) */\n attachmentType: 'file';\n /**\n * Extension hint, useful for rendering a specific icon.\n * An unknown or empty extension will be rendered as a generic icon.\n * Example: `pdf`\n */\n extension: string;\n /**\n * Unique ID of the file.\n */\n /* @conditional-compile-remove(file-sharing) */\n id: string;\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Download URL for the file.\n */\n url: string;\n /* @conditional-compile-remove(file-sharing) */\n /*\n * Optional dictionary of meta data associated with the file.\n */\n payload?: Record<string, string>;\n}\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * Metadata for rendering images inline with a message.\n * This does not include images attached as files.\n * @beta\n */\nexport interface InlineImageMetadata {\n /*\n * Type of the attachment\n */\n attachmentType: 'inlineImage';\n /**\n * Unique ID of the attachment.\n */\n id: string;\n /*\n * Preview URL for low resolution version.\n */\n previewUrl?: string;\n /**\n * Download URL for the full resolution version.\n */\n url: string;\n /**\n * Optional fetched Image source fot the full resolution version.\n */\n fullSizeImageSrc?: string;\n}\n\n/**\n * Metadata containing information about the uploaded file.\n * @beta\n */\nexport type AttachmentMetadata =\n | FileMetadata\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ InlineImageMetadata;\n\n/**\n * Strings of _FileDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _FileDownloadCardsStrings {\n /** Aria label to notify user when focus is on file download button. */\n downloadFile: string;\n fileCardGroupMessage: string;\n}\n\n/**\n * @beta\n * A file download error returned via a {@link FileDownloadHandler}.\n * This error message is used to render an error message in the UI.\n */\nexport interface FileDownloadError {\n /** The error message to display in the UI */\n errorMessage: string;\n}\n\n/**\n * @beta\n *\n * A callback function for handling file downloads.\n * The function needs to return a promise that resolves to a file download URL.\n * If the promise is rejected, the {@link Error.message} will be used to display an error message to the user.\n *\n * @example\n * ```ts\n * const fileDownloadHandler: FileDownloadHandler = async (userId, fileData) => {\n * if (isUnauthorizedUser(userId)) {\n * return { errorMessage: 'You don’t have permission to download this file.' };\n * } else {\n * return new URL(fileData.url);\n * }\n * }\n *\n * const App = () => (\n * <ChatComposite\n * ...\n * fileSharing={{\n * fileDownloadHandler: fileDownloadHandler\n * }}\n * />\n * )\n *\n * ```\n * @param userId - The user ID of the user downloading the file.\n * @param fileMetadata - The {@link AttachmentMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (\n userId: string,\n fileMetadata: AttachmentMetadata\n) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCardsProps {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that includes file metadata\n */\n fileMetadata?: AttachmentMetadata[];\n /**\n * A function of type {@link FileDownloadHandler} for handling file downloads.\n * If the function is not specified, the file's `url` will be opened in a new tab to\n * initiate the download.\n */\n downloadHandler?: FileDownloadHandler;\n /**\n * Optional callback that runs if downloadHandler returns {@link FileDownloadError}.\n */\n onDownloadErrorMessage?: (errMsg: string) => void;\n /**\n * Optional aria label strings for file download cards\n */\n strings?: _FileDownloadCardsStrings;\n}\n\nconst fileDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _FileDownloadCards = (props: _FileDownloadCardsProps): JSX.Element => {\n const { userId, fileMetadata } = props;\n const [showSpinner, setShowSpinner] = useState(false);\n const localeStrings = useLocaleStringsTrampoline();\n\n const downloadFileButtonString = useMemo(\n () => () => {\n return props.strings?.downloadFile ?? localeStrings.downloadFile;\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const isFileSharingAttachment = useCallback((attachment: AttachmentMetadata): boolean => {\n /* @conditional-compile-remove(file-sharing) */\n return attachment.attachmentType === 'file';\n return false;\n }, []);\n\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n const isShowDownloadIcon = useCallback((attachment: AttachmentMetadata): boolean => {\n /* @conditional-compile-remove(file-sharing) */\n return attachment.attachmentType === 'file' && attachment.payload?.teamsFileAttachment !== 'true';\n return true;\n }, []);\n\n const fileCardGroupDescription = useMemo(\n () => () => {\n const fileGroupLocaleString = props.strings?.fileCardGroupMessage ?? localeStrings.fileCardGroupMessage;\n /* @conditional-compile-remove(file-sharing) */\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.filter(isFileSharingAttachment).length ?? 0}`\n });\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.length ?? 0}`\n });\n },\n [props.strings?.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata, isFileSharingAttachment]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId: string, file: AttachmentMetadata) => {\n if (!props.downloadHandler) {\n window.open(file.url, '_blank', 'noopener,noreferrer');\n } else {\n setShowSpinner(true);\n try {\n const response = await props.downloadHandler(userId, file);\n setShowSpinner(false);\n if (response instanceof URL) {\n window.open(response.toString(), '_blank', 'noopener,noreferrer');\n } else {\n props.onDownloadErrorMessage && props.onDownloadErrorMessage(response.errorMessage);\n }\n } finally {\n setShowSpinner(false);\n }\n }\n },\n [props]\n );\n if (\n !fileMetadata ||\n fileMetadata.length === 0 ||\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !fileMetadata.some(isFileSharingAttachment)\n ) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup ariaLabel={fileCardGroupDescription()}>\n {fileMetadata &&\n fileMetadata\n .filter((attachment) => {\n /* @conditional-compile-remove(file-sharing) */\n return isFileSharingAttachment(attachment);\n return true;\n })\n .map((file) => file as unknown as FileMetadata)\n .map((file) => (\n <TooltipHost content={downloadFileButtonString()} key={file.name}>\n <_FileCard\n fileName={file.name}\n key={file.name}\n fileExtension={file.extension}\n actionIcon={\n showSpinner ? (\n <Spinner size={SpinnerSize.medium} aria-live={'polite'} role={'status'} />\n ) : true &&\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ isShowDownloadIcon(\n file as unknown as AttachmentMetadata\n ) ? (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n ) : undefined\n }\n actionHandler={() => fileDownloadHandler(userId, file as unknown as AttachmentMetadata)}\n />\n </TooltipHost>\n ))}\n </_FileCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst DownloadIconTrampoline = (): JSX.Element => {\n // @conditional-compile-remove(file-sharing)\n return <Icon data-ui-id=\"file-download-card-download-icon\" iconName=\"DownloadFile\" style={actionIconStyle} />;\n // Return _some_ available icon, as the real icon is beta-only.\n return <Icon iconName=\"EditBoxCancel\" style={actionIconStyle} />;\n};\n\nconst useLocaleStringsTrampoline = (): _FileDownloadCardsStrings => {\n /* @conditional-compile-remove(file-sharing) */\n return useLocale().strings.messageThread;\n return { downloadFile: '', fileCardGroupMessage: '' };\n};\n"]}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ImageOverlay.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/ImageOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(image-overlay) */\nimport { DefaultButton, Icon, IconButton, Modal, Stack, mergeStyles } from '@fluentui/react';\n/* @conditional-compile-remove(image-overlay) */\nimport React, { useState } from 'react';\n/* @conditional-compile-remove(image-overlay) */\nimport {\n bodyContainer,\n brokenImageStyle,\n cancelIcon,\n closeButtonStyles,\n controlBarContainerStyle,\n downloadButtonStyle,\n downloadIcon,\n downloadIconStyle,\n focusTrapZoneStyle,\n headerStyle,\n normalImageStyle,\n overlayStyles,\n scrollableContentStyle,\n smallDownloadButtonContainerStyle,\n themeProviderRootStyle,\n titleBarContainerStyle,\n titleStyle\n} from './styles/ImageOverlay.style';\n/* @conditional-compile-remove(image-overlay) */\nimport { FluentThemeProvider } from '../theming/FluentThemeProvider';\n/* @conditional-compile-remove(image-overlay) */\nimport { useLocale } from '../localization';\n/* @conditional-compile-remove(image-overlay) */\nimport { imageOverlayTheme } from '../theming';\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Props for {@link ImageOverlay}.\n *\n * @beta\n */\nexport interface ImageOverlayProps {\n /**\n * Boolean that controls whether the modal is displayed.\n */\n isOpen: boolean;\n /**\n * Image source used to display the image in a large scale.\n */\n imageSrc: string;\n /**\n * Optional string used as a alt text for the image. @default 'image'\n */\n altText?: string;\n /**\n * Optional string used as the title of the image and displayed on the top left corner of the ImageOverlay.\n */\n title?: string;\n /**\n * Optional JSX element used as a title icon and displayed to the left of the title element.\n */\n titleIcon?: JSX.Element;\n /**\n * Callback to invoke when the ImageOverlay modal is dismissed\n */\n onDismiss: () => void;\n /**\n * Optional callback called when the download button is clicked. If not provided, the download button will not be rendered.\n */\n onDownloadButtonClicked?: (imageSrc: string) => void;\n}\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Strings of {@link ImageOverlay} that can be overridden.\n *\n * @
|
1
|
+
{"version":3,"file":"ImageOverlay.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/ImageOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(image-overlay) */\nimport { DefaultButton, Icon, IconButton, Modal, Stack, mergeStyles } from '@fluentui/react';\n/* @conditional-compile-remove(image-overlay) */\nimport React, { useState } from 'react';\n/* @conditional-compile-remove(image-overlay) */\nimport {\n bodyContainer,\n brokenImageStyle,\n cancelIcon,\n closeButtonStyles,\n controlBarContainerStyle,\n downloadButtonStyle,\n downloadIcon,\n downloadIconStyle,\n focusTrapZoneStyle,\n headerStyle,\n normalImageStyle,\n overlayStyles,\n scrollableContentStyle,\n smallDownloadButtonContainerStyle,\n themeProviderRootStyle,\n titleBarContainerStyle,\n titleStyle\n} from './styles/ImageOverlay.style';\n/* @conditional-compile-remove(image-overlay) */\nimport { FluentThemeProvider } from '../theming/FluentThemeProvider';\n/* @conditional-compile-remove(image-overlay) */\nimport { useLocale } from '../localization';\n/* @conditional-compile-remove(image-overlay) */\nimport { imageOverlayTheme } from '../theming';\n\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Props for {@link ImageOverlay}.\n *\n * @beta\n */\nexport interface ImageOverlayProps {\n /**\n * Boolean that controls whether the modal is displayed.\n */\n isOpen: boolean;\n /**\n * Image source used to display the image in a large scale.\n */\n imageSrc: string;\n /**\n * Optional string used as a alt text for the image. @default 'image'\n */\n altText?: string;\n /**\n * Optional string used as the title of the image and displayed on the top left corner of the ImageOverlay.\n */\n title?: string;\n /**\n * Optional JSX element used as a title icon and displayed to the left of the title element.\n */\n titleIcon?: JSX.Element;\n /**\n * Callback to invoke when the ImageOverlay modal is dismissed\n */\n onDismiss: () => void;\n /**\n * Optional callback called when the download button is clicked. If not provided, the download button will not be rendered.\n */\n onDownloadButtonClicked?: (imageSrc: string) => void;\n}\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Strings of {@link ImageOverlay} that can be overridden.\n *\n * @public\n */\nexport interface ImageOverlayStrings {\n /**\n * Download button label for ImageOverlay\n */\n downloadButtonLabel: string;\n /**\n * Dismiss button aria label for ImageOverlay\n */\n dismissButtonAriaLabel: string;\n}\n/* @conditional-compile-remove(image-overlay) */\n/**\n * Component to render a fullscreen modal for a selected image.\n *\n * @beta\n */\nexport const ImageOverlay = (props: ImageOverlayProps): JSX.Element => {\n const { isOpen, imageSrc, title, titleIcon, altText, onDownloadButtonClicked, onDismiss } = props;\n\n /* @conditional-compile-remove(image-overlay) */\n const localeStrings = useLocale().strings.imageOverlay;\n\n const [isImageLoaded, setIsImageLoaded] = useState<boolean>(true);\n\n const imageStyle = isImageLoaded ? normalImageStyle : brokenImageStyle(imageOverlayTheme);\n\n const renderHeaderBar = (): JSX.Element => {\n return (\n <Stack className={mergeStyles(headerStyle)}>\n <Stack className={mergeStyles(titleBarContainerStyle)}>\n {titleIcon}\n <Stack.Item className={mergeStyles(titleStyle(imageOverlayTheme))} aria-label={title || 'Image'}>\n {title}\n </Stack.Item>\n </Stack>\n <Stack className={mergeStyles(controlBarContainerStyle)}>\n {onDownloadButtonClicked && (\n <DefaultButton\n className={mergeStyles(downloadButtonStyle)}\n /* @conditional-compile-remove(image-overlay) */\n text={localeStrings.downloadButtonLabel}\n onClick={() => onDownloadButtonClicked && onDownloadButtonClicked(imageSrc)}\n onRenderIcon={() => <Icon iconName={downloadIcon.iconName} className={mergeStyles(downloadIconStyle)} />}\n aria-live={'polite'}\n /* @conditional-compile-remove(image-overlay) */\n aria-label={localeStrings.downloadButtonLabel}\n />\n )}\n {onDownloadButtonClicked && (\n <IconButton\n iconProps={downloadIcon}\n className={mergeStyles(smallDownloadButtonContainerStyle(imageOverlayTheme))}\n onClick={() => onDownloadButtonClicked && onDownloadButtonClicked(imageSrc)}\n /* @conditional-compile-remove(image-overlay) */\n aria-label={localeStrings.downloadButtonLabel}\n aria-live={'polite'}\n />\n )}\n <IconButton\n iconProps={cancelIcon}\n className={mergeStyles(closeButtonStyles(imageOverlayTheme))}\n onClick={onDismiss}\n /* @conditional-compile-remove(image-overlay) */\n ariaLabel={localeStrings.dismissButtonAriaLabel}\n aria-live={'polite'}\n />\n </Stack>\n </Stack>\n );\n };\n\n const renderBodyWithLightDismiss = (): JSX.Element => {\n return (\n <Stack className={mergeStyles(bodyContainer)} onClick={() => props.onDismiss()}>\n {imageSrc && (\n <img\n src={imageSrc}\n className={mergeStyles(imageStyle)}\n alt={altText || 'image'}\n aria-label={'image-overlay-main-image'}\n aria-live={'polite'}\n onError={() => {\n setIsImageLoaded(false);\n }}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.persist();\n }}\n />\n )}\n </Stack>\n );\n };\n\n return (\n <Modal\n titleAriaId={title}\n isOpen={isOpen}\n onDismiss={onDismiss}\n overlay={{ styles: { ...overlayStyles(imageOverlayTheme) } }}\n styles={{ main: focusTrapZoneStyle, scrollableContent: scrollableContentStyle }}\n isDarkOverlay={true}\n >\n <FluentThemeProvider fluentTheme={imageOverlayTheme} rootStyle={themeProviderRootStyle}>\n {renderHeaderBar()}\n {renderBodyWithLightDismiss()}\n </FluentThemeProvider>\n </Modal>\n );\n};\n"]}
|