@azure/communication-react 1.5.1-alpha-202306010016 → 1.5.1-alpha-202306030013
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 +22 -2
- package/dist/dist-cjs/communication-react/index.js +162 -63
- package/dist/dist-cjs/communication-react/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 +37 -13
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/EventSubscriber.js +1 -1
- package/dist/dist-esm/chat-stateful-client/src/EventSubscriber.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/ChatMessageComponent.js +2 -2
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js +2 -2
- 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 +4 -4
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js +10 -5
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +5 -8
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageThread.js +16 -8
- package/dist/dist-esm/react-components/src/components/MessageThread.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.d.ts +5 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +71 -2
- 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/CallAdapter.d.ts +19 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/index.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/index.d.ts +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +4 -4
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.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/CallWithChatComposite/adapter/CallWithChatBackedChatAdapter.js +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +2 -2
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +11 -11
- 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/index.js.map +1 -1
- package/package.json +8 -8
@@ -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';\n/* @conditional-compile-remove(teams-inline-images) */\nimport { useEffect } from 'react';\nimport { _formatString } from '@internal/acs-ui-common';\nimport { Parser, ProcessNodeDefinitions, IsValidNodeDefinitions, ProcessingInstructionType } from 'html-to-react';\n\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';\n/* @conditional-compile-remove(teams-inline-images) */\nimport { FileMetadata } from '../FileDownloadCards';\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(teams-inline-images) */\n attachmentsMap?: Record<string, string>;\n /* @conditional-compile-remove(teams-inline-images) */\n onFetchAttachment?: (attachment: FileMetadata) => Promise<void>;\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/** @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 const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n\n /* @conditional-compile-remove(teams-inline-images) */\n useEffect(() => {\n props.message.attachedFilesMetadata?.map((fileMetadata) => {\n if (props.onFetchAttachment && props.attachmentsMap && props.attachmentsMap[fileMetadata.id] === undefined) {\n props.onFetchAttachment(fileMetadata);\n }\n });\n }, [props]);\n\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={`${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`}\n ariaLabel={messageContentAriaText(props)}\n content={processHtmlToReact(props)}\n />\n );\n};\n\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={`${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`}\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 messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n // Strip all html tags from the content for aria.\n\n return props.message.content\n ? props.message.mine\n ? _formatString(props.strings.messageContentMineAriaText, {\n message: DOMPurify.sanitize(props.message.content, { ALLOWED_TAGS: [] })\n })\n : _formatString(props.strings.messageContentAriaText, {\n author: `${props.message.senderDisplayName}`,\n message: DOMPurify.sanitize(props.message.content, { ALLOWED_TAGS: [] })\n })\n : undefined;\n};\n\nconst processNodeDefinitions = ProcessNodeDefinitions();\nconst htmlToReactParser = Parser();\n\n/* @conditional-compile-remove(teams-inline-images) */\nconst processInlineImage = (props: ChatMessageContentProps): ProcessingInstructionType => ({\n // Custom <img> processing\n shouldProcessNode: (node): boolean => {\n // Process img node with id in attachments list\n return (\n node.name &&\n node.name === 'img' &&\n node.attribs &&\n node.attribs.id &&\n props.message.attachedFilesMetadata?.find((f) => f.id === node.attribs.id)\n );\n },\n processNode: (node, children, index): HTMLElement => {\n // logic to check id in map/list\n if (props.attachmentsMap && node.attribs.id in props.attachmentsMap) {\n node.attribs = { ...node.attribs, src: props.attachmentsMap[node.attribs.id] };\n }\n return processNodeDefinitions.processDefaultNode(node, children, index);\n }\n});\n\n/* @conditional-compile-remove(mention) */\nconst processMention = (props: ChatMessageContentProps): ProcessingInstructionType => ({\n shouldProcessNode: (node) => {\n if (props.mentionDisplayOptions?.onRenderMention) {\n // Override the handling of the <msft-mention> tag in the HTML if there's a custom renderer\n return node.name === 'msft-mention';\n }\n return false;\n },\n processNode: (node) => {\n if (props.mentionDisplayOptions?.onRenderMention) {\n const { id, displaytext } = node.attribs;\n const mention: Mention = {\n id: id,\n displayText: displaytext\n };\n return props.mentionDisplayOptions.onRenderMention(mention, defaultOnMentionRender);\n }\n return processNodeDefinitions.processDefaultNode;\n }\n});\n\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const steps: ProcessingInstructionType[] = [\n /* @conditional-compile-remove(teams-inline-images) */\n processInlineImage(props),\n /* @conditional-compile-remove(mention) */\n processMention(props),\n {\n // Process everything else in the default way\n shouldProcessNode: IsValidNodeDefinitions.alwaysValid,\n processNode: processNodeDefinitions.processDefaultNode\n }\n ];\n\n return htmlToReactParser.parseWithInstructions(\n props.message.content ?? '',\n IsValidNodeDefinitions.alwaysValid,\n steps\n );\n};\n\"../../../../acs-ui-common/src\""]}
|
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';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { useEffect } from 'react';\nimport { _formatString } from '@internal/acs-ui-common';\nimport { Parser, ProcessNodeDefinitions, IsValidNodeDefinitions, ProcessingInstructionType } from 'html-to-react';\n\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';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { FileMetadata } from '../FileDownloadCards';\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(teams-inline-images-and-file-sharing) */\n attachmentsMap?: Record<string, string>;\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n onFetchAttachment?: (attachment: FileMetadata) => Promise<void>;\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/** @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 const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n useEffect(() => {\n props.message.attachedFilesMetadata?.map((fileMetadata) => {\n if (props.onFetchAttachment && props.attachmentsMap && props.attachmentsMap[fileMetadata.id] === undefined) {\n props.onFetchAttachment(fileMetadata);\n }\n });\n }, [props]);\n\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={`${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`}\n ariaLabel={messageContentAriaText(props)}\n content={processHtmlToReact(props)}\n />\n );\n};\n\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n return (\n <MessageContentWithLiveAria\n message={props.message}\n liveMessage={`${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`}\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 messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n // Strip all html tags from the content for aria.\n\n return props.message.content\n ? props.message.mine\n ? _formatString(props.strings.messageContentMineAriaText, {\n message: DOMPurify.sanitize(props.message.content, { ALLOWED_TAGS: [] })\n })\n : _formatString(props.strings.messageContentAriaText, {\n author: `${props.message.senderDisplayName}`,\n message: DOMPurify.sanitize(props.message.content, { ALLOWED_TAGS: [] })\n })\n : undefined;\n};\n\nconst processNodeDefinitions = ProcessNodeDefinitions();\nconst htmlToReactParser = Parser();\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nconst processInlineImage = (props: ChatMessageContentProps): ProcessingInstructionType => ({\n // Custom <img> processing\n shouldProcessNode: (node): boolean => {\n // Process img node with id in attachments list\n return (\n node.name &&\n node.name === 'img' &&\n node.attribs &&\n node.attribs.id &&\n props.message.attachedFilesMetadata?.find((f) => f.id === node.attribs.id)\n );\n },\n processNode: (node, children, index): HTMLElement => {\n // logic to check id in map/list\n if (props.attachmentsMap && node.attribs.id in props.attachmentsMap) {\n node.attribs = { ...node.attribs, src: props.attachmentsMap[node.attribs.id] };\n }\n return processNodeDefinitions.processDefaultNode(node, children, index);\n }\n});\n\n/* @conditional-compile-remove(mention) */\nconst processMention = (props: ChatMessageContentProps): ProcessingInstructionType => ({\n shouldProcessNode: (node) => {\n if (props.mentionDisplayOptions?.onRenderMention) {\n // Override the handling of the <msft-mention> tag in the HTML if there's a custom renderer\n return node.name === 'msft-mention';\n }\n return false;\n },\n processNode: (node) => {\n if (props.mentionDisplayOptions?.onRenderMention) {\n const { id, displaytext } = node.attribs;\n const mention: Mention = {\n id: id,\n displayText: displaytext\n };\n return props.mentionDisplayOptions.onRenderMention(mention, defaultOnMentionRender);\n }\n return processNodeDefinitions.processDefaultNode;\n }\n});\n\nconst processHtmlToReact = (props: ChatMessageContentProps): JSX.Element => {\n const steps: ProcessingInstructionType[] = [\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n processInlineImage(props),\n /* @conditional-compile-remove(mention) */\n processMention(props),\n {\n // Process everything else in the default way\n shouldProcessNode: IsValidNodeDefinitions.alwaysValid,\n processNode: processNodeDefinitions.processDefaultNode\n }\n ];\n\n return htmlToReactParser.parseWithInstructions(\n props.message.content ?? '',\n IsValidNodeDefinitions.alwaysValid,\n steps\n );\n};\n\"../../../../acs-ui-common/src\""]}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/**
|
3
3
|
* @beta
|
4
4
|
*/
|
5
|
-
export declare type FileMetadataAttachmentType = 'fileSharing' | /* @conditional-compile-remove(teams-inline-images) */ 'teamsInlineImage' | 'unknown';
|
5
|
+
export declare type FileMetadataAttachmentType = 'fileSharing' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'teamsInlineImage' | 'unknown';
|
6
6
|
/**
|
7
7
|
* Meta Data containing information about the uploaded file.
|
8
8
|
* @beta
|
@@ -56,17 +56,22 @@ export const _FileDownloadCards = (props) => {
|
|
56
56
|
}
|
57
57
|
}
|
58
58
|
}), [props]);
|
59
|
-
// Its safe to assume that if the first item in the fileMetadata is not a fileSharing type we don't want to display the FileDownloadCard.
|
60
|
-
// Since you can't have both fileSharing and teamsInlineImage in the same message.
|
61
59
|
if (!fileMetadata ||
|
62
60
|
fileMetadata.length === 0 ||
|
63
|
-
/* @conditional-compile-remove(teams-inline-images) */ fileMetadata
|
61
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !fileMetadata.some((attachment) => attachment.attachmentType === 'fileSharing')) {
|
64
62
|
return React.createElement(React.Fragment, null);
|
65
63
|
}
|
66
64
|
return (React.createElement("div", { style: fileDownloadCardsStyle, "data-ui-id": "file-download-card-group" },
|
67
65
|
React.createElement(_FileCardGroup, null, fileMetadata &&
|
68
|
-
fileMetadata
|
69
|
-
|
66
|
+
fileMetadata
|
67
|
+
.filter((attachment) => {
|
68
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */
|
69
|
+
return attachment.attachmentType === 'fileSharing';
|
70
|
+
return true;
|
71
|
+
})
|
72
|
+
.map((file) => (React.createElement(_FileCard, { fileName: file.name, key: file.name, fileExtension: file.extension, actionIcon: showSpinner ? (React.createElement(Spinner, { size: SpinnerSize.medium, "aria-live": 'polite', role: 'status' })) : true &&
|
73
|
+
/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ !file.previewUrl ? (React.createElement(IconButton, { className: iconButtonClassName, ariaLabel: downloadFileButtonString() },
|
74
|
+
React.createElement(DownloadIconTrampoline, null))) : undefined, actionHandler: () => fileDownloadHandler(userId, file) }))))));
|
70
75
|
};
|
71
76
|
/**
|
72
77
|
* @private
|
@@ -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.\nimport { Icon, IconButton, Spinner, SpinnerSize } 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';\n\n/* @conditional-compile-remove(teams-inline-images) */\n/**\n * @beta\n */\nexport type FileMetadataAttachmentType =\n | 'fileSharing'\n | /* @conditional-compile-remove(teams-inline-images) */ 'teamsInlineImage'\n | 'unknown';\n\n/**\n * Meta Data containing information about the uploaded file.\n * @beta\n */\nexport interface FileMetadata {\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Attachment type of the file.\n * Possible values {@link FileDownloadHandler}.\n */\n attachmentType: FileMetadataAttachmentType;\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Unique ID of the file.\n */\n id: string;\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Extension is used for rendering the file icon.\n * An unknown extension will be rendered as a generic icon.\n * Example: `jpeg`\n */\n extension: string;\n /**\n * Download URL for the file.\n */\n url: string;\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Preview URL for the file.\n * Used in the message bubble for inline images.\n */\n previewUrl?: string;\n}\n\n/* @conditional-compile-remove(teams-inline-images) */\n/**\n * @beta\n */\nexport interface AttachmentDownloadResult {\n blobUrl: string;\n}\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}\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 FileMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (userId: string, fileMetadata: FileMetadata) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCards {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that inculdes file metadata\n */\n fileMetadata: FileMetadata[];\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 arialabel 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: _FileDownloadCards): 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 // Return download button without aria label\n return props.strings?.downloadFile ?? '';\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId, file) => {\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 // Its safe to assume that if the first item in the fileMetadata is not a fileSharing type we don't want to display the FileDownloadCard.\n // Since you can't have both fileSharing and teamsInlineImage in the same message.\n if (\n !fileMetadata ||\n fileMetadata.length === 0 ||\n /* @conditional-compile-remove(teams-inline-images) */ fileMetadata[0].attachmentType !== 'fileSharing'\n ) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup>\n {fileMetadata &&\n fileMetadata.map((file) => (\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 ) : (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n )\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\n />\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: '' };\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.\nimport { Icon, IconButton, Spinner, SpinnerSize } 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';\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @beta\n */\nexport type FileMetadataAttachmentType =\n | 'fileSharing'\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'teamsInlineImage'\n | 'unknown';\n\n/**\n * Meta Data containing information about the uploaded file.\n * @beta\n */\nexport interface FileMetadata {\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n /*\n * Attachment type of the file.\n * Possible values {@link FileDownloadHandler}.\n */\n attachmentType: FileMetadataAttachmentType;\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n /*\n * Unique ID of the file.\n */\n id: string;\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Extension is used for rendering the file icon.\n * An unknown extension will be rendered as a generic icon.\n * Example: `jpeg`\n */\n extension: string;\n /**\n * Download URL for the file.\n */\n url: string;\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n /*\n * Preview URL for the file.\n * Used in the message bubble for inline images.\n */\n previewUrl?: string;\n}\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @beta\n */\nexport interface AttachmentDownloadResult {\n blobUrl: string;\n}\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}\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 FileMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (userId: string, fileMetadata: FileMetadata) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCards {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that inculdes file metadata\n */\n fileMetadata: FileMetadata[];\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 arialabel 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: _FileDownloadCards): 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 // Return download button without aria label\n return props.strings?.downloadFile ?? '';\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId, file: FileMetadata) => {\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(\n (attachment) => attachment.attachmentType === 'fileSharing'\n )\n ) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup>\n {fileMetadata &&\n fileMetadata\n .filter((attachment) => {\n /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n return attachment.attachmentType === 'fileSharing';\n return true;\n })\n .map((file) => (\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) */ !file.previewUrl ? (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n ) : undefined\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\n />\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: '' };\n};\n"]}
|
@@ -256,12 +256,6 @@ export const InputBoxComponent = (props) => {
|
|
256
256
|
updateMentionSuggestions(suggestions);
|
257
257
|
}), 500);
|
258
258
|
/* @conditional-compile-remove(mention) */
|
259
|
-
useEffect(() => {
|
260
|
-
return () => {
|
261
|
-
debouncedQueryUpdate.cancel();
|
262
|
-
};
|
263
|
-
}, [debouncedQueryUpdate]);
|
264
|
-
/* @conditional-compile-remove(mention) */
|
265
259
|
// Update selections index in mention to navigate by words
|
266
260
|
const updateSelectionIndexesWithMentionIfNeeded = useCallback((event, inputTextValue, selectionStartValue, selectionEndValue, tagsValue) => {
|
267
261
|
var _a, _b, _c;
|
@@ -386,6 +380,7 @@ export const InputBoxComponent = (props) => {
|
|
386
380
|
/* @conditional-compile-remove(mention) */
|
387
381
|
const handleOnChange = useCallback((event, tagsValue, htmlTextValue, inputTextValue, currentTriggerStartIndex, previousSelectionStart, previousSelectionEnd, currentSelectionStart, currentSelectionEnd, updatedValue) => __awaiter(void 0, void 0, void 0, function* () {
|
388
382
|
var _b;
|
383
|
+
debouncedQueryUpdate.cancel();
|
389
384
|
if (event.currentTarget === null) {
|
390
385
|
return;
|
391
386
|
}
|
@@ -609,8 +604,10 @@ export const InputBoxComponent = (props) => {
|
|
609
604
|
setCaretIndex(undefined);
|
610
605
|
setSelectionStartValue(null);
|
611
606
|
setSelectionEndValue(null);
|
612
|
-
// Dismiss the suggestions on blur
|
613
|
-
|
607
|
+
// Dismiss the suggestions on blur, after enough time to select by mouse if needed
|
608
|
+
setTimeout(() => {
|
609
|
+
setMentionSuggestions([]);
|
610
|
+
}, 200);
|
614
611
|
}, autoComplete: "off", onKeyDown: onTextFieldKeyDown, styles: mergedTextFieldStyle, disabled: disabled, errorMessage: errorMessage, onRenderSuffix: onRenderChildren, elementRef: inputBoxRef }))));
|
615
612
|
};
|
616
613
|
/**
|