@azure/communication-react 1.14.0-alpha-202403080013 → 1.14.0-alpha-202403120012
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 +12 -10
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-CQnsLK4_.js → RichTextSendBoxWrapper-DdhoRD21.js} +2 -2
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-CQnsLK4_.js.map → RichTextSendBoxWrapper-DdhoRD21.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index--vbi3hW5.js → index-C48Yhr_k.js} +146 -134
- package/dist/dist-cjs/communication-react/index-C48Yhr_k.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +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 +14 -25
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/ChatContext.js +13 -2
- package/dist/dist-esm/chat-stateful-client/src/ChatContext.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.d.ts +11 -2
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.js +36 -12
- package/dist/dist-esm/chat-stateful-client/src/ResourceDownloadQueue.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +20 -22
- 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 +2 -2
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ImageOverlay.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/ImageOverlay.js +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/ReactionButton.d.ts +2 -0
- package/dist/dist-esm/react-components/src/components/ReactionButton.js +1 -1
- package/dist/dist-esm/react-components/src/components/ReactionButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +3 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js +12 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/localization/locales/en-US/strings.json +1 -0
- package/dist/dist-esm/react-components/src/theming/themes.d.ts +1 -1
- package/dist/dist-esm/react-components/src/theming/themes.js +1 -1
- package/dist/dist-esm/react-components/src/theming/themes.js.map +1 -1
- package/dist/dist-esm/react-components/src/theming/v9ThemeShim.js +7 -0
- package/dist/dist-esm/react-components/src/theming/v9ThemeShim.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +0 -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.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +2 -10
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/hooks/useHandlers.js +0 -1
- 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/CallPage.js +1 -22
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/CallPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/DtmfDialpadPage.js +0 -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/MediaGalleryUtils.js +0 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/MediaGalleryUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +0 -2
- 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.d.ts +2 -2
- 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/CallWithChatBackedCallAdapter.js +0 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +28 -10
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js +2 -9
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js +0 -8
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DtmfDialerButton.js +0 -7
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DtmfDialerButton.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js +0 -8
- 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/PreparedMoreDrawer.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/SendBox.js +1 -2
- package/dist/dist-esm/react-composites/src/composites/common/SendBox.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/icons.js +0 -2
- package/dist/dist-esm/react-composites/src/composites/common/icons.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +3 -3
- package/dist/dist-cjs/communication-react/index--vbi3hW5.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ResourceDownloadQueue.js","sourceRoot":"","sources":["../../../../../chat-stateful-client/src/ResourceDownloadQueue.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatContext } from './ChatContext';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatError } from './ChatClientState';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatMessageWithStatus, ResourceFetchResult } from './types/ChatMessageWithStatus';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport type { CommunicationTokenCredential } from '@azure/communication-common';\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @private\n */\nexport class ResourceDownloadQueue {\n private _messagesNeedingResourceRetrieval: ChatMessageWithStatus[] = [];\n private _context: ChatContext;\n private isActive = false;\n private _credential: CommunicationTokenCredential;\n\n constructor(context: ChatContext, credential: CommunicationTokenCredential) {\n this._context = context;\n this._credential = credential;\n }\n\n public containsMessageWithSameAttachments(message: ChatMessageWithStatus): boolean {\n let contains = false;\n const incomingAttachment = message.content?.attachments;\n if (incomingAttachment) {\n for (const m of this._messagesNeedingResourceRetrieval) {\n const existingAttachment = m.content?.attachments ?? [];\n contains = incomingAttachment.every((element, index) => element === existingAttachment[index]);\n if (contains) {\n break;\n }\n }\n }\n\n return contains;\n }\n\n public addMessage(message: ChatMessageWithStatus): void {\n // make a copy of message and add to queue\n const copy = { ...message };\n this._messagesNeedingResourceRetrieval.push(copy);\n }\n\n public async startQueue(threadId: string, operation: ImageRequest, options?: { singleUrl: string }): Promise<void> {\n if (this.isActive) {\n return;\n }\n while (this._messagesNeedingResourceRetrieval.length > 0) {\n this.isActive = true;\n let message = this._messagesNeedingResourceRetrieval.shift();\n if (!message) {\n this.isActive = false;\n continue;\n }\n\n if (options) {\n const singleUrl = options.singleUrl;\n message = await this.downloadSingleUrl(message, singleUrl, operation);\n } else {\n message = await this.downloadAllPreviewUrls(message, operation);\n }\n this._context.setChatMessage(threadId, message);\n this.isActive = false;\n }\n }\n\n private async downloadSingleUrl(\n message: ChatMessageWithStatus,\n resourceUrl: string,\n operation: ImageRequest\n ): Promise<ChatMessageWithStatus> {\n const response: ResourceFetchResult = { sourceUrl: '' };\n try {\n const blobUrl = await this.downloadResource(operation, resourceUrl);\n response.sourceUrl = blobUrl;\n } catch (error) {\n response.error = error as Error;\n }\n\n message = { ...message, resourceCache: { ...message.resourceCache, [resourceUrl]: response } };\n return message;\n }\n\n private async downloadAllPreviewUrls(\n message: ChatMessageWithStatus,\n operation: ImageRequest\n ): Promise<ChatMessageWithStatus> {\n const attachments = message.content?.attachments;\n if (message.type === 'html' && attachments) {\n if (message.resourceCache === undefined) {\n message.resourceCache = {};\n }\n for (const attachment of attachments) {\n if (attachment.previewUrl && attachment.attachmentType === 'image') {\n const response: ResourceFetchResult = { sourceUrl: '' };\n try {\n const blobUrl = await this.downloadResource(operation, attachment.previewUrl);\n response.sourceUrl = blobUrl;\n } catch (error) {\n response.error = error as Error;\n }\n message.resourceCache[attachment.previewUrl] = response;\n }\n }\n }\n\n return message;\n }\n\n private async downloadResource(operation: ImageRequest, url: string): Promise<string> {\n const blobUrl = await operation(url, this._credential);\n return blobUrl;\n }\n}\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @private\n */\nexport const fetchImageSource = async (src: string, credential: CommunicationTokenCredential): Promise<string> => {\n async function fetchWithAuthentication(url: string, token: string): Promise<Response> {\n const headers = new Headers();\n headers.append('Authorization', `Bearer ${token}`);\n try {\n return await fetchWithTimeout(url, { headers });\n } catch (err) {\n throw new ChatError('ChatThreadClient.getMessage', err as Error);\n }\n }\n async function fetchWithTimeout(\n resource: string | URL | Request,\n options: { timeout?: number; headers?: Headers }\n ): Promise<Response> {\n // default timeout is 30 seconds\n const { timeout = 30000 } = options;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(resource, {\n ...options,\n signal: controller.signal\n });\n clearTimeout(id);\n return response;\n }\n const accessToken = await credential.getToken();\n const response = await fetchWithAuthentication(src, accessToken.token);\n const blob = await response.blob();\n return URL.createObjectURL(blob);\n};\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\ninterface ImageRequest {\n (request: string, credential: CommunicationTokenCredential): Promise<string>;\n}\n"]}
|
1
|
+
{"version":3,"file":"ResourceDownloadQueue.js","sourceRoot":"","sources":["../../../../../chat-stateful-client/src/ResourceDownloadQueue.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatContext } from './ChatContext';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatError } from './ChatClientState';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport { ChatMessageWithStatus, ResourceFetchResult } from './types/ChatMessageWithStatus';\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\nimport type { CommunicationTokenCredential } from '@azure/communication-common';\n\ndeclare type CancellationDetails = { src: string; abortController: AbortController };\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @private\n */\nexport class ResourceDownloadQueue {\n private _messagesNeedingResourceRetrieval: ChatMessageWithStatus[] = [];\n private _context: ChatContext;\n private isActive = false;\n private _credential: CommunicationTokenCredential;\n private _requestsToCancel: Record<string, CancellationDetails> = {};\n\n constructor(context: ChatContext, credential: CommunicationTokenCredential) {\n this._context = context;\n this._credential = credential;\n }\n\n public containsMessageWithSameAttachments(message: ChatMessageWithStatus): boolean {\n let contains = false;\n const incomingAttachment = message.content?.attachments;\n if (incomingAttachment) {\n for (const m of this._messagesNeedingResourceRetrieval) {\n const existingAttachment = m.content?.attachments ?? [];\n contains = incomingAttachment.every((element, index) => element === existingAttachment[index]);\n if (contains) {\n break;\n }\n }\n }\n\n return contains;\n }\n\n public addMessage(message: ChatMessageWithStatus): void {\n // make a copy of message and add to queue\n const copy = { ...message };\n this._messagesNeedingResourceRetrieval.push(copy);\n }\n\n public async startQueue(threadId: string, operation: ImageRequest, options?: { singleUrl: string }): Promise<void> {\n if (this.isActive) {\n return;\n }\n while (this._messagesNeedingResourceRetrieval.length > 0) {\n this.isActive = true;\n let message = this._messagesNeedingResourceRetrieval.shift();\n if (!message) {\n this.isActive = false;\n continue;\n }\n\n if (options) {\n const singleUrl = options.singleUrl;\n message = await this.downloadSingleUrl(message, singleUrl, operation);\n } else {\n message = await this.downloadAllPreviewUrls(message, operation);\n }\n this._context.setChatMessage(threadId, message);\n this.isActive = false;\n }\n }\n\n public cancelAllRequests(): void {\n for (const key in this._requestsToCancel) {\n this._requestsToCancel[key].abortController.abort();\n }\n this._requestsToCancel = {};\n }\n\n public cancelRequest(url: string): void {\n if (this._requestsToCancel[url]) {\n this._requestsToCancel[url].abortController.abort();\n delete this._requestsToCancel[url];\n }\n }\n\n private async downloadSingleUrl(\n message: ChatMessageWithStatus,\n resourceUrl: string,\n operation: ImageRequest\n ): Promise<ChatMessageWithStatus> {\n const response: ResourceFetchResult = { sourceUrl: '' };\n try {\n const abortController = new AbortController();\n const blobUrl = await this.downloadResource(operation, resourceUrl, abortController);\n response.sourceUrl = blobUrl;\n } catch (error) {\n response.error = error as Error;\n delete this._requestsToCancel[resourceUrl];\n }\n\n message = { ...message, resourceCache: { ...message.resourceCache, [resourceUrl]: response } };\n return message;\n }\n\n private async downloadAllPreviewUrls(\n message: ChatMessageWithStatus,\n operation: ImageRequest\n ): Promise<ChatMessageWithStatus> {\n const attachments = message.content?.attachments;\n if (message.type === 'html' && attachments) {\n if (message.resourceCache === undefined) {\n message.resourceCache = {};\n }\n for (const attachment of attachments) {\n if (attachment.previewUrl && attachment.attachmentType === 'image') {\n const response: ResourceFetchResult = { sourceUrl: '' };\n try {\n const abortController = new AbortController();\n const blobUrl = await this.downloadResource(operation, attachment.previewUrl, abortController);\n response.sourceUrl = blobUrl;\n } catch (error) {\n response.error = error as Error;\n delete this._requestsToCancel[attachment.previewUrl];\n }\n message.resourceCache[attachment.previewUrl] = response;\n }\n }\n }\n\n return message;\n }\n\n private async downloadResource(\n operation: ImageRequest,\n url: string,\n abortController: AbortController\n ): Promise<string> {\n this._requestsToCancel[url] = { src: url, abortController };\n const blobUrl = await operation(url, this._credential, { abortController });\n delete this._requestsToCancel[url];\n return blobUrl;\n }\n}\n\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\n/**\n * @private\n */\nexport const fetchImageSource = async (\n src: string,\n credential: CommunicationTokenCredential,\n options: { abortController: AbortController; timeout?: number }\n): Promise<string> => {\n async function fetchWithAuthentication(\n url: string,\n token: string,\n options: { abortController: AbortController; timeout?: number }\n ): Promise<Response> {\n const headers = new Headers();\n headers.append('Authorization', `Bearer ${token}`);\n try {\n return await fetchWithTimeout(url, {\n timeout: options.timeout,\n headers,\n abortController: options.abortController\n });\n } catch (err) {\n throw new ChatError('ChatThreadClient.getMessage', err as Error);\n }\n }\n async function fetchWithTimeout(\n resource: string | URL | Request,\n options: { timeout?: number; headers?: Headers; abortController: AbortController }\n ): Promise<Response> {\n // default timeout is 30 seconds\n const { timeout = 30000, abortController } = options;\n\n const id = setTimeout(() => {\n abortController.abort();\n }, timeout);\n\n const response = await fetch(resource, {\n ...options,\n signal: abortController.signal\n });\n clearTimeout(id);\n return response;\n }\n const accessToken = await credential.getToken();\n const response = await fetchWithAuthentication(src, accessToken.token, options);\n const blob = await response.blob();\n\n return URL.createObjectURL(blob);\n};\n/* @conditional-compile-remove(teams-inline-images-and-file-sharing) */\ninterface ImageRequest {\n (\n request: string,\n credential: CommunicationTokenCredential,\n options: { abortController: AbortController; timeout?: number }\n ): Promise<string>;\n}\n"]}
|
@@ -16,18 +16,18 @@ type BlockedMessageContentProps = {
|
|
16
16
|
/**
|
17
17
|
* InlineImage's state, as reflected in the UI.
|
18
18
|
*
|
19
|
-
* @
|
19
|
+
* @public
|
20
20
|
*/
|
21
21
|
export interface InlineImage {
|
22
22
|
/** ID of the message that the inline image is belonged to */
|
23
23
|
messageId: string;
|
24
24
|
/** Attributes of the inline image */
|
25
|
-
|
25
|
+
imageAttributes: React.ImgHTMLAttributes<HTMLImageElement>;
|
26
26
|
}
|
27
27
|
/**
|
28
28
|
* Options to display inline image in the inline image scenario.
|
29
29
|
*
|
30
|
-
* @
|
30
|
+
* @public
|
31
31
|
*/
|
32
32
|
export interface InlineImageOptions {
|
33
33
|
/**
|
@@ -59,17 +59,7 @@ export const BlockedMessageContent = (props) => {
|
|
59
59
|
blockedMessage && React.createElement("p", null, blockedMessage),
|
60
60
|
blockedMessageLink && (React.createElement(Link, { target: '_blank', href: blockedMessageLink }, blockedMessageLinkText))) }));
|
61
61
|
};
|
62
|
-
|
63
|
-
const extractContent = (s) => {
|
64
|
-
const span = document.createElement('span');
|
65
|
-
span.innerHTML = s;
|
66
|
-
return span.textContent || span.innerText;
|
67
|
-
};
|
68
|
-
const generateLiveMessage = (props) => {
|
69
|
-
const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });
|
70
|
-
return `${props.message.editedOn ? props.strings.editedTag : ''} ${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')} `;
|
71
|
-
};
|
72
|
-
const messageContentAriaText = (props) => {
|
62
|
+
const extractContentForAllyMessage = (props) => {
|
73
63
|
if (props.message.content) {
|
74
64
|
// Replace all <img> tags with 'image' for aria.
|
75
65
|
const parsedContent = DOMPurify.sanitize(props.message.content, {
|
@@ -86,20 +76,28 @@ const messageContentAriaText = (props) => {
|
|
86
76
|
});
|
87
77
|
// Strip all html tags from the content for aria.
|
88
78
|
const message = DOMPurify.sanitize(parsedContent, { ALLOWED_TAGS: [] });
|
89
|
-
return
|
90
|
-
? _formatString(props.strings.messageContentMineAriaText, {
|
91
|
-
message: message
|
92
|
-
})
|
93
|
-
: _formatString(props.strings.messageContentAriaText, {
|
94
|
-
author: `${props.message.senderDisplayName}`,
|
95
|
-
message: message
|
96
|
-
});
|
79
|
+
return message;
|
97
80
|
}
|
98
|
-
return
|
81
|
+
return '';
|
82
|
+
};
|
83
|
+
const generateLiveMessage = (props) => {
|
84
|
+
const liveAuthor = _formatString(props.strings.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });
|
85
|
+
return `${props.message.editedOn ? props.strings.editedTag : ''} ${props.message.mine ? '' : liveAuthor} ${extractContentForAllyMessage(props)} `;
|
86
|
+
};
|
87
|
+
const messageContentAriaText = (props) => {
|
88
|
+
const message = extractContentForAllyMessage(props);
|
89
|
+
return props.message.mine
|
90
|
+
? _formatString(props.strings.messageContentMineAriaText, {
|
91
|
+
message: message
|
92
|
+
})
|
93
|
+
: _formatString(props.strings.messageContentAriaText, {
|
94
|
+
author: `${props.message.senderDisplayName}`,
|
95
|
+
message: message
|
96
|
+
});
|
99
97
|
};
|
100
98
|
/* @conditional-compile-remove(image-overlay) */
|
101
99
|
const defaultOnRenderInlineImage = (inlineImage) => {
|
102
|
-
return (React.createElement("img", Object.assign({ key: inlineImage.
|
100
|
+
return (React.createElement("img", Object.assign({ key: inlineImage.imageAttributes.id, tabIndex: 0, "data-ui-id": inlineImage.imageAttributes.id }, inlineImage.imageAttributes)));
|
103
101
|
};
|
104
102
|
const processHtmlToReact = (props) => {
|
105
103
|
var _a;
|
@@ -126,7 +124,7 @@ const processHtmlToReact = (props) => {
|
|
126
124
|
domNode.attribs['aria-label'] = domNode.attribs.name;
|
127
125
|
const imgProps = attributesToProps(domNode.attribs);
|
128
126
|
/* @conditional-compile-remove(image-overlay) */
|
129
|
-
const inlineImageProps = { messageId: props.message.messageId,
|
127
|
+
const inlineImageProps = { messageId: props.message.messageId, imageAttributes: imgProps };
|
130
128
|
/* @conditional-compile-remove(image-overlay) */
|
131
129
|
return ((_c = props.inlineImageOptions) === null || _c === void 0 ? void 0 : _c.onRenderInlineImage)
|
132
130
|
? props.inlineImageOptions.onRenderInlineImage(inlineImageProps, defaultOnRenderInlineImage)
|
@@ -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 (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 (domNode.name && domNode.name === 'img' && domNode.attribs && domNode.attribs.id) {\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 * @public\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 imageAttributes: 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 * @public\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\nconst extractContentForAllyMessage = (props: ChatMessageContentProps): string => {\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 return message;\n }\n return '';\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 } ${extractContentForAllyMessage(props)} `;\n};\n\nconst messageContentAriaText = (props: ChatMessageContentProps): string | undefined => {\n const message = extractContentForAllyMessage(props);\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\n/* @conditional-compile-remove(image-overlay) */\nconst defaultOnRenderInlineImage = (inlineImage: InlineImage): JSX.Element => {\n return (\n <img\n key={inlineImage.imageAttributes.id}\n tabIndex={0}\n data-ui-id={inlineImage.imageAttributes.id}\n {...inlineImage.imageAttributes}\n />\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 (domNode.name && domNode.name === 'img' && domNode.attribs && domNode.attribs.id) {\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, imageAttributes: 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,9 +1,9 @@
|
|
1
1
|
/// <reference types="react" />
|
2
2
|
/**
|
3
3
|
* Represents the type of attachment
|
4
|
-
* @
|
4
|
+
* @public
|
5
5
|
*/
|
6
|
-
export type ChatAttachmentType = 'unknown' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ '
|
6
|
+
export type ChatAttachmentType = 'unknown' | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'image' | /* @conditional-compile-remove(file-sharing) */ 'file';
|
7
7
|
/**
|
8
8
|
* Metadata containing basic information about the uploaded file.
|
9
9
|
*
|
@@ -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 AttachmentMetadata {\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/**\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 /* @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.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?.length ?? 0}`\n });\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.length ?? 0}`\n });\n },\n [props.strings?.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata]\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\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.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(file) ? (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n ) : undefined\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\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
|
+
{"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(teams-inline-images-and-file-sharing) */\n/**\n * Represents the type of attachment\n * @public\n */\nexport type ChatAttachmentType =\n | 'unknown'\n | /* @conditional-compile-remove(teams-inline-images-and-file-sharing) */ 'image'\n | /* @conditional-compile-remove(file-sharing) */ 'file';\n\n/**\n * Metadata containing basic information about the uploaded file.\n *\n * @beta\n */\nexport interface AttachmentMetadata {\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/**\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 /* @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.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?.length ?? 0}`\n });\n return _formatString(fileGroupLocaleString, {\n fileCount: `${fileMetadata?.length ?? 0}`\n });\n },\n [props.strings?.fileCardGroupMessage, localeStrings.fileCardGroupMessage, fileMetadata]\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\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.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(file) ? (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n ) : undefined\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\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"]}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/**
|
3
3
|
* Props for {@link ImageOverlay}.
|
4
4
|
*
|
5
|
-
* @
|
5
|
+
* @public
|
6
6
|
*/
|
7
7
|
export interface ImageOverlayProps {
|
8
8
|
/**
|
@@ -52,7 +52,7 @@ export interface ImageOverlayStrings {
|
|
52
52
|
/**
|
53
53
|
* Component to render a fullscreen modal for a selected image.
|
54
54
|
*
|
55
|
-
* @
|
55
|
+
* @public
|
56
56
|
*/
|
57
57
|
export declare const ImageOverlay: (props: ImageOverlayProps) => JSX.Element;
|
58
58
|
//# sourceMappingURL=ImageOverlay.d.ts.map
|
@@ -16,7 +16,7 @@ import { imageOverlayTheme } from '../theming';
|
|
16
16
|
/**
|
17
17
|
* Component to render a fullscreen modal for a selected image.
|
18
18
|
*
|
19
|
-
* @
|
19
|
+
* @public
|
20
20
|
*/
|
21
21
|
export const ImageOverlay = (props) => {
|
22
22
|
const { isOpen, imageSrc, title, titleIcon, altText, onDownloadButtonClicked, onDismiss } = props;
|
@@ -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 * @
|
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 * @public\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 * @public\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"]}
|