@azure/communication-react 1.14.1-alpha-202403280012 → 1.14.1-alpha-202403290012

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.
Files changed (83) hide show
  1. package/dist/communication-react.d.ts +134 -61
  2. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-D3ER8Kz9.js → RichTextSendBoxWrapper-CH6WvEGZ.js} +4 -4
  3. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-D3ER8Kz9.js.map → RichTextSendBoxWrapper-CH6WvEGZ.js.map} +1 -1
  4. package/dist/dist-cjs/communication-react/{index-BI61bnOi.js → index-qxnuqL7s.js} +291 -207
  5. package/dist/dist-cjs/communication-react/index-qxnuqL7s.js.map +1 -0
  6. package/dist/dist-cjs/communication-react/index.js +3 -3
  7. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  8. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  9. package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js +1 -2
  10. package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
  11. package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
  12. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/AttachmentCard.d.ts +11 -15
  14. package/dist/dist-esm/react-components/src/components/AttachmentCard.js +25 -41
  15. package/dist/dist-esm/react-components/src/components/AttachmentCard.js.map +1 -1
  16. package/dist/dist-esm/react-components/src/components/AttachmentDownloadCards.d.ts +18 -11
  17. package/dist/dist-esm/react-components/src/components/AttachmentDownloadCards.js +74 -62
  18. package/dist/dist-esm/react-components/src/components/AttachmentDownloadCards.js.map +1 -1
  19. package/dist/dist-esm/react-components/src/components/AttachmentUploadCards.js +37 -4
  20. package/dist/dist-esm/react-components/src/components/AttachmentUploadCards.js.map +1 -1
  21. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.d.ts +6 -3
  22. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.js.map +1 -1
  23. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.d.ts +5 -5
  24. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.js +7 -7
  25. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.js.map +1 -1
  26. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/FluentChatMessageComponent.js +13 -18
  27. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/FluentChatMessageComponent.js.map +1 -1
  28. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.d.ts +9 -9
  29. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.js.map +1 -1
  30. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponentAsMessageBubble.d.ts +9 -9
  31. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponentAsMessageBubble.js +10 -10
  32. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponentAsMessageBubble.js.map +1 -1
  33. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js +12 -10
  34. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js.map +1 -1
  35. package/dist/dist-esm/react-components/src/components/MessageThread.d.ts +10 -9
  36. package/dist/dist-esm/react-components/src/components/MessageThread.js +6 -3
  37. package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
  38. package/dist/dist-esm/react-components/src/components/index.d.ts +2 -2
  39. package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
  40. package/dist/dist-esm/react-components/src/components/styles/AttachmentCard.styles.d.ts +1 -1
  41. package/dist/dist-esm/react-components/src/components/styles/AttachmentCard.styles.js +1 -1
  42. package/dist/dist-esm/react-components/src/components/styles/AttachmentCard.styles.js.map +1 -1
  43. package/dist/dist-esm/react-components/src/components/utils/ChatMessageComponentUtils.d.ts +10 -2
  44. package/dist/dist-esm/react-components/src/components/utils/ChatMessageComponentUtils.js +20 -14
  45. package/dist/dist-esm/react-components/src/components/utils/ChatMessageComponentUtils.js.map +1 -1
  46. package/dist/dist-esm/react-components/src/localization/locales/en-US/strings.json +1 -0
  47. package/dist/dist-esm/react-components/src/theming/icons.d.ts +3 -2
  48. package/dist/dist-esm/react-components/src/theming/icons.js +5 -3
  49. package/dist/dist-esm/react-components/src/theming/icons.js.map +1 -1
  50. package/dist/dist-esm/react-components/src/types/Attachment.d.ts +97 -37
  51. package/dist/dist-esm/react-components/src/types/Attachment.js.map +1 -1
  52. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js +3 -3
  53. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.js.map +1 -1
  54. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalPreview.js +2 -2
  55. package/dist/dist-esm/react-composites/src/composites/CallComposite/components/LocalPreview.js.map +1 -1
  56. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.d.ts +1 -1
  57. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js +32 -17
  58. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js.map +1 -1
  59. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalDeviceSettings.styles.d.ts +5 -1
  60. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalDeviceSettings.styles.js +12 -0
  61. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalDeviceSettings.styles.js.map +1 -1
  62. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalPreview.styles.d.ts +2 -14
  63. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalPreview.styles.js +14 -10
  64. package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/LocalPreview.styles.js.map +1 -1
  65. package/dist/dist-esm/react-composites/src/composites/ChatComposite/AttachmentDownloadErrorBar.d.ts +15 -0
  66. package/dist/dist-esm/react-composites/src/composites/ChatComposite/{FileDownloadErrorBar.js → AttachmentDownloadErrorBar.js} +5 -5
  67. package/dist/dist-esm/react-composites/src/composites/ChatComposite/AttachmentDownloadErrorBar.js.map +1 -0
  68. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.d.ts +4 -5
  69. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +10 -7
  70. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
  71. package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/FileUploadButton.js +1 -1
  72. package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/FileUploadButton.js.map +1 -1
  73. package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/index.d.ts +2 -0
  74. package/dist/dist-esm/react-composites/src/composites/ChatComposite/file-sharing/index.js.map +1 -1
  75. package/dist/dist-esm/react-composites/src/composites/ChatComposite/index.d.ts +1 -1
  76. package/dist/dist-esm/react-composites/src/composites/ChatComposite/index.js.map +1 -1
  77. package/dist/dist-esm/react-composites/src/composites/common/PeoplePaneContent.js +11 -2
  78. package/dist/dist-esm/react-composites/src/composites/common/PeoplePaneContent.js.map +1 -1
  79. package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +3 -2
  80. package/package.json +1 -1
  81. package/dist/dist-cjs/communication-react/index-BI61bnOi.js.map +0 -1
  82. package/dist/dist-esm/react-composites/src/composites/ChatComposite/FileDownloadErrorBar.d.ts +0 -15
  83. package/dist/dist-esm/react-composites/src/composites/ChatComposite/FileDownloadErrorBar.js.map +0 -1
@@ -1,99 +1,111 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
- return new (P || (P = Promise))(function (resolve, reject) {
6
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
- step((generator = generator.apply(thisArg, _arguments || [])).next());
10
- });
11
- };
12
- import { Icon, Spinner, SpinnerSize, TooltipHost } from '@fluentui/react';
13
- import React, { useCallback, useState } from 'react';
3
+ import { Icon, TooltipHost } from '@fluentui/react';
4
+ import React, { useCallback } from 'react';
14
5
  import { useMemo } from 'react';
15
6
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
16
7
  import { useLocale } from '../localization';
17
8
  import { _AttachmentCard } from './AttachmentCard';
18
9
  import { _AttachmentCardGroup } from './AttachmentCardGroup';
19
10
  import { _formatString } from "../../../acs-ui-common/src";
20
- import { Open20Regular } from '@fluentui/react-icons';
21
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
22
- import { ArrowDownload20Regular } from '@fluentui/react-icons';
23
11
  const attachmentDownloadCardsStyle = {
24
12
  marginTop: '0.25rem'
25
13
  };
26
- const actionIconStyle = { height: '1rem' };
27
14
  /**
28
15
  * @internal
29
16
  */
30
17
  export const _AttachmentDownloadCards = (props) => {
31
18
  var _a, _b;
32
- const { userId, fileMetadata } = props;
33
- const [showSpinner, setShowSpinner] = useState(false);
19
+ const { attachments, message } = props;
34
20
  const localeStrings = useLocaleStringsTrampoline();
21
+ const getMenuActions = useCallback((attachment, localeStrings, message, action) => {
22
+ const defaultMenuActions = getDefaultMenuActions(localeStrings, message);
23
+ try {
24
+ const actions = action === null || action === void 0 ? void 0 : action(attachment, message);
25
+ if (actions && actions.length > 0) {
26
+ return actions;
27
+ }
28
+ else {
29
+ return defaultMenuActions;
30
+ }
31
+ }
32
+ catch (error) {
33
+ return defaultMenuActions;
34
+ }
35
+ }, []);
35
36
  const downloadAttachmentButtonString = useMemo(() => () => {
36
37
  var _a, _b;
37
38
  return (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.downloadAttachment) !== null && _b !== void 0 ? _b : localeStrings.downloadAttachment;
38
39
  }, [(_a = props.strings) === null || _a === void 0 ? void 0 : _a.downloadAttachment, localeStrings.downloadAttachment]);
39
- const isShowDownloadIcon = useCallback((attachment) => {
40
- var _a;
41
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
42
- return ((_a = attachment.payload) === null || _a === void 0 ? void 0 : _a.teamsFileAttachment) !== 'true';
43
- return true;
44
- }, []);
45
40
  const attachmentCardGroupDescription = useMemo(() => () => {
46
41
  var _a, _b, _c, _d;
47
- const fileGroupLocaleString = (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.attachmentCardGroupMessage) !== null && _b !== void 0 ? _b : localeStrings.attachmentCardGroupMessage;
42
+ const attachmentGroupLocaleString = (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.attachmentCardGroupMessage) !== null && _b !== void 0 ? _b : localeStrings.attachmentCardGroupMessage;
48
43
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
49
- return _formatString(fileGroupLocaleString, {
50
- attachmentCount: `${(_c = fileMetadata === null || fileMetadata === void 0 ? void 0 : fileMetadata.length) !== null && _c !== void 0 ? _c : 0}`
44
+ return _formatString(attachmentGroupLocaleString, {
45
+ attachmentCount: `${(_c = attachments === null || attachments === void 0 ? void 0 : attachments.length) !== null && _c !== void 0 ? _c : 0}`
51
46
  });
52
- return _formatString(fileGroupLocaleString, {
53
- attachmentCount: `${(_d = fileMetadata === null || fileMetadata === void 0 ? void 0 : fileMetadata.length) !== null && _d !== void 0 ? _d : 0}`
47
+ return _formatString(attachmentGroupLocaleString, {
48
+ attachmentCount: `${(_d = attachments === null || attachments === void 0 ? void 0 : attachments.length) !== null && _d !== void 0 ? _d : 0}`
54
49
  });
55
- }, [(_b = props.strings) === null || _b === void 0 ? void 0 : _b.attachmentCardGroupMessage, localeStrings.attachmentCardGroupMessage, fileMetadata]);
56
- const fileDownloadHandler = useCallback((userId, file) => __awaiter(void 0, void 0, void 0, function* () {
57
- if (!props.downloadHandler) {
58
- window.open(file.url, '_blank', 'noopener,noreferrer');
59
- }
60
- else {
61
- setShowSpinner(true);
62
- try {
63
- const response = yield props.downloadHandler(userId, file);
64
- setShowSpinner(false);
65
- if (response instanceof URL) {
66
- window.open(response.toString(), '_blank', 'noopener,noreferrer');
67
- }
68
- else {
69
- props.onDownloadErrorMessage && props.onDownloadErrorMessage(response.errorMessage);
70
- }
71
- }
72
- finally {
73
- setShowSpinner(false);
74
- }
75
- }
76
- }), [props]);
77
- if (!fileMetadata || fileMetadata.length === 0 || !fileMetadata) {
50
+ }, [(_b = props.strings) === null || _b === void 0 ? void 0 : _b.attachmentCardGroupMessage, localeStrings.attachmentCardGroupMessage, attachments]);
51
+ if (!attachments || attachments.length === 0 || !attachments) {
78
52
  return React.createElement(React.Fragment, null);
79
53
  }
80
- return (React.createElement("div", { style: attachmentDownloadCardsStyle, "data-ui-id": "file-download-card-group" },
81
- React.createElement(_AttachmentCardGroup, { ariaLabel: attachmentCardGroupDescription() }, fileMetadata &&
82
- fileMetadata.map((attachment) => (React.createElement(TooltipHost, { content: downloadAttachmentButtonString(), key: attachment.name },
83
- React.createElement(_AttachmentCard, { attachmentName: attachment.name, key: attachment.name, attachmentExtension: attachment.extension, actionIcon: showSpinner ? (React.createElement(Spinner, { size: SpinnerSize.medium, "aria-live": 'polite', role: 'status' })) : true && isShowDownloadIcon(attachment) ? (React.createElement(DownloadIconTrampoline, null)) : (React.createElement(Open20Regular, null)), actionHandler: () => fileDownloadHandler(userId, attachment) })))))));
54
+ return (React.createElement("div", { style: attachmentDownloadCardsStyle, "data-ui-id": "attachment-download-card-group" },
55
+ React.createElement(_AttachmentCardGroup, { ariaLabel: attachmentCardGroupDescription() }, attachments &&
56
+ attachments.map((attachment) => (React.createElement(TooltipHost, { content: downloadAttachmentButtonString(), key: attachment.name },
57
+ React.createElement(_AttachmentCard, { attachment: attachment, key: attachment.id, menuActions: getMenuActions(attachment, localeStrings, message, props.actionsForAttachment), onActionHandlerFailed: props.onActionHandlerFailed })))))));
84
58
  };
85
59
  /**
86
60
  * @private
87
61
  */
88
- const DownloadIconTrampoline = () => {
89
- // @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload)
90
- return React.createElement(ArrowDownload20Regular, { "data-ui-id": 'file-download-card-download-icon' });
91
- // Return _some_ available icon, as the real icon is beta-only.
92
- return React.createElement(Icon, { iconName: "EditBoxCancel", style: actionIconStyle });
93
- };
94
62
  const useLocaleStringsTrampoline = () => {
95
63
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
96
64
  return useLocale().strings.messageThread;
97
- return { downloadAttachment: '', attachmentCardGroupMessage: '' };
65
+ return { downloadAttachment: '', openAttachment: '', attachmentCardGroupMessage: '' };
66
+ };
67
+ /**
68
+ * @private
69
+ */
70
+ const getDefaultMenuActions = (locale, chatMessage) => {
71
+ var _a;
72
+ // if message is sent by a Teams user, we need to use a different icon ("open")
73
+ if ((_a = chatMessage === null || chatMessage === void 0 ? void 0 : chatMessage.senderId) === null || _a === void 0 ? void 0 : _a.includes('8:orgid:')) {
74
+ return [
75
+ Object.assign(Object.assign({}, defaultAttachmentMenuAction), { name: locale.openAttachment, icon: React.createElement(Icon, { iconName: "OpenAttachment" }) })
76
+ ];
77
+ }
78
+ // otherwise, use the default icon ("download")
79
+ return [
80
+ Object.assign(Object.assign({}, defaultAttachmentMenuAction), { name: locale.downloadAttachment })
81
+ ];
82
+ };
83
+ /**
84
+ * @beta
85
+ *
86
+ * The default menu action for downloading attachments. This action will open the attachment's URL in a new tab.
87
+ */
88
+ export const defaultAttachmentMenuAction = {
89
+ /**
90
+ *
91
+ * name is used for aria-label only when there's one button. For multiple buttons, it's used as a label.
92
+ * by default it's an unlocalized string when this is used as a imported constant,
93
+ * but you can overwrite it with your own localized string.
94
+ *
95
+ * i.e. defaultAttachmentMenuAction.name = localize('Download');
96
+ *
97
+ * when no action is provided, the UI library will overwrite this name
98
+ * with a localized string this string when it's used in the UI.
99
+ */
100
+ name: 'Download',
101
+ // this is the icon shown on the right of the attachment card
102
+ icon: React.createElement(Icon, { iconName: "DownloadAttachment", "data-ui-id": "attachment-download-card-download-icon" }),
103
+ // this is the action that runs when the icon is clicked
104
+ onClick: (attachment) => {
105
+ return new Promise((resolve) => {
106
+ window.open(attachment.url, '_blank', 'noopener,noreferrer');
107
+ resolve();
108
+ });
109
+ }
98
110
  };
99
111
  //# sourceMappingURL=AttachmentDownloadCards.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/AttachmentDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, Spinner, SpinnerSize, TooltipHost } from '@fluentui/react';\nimport React, { useCallback, useState } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { useLocale } from '../localization';\nimport { _AttachmentCard } from './AttachmentCard';\nimport { _AttachmentCardGroup } from './AttachmentCardGroup';\nimport { _formatString } from '@internal/acs-ui-common';\nimport { AttachmentMetadata, FileDownloadHandler } from '../types/Attachment';\nimport { Open20Regular } from '@fluentui/react-icons';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { ArrowDownload20Regular } from '@fluentui/react-icons';\n\n/**\n * Represents the type of attachment\n * @public\n */\nexport type ChatAttachmentType =\n | 'unknown'\n | 'image'\n | /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ 'file';\n\n/**\n * Strings of _AttachmentDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _AttachmentDownloadCardsStrings {\n /** Aria label to notify user when focus is on attachment download button. */\n downloadAttachment: string;\n attachmentCardGroupMessage: string;\n}\n\n/**\n * @internal\n */\nexport interface _AttachmentDownloadCardsProps {\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 attachment downloads.\n * If the function is not specified, the attachment'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 attachment download cards\n */\n strings?: _AttachmentDownloadCardsStrings;\n}\n\nconst attachmentDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _AttachmentDownloadCards = (props: _AttachmentDownloadCardsProps): JSX.Element => {\n const { userId, fileMetadata } = props;\n const [showSpinner, setShowSpinner] = useState(false);\n const localeStrings = useLocaleStringsTrampoline();\n\n const downloadAttachmentButtonString = useMemo(\n () => () => {\n return props.strings?.downloadAttachment ?? localeStrings.downloadAttachment;\n },\n [props.strings?.downloadAttachment, localeStrings.downloadAttachment]\n );\n\n const isShowDownloadIcon = useCallback((attachment: AttachmentMetadata): boolean => {\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n return attachment.payload?.teamsFileAttachment !== 'true';\n return true;\n }, []);\n\n const attachmentCardGroupDescription = useMemo(\n () => () => {\n const fileGroupLocaleString =\n props.strings?.attachmentCardGroupMessage ?? localeStrings.attachmentCardGroupMessage;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n return _formatString(fileGroupLocaleString, {\n attachmentCount: `${fileMetadata?.length ?? 0}`\n });\n return _formatString(fileGroupLocaleString, {\n attachmentCount: `${fileMetadata?.length ?? 0}`\n });\n },\n [props.strings?.attachmentCardGroupMessage, localeStrings.attachmentCardGroupMessage, 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 (!fileMetadata || fileMetadata.length === 0 || !fileMetadata) {\n return <></>;\n }\n\n return (\n <div style={attachmentDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_AttachmentCardGroup ariaLabel={attachmentCardGroupDescription()}>\n {fileMetadata &&\n fileMetadata.map((attachment) => (\n <TooltipHost content={downloadAttachmentButtonString()} key={attachment.name}>\n <_AttachmentCard\n attachmentName={attachment.name}\n key={attachment.name}\n attachmentExtension={attachment.extension}\n actionIcon={\n showSpinner ? (\n <Spinner size={SpinnerSize.medium} aria-live={'polite'} role={'status'} />\n ) : true && isShowDownloadIcon(attachment) ? (\n <DownloadIconTrampoline />\n ) : (\n <Open20Regular />\n )\n }\n actionHandler={() => fileDownloadHandler(userId, attachment)}\n />\n </TooltipHost>\n ))}\n </_AttachmentCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst DownloadIconTrampoline = (): JSX.Element => {\n // @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload)\n return <ArrowDownload20Regular data-ui-id={'file-download-card-download-icon'} />;\n // Return _some_ available icon, as the real icon is beta-only.\n return <Icon iconName=\"EditBoxCancel\" style={actionIconStyle} />;\n};\n\nconst useLocaleStringsTrampoline = (): _AttachmentDownloadCardsStrings => {\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n return useLocale().strings.messageThread;\n return { downloadAttachment: '', attachmentCardGroupMessage: '' };\n};\n"]}
1
+ {"version":3,"file":"AttachmentDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/AttachmentDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, TooltipHost } from '@fluentui/react';\nimport React, { useCallback } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { useLocale } from '../localization';\nimport { _AttachmentCard } from './AttachmentCard';\nimport { _AttachmentCardGroup } from './AttachmentCardGroup';\nimport { _formatString } from '@internal/acs-ui-common';\nimport { AttachmentMenuAction, AttachmentMetadata } from '../types/Attachment';\nimport { ChatMessage } from '../types';\n\n/**\n * Represents the type of attachment\n * @public\n */\nexport type ChatAttachmentType =\n | 'unknown'\n | 'image'\n | /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ 'file';\n\n/**\n * Strings of _AttachmentDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _AttachmentDownloadCardsStrings {\n /** Aria label to notify user when focus is on attachment download button. */\n downloadAttachment: string;\n /** Aria label to notify user when focus is on attachment open button. */\n openAttachment: string;\n attachmentCardGroupMessage: string;\n}\n\n/**\n * @internal\n */\nexport interface _AttachmentDownloadCardsProps {\n /**\n * A chat message metadata that includes attachment metadata\n */\n attachments?: AttachmentMetadata[];\n /**\n * A chat message metadata that includes attachment metadata\n */\n message?: ChatMessage;\n /**\n * Optional callback to handle attachment download\n */\n actionsForAttachment?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[];\n /**\n * Optional callback that runs if downloadHandler returns an error.\n */\n onActionHandlerFailed?: (errMsg: string) => void;\n /**\n * Optional aria label strings for attachment download cards\n */\n strings?: _AttachmentDownloadCardsStrings;\n}\n\nconst attachmentDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\n/**\n * @internal\n */\nexport const _AttachmentDownloadCards = (props: _AttachmentDownloadCardsProps): JSX.Element => {\n const { attachments, message } = props;\n const localeStrings = useLocaleStringsTrampoline();\n\n const getMenuActions = useCallback(\n (\n attachment: AttachmentMetadata,\n localeStrings: _AttachmentDownloadCardsStrings,\n message?: ChatMessage,\n action?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[]\n ): AttachmentMenuAction[] => {\n const defaultMenuActions = getDefaultMenuActions(localeStrings, message);\n try {\n const actions = action?.(attachment, message);\n if (actions && actions.length > 0) {\n return actions;\n } else {\n return defaultMenuActions;\n }\n } catch (error) {\n return defaultMenuActions;\n }\n },\n []\n );\n\n const downloadAttachmentButtonString = useMemo(\n () => () => {\n return props.strings?.downloadAttachment ?? localeStrings.downloadAttachment;\n },\n [props.strings?.downloadAttachment, localeStrings.downloadAttachment]\n );\n\n const attachmentCardGroupDescription = useMemo(\n () => () => {\n const attachmentGroupLocaleString =\n props.strings?.attachmentCardGroupMessage ?? localeStrings.attachmentCardGroupMessage;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n return _formatString(attachmentGroupLocaleString, {\n attachmentCount: `${attachments?.length ?? 0}`\n });\n return _formatString(attachmentGroupLocaleString, {\n attachmentCount: `${attachments?.length ?? 0}`\n });\n },\n [props.strings?.attachmentCardGroupMessage, localeStrings.attachmentCardGroupMessage, attachments]\n );\n\n if (!attachments || attachments.length === 0 || !attachments) {\n return <></>;\n }\n\n return (\n <div style={attachmentDownloadCardsStyle} data-ui-id=\"attachment-download-card-group\">\n <_AttachmentCardGroup ariaLabel={attachmentCardGroupDescription()}>\n {attachments &&\n attachments.map((attachment) => (\n <TooltipHost content={downloadAttachmentButtonString()} key={attachment.name}>\n <_AttachmentCard\n attachment={attachment}\n key={attachment.id}\n menuActions={getMenuActions(attachment, localeStrings, message, props.actionsForAttachment)}\n onActionHandlerFailed={props.onActionHandlerFailed}\n />\n </TooltipHost>\n ))}\n </_AttachmentCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst useLocaleStringsTrampoline = (): _AttachmentDownloadCardsStrings => {\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n return useLocale().strings.messageThread;\n return { downloadAttachment: '', openAttachment: '', attachmentCardGroupMessage: '' };\n};\n\n/**\n * @private\n */\nconst getDefaultMenuActions = (\n locale: _AttachmentDownloadCardsStrings,\n chatMessage?: ChatMessage\n): AttachmentMenuAction[] => {\n // if message is sent by a Teams user, we need to use a different icon (\"open\")\n if (chatMessage?.senderId?.includes('8:orgid:')) {\n return [\n {\n ...defaultAttachmentMenuAction,\n name: locale.openAttachment,\n icon: <Icon iconName=\"OpenAttachment\" />\n }\n ];\n }\n // otherwise, use the default icon (\"download\")\n return [\n {\n ...defaultAttachmentMenuAction,\n name: locale.downloadAttachment\n }\n ];\n};\n\n/**\n * @beta\n *\n * The default menu action for downloading attachments. This action will open the attachment's URL in a new tab.\n */\nexport const defaultAttachmentMenuAction: AttachmentMenuAction = {\n /**\n *\n * name is used for aria-label only when there's one button. For multiple buttons, it's used as a label.\n * by default it's an unlocalized string when this is used as a imported constant,\n * but you can overwrite it with your own localized string.\n *\n * i.e. defaultAttachmentMenuAction.name = localize('Download');\n *\n * when no action is provided, the UI library will overwrite this name\n * with a localized string this string when it's used in the UI.\n */\n name: 'Download',\n // this is the icon shown on the right of the attachment card\n icon: <Icon iconName=\"DownloadAttachment\" data-ui-id=\"attachment-download-card-download-icon\" />,\n // this is the action that runs when the icon is clicked\n onClick: (attachment: AttachmentMetadata) => {\n return new Promise<void>((resolve) => {\n window.open((attachment as AttachmentMetadata).url, '_blank', 'noopener,noreferrer');\n resolve();\n });\n }\n};\n"]}
@@ -1,24 +1,57 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
  import { Icon, mergeStyles } from '@fluentui/react';
4
- import React from 'react';
4
+ import React, { useMemo } from 'react';
5
5
  import { _AttachmentCard } from './AttachmentCard';
6
6
  import { _AttachmentCardGroup } from './AttachmentCardGroup';
7
7
  import { extension } from './utils';
8
+ import { useLocaleAttachmentCardStringsTrampoline } from './utils/common';
8
9
  const actionIconStyle = { height: '1rem' };
9
10
  /**
10
11
  * @internal
11
12
  */
12
13
  export const _AttachmentUploadCards = (props) => {
14
+ var _a;
13
15
  const attachments = props.activeFileUploads;
16
+ const localeStrings = useLocaleAttachmentCardStringsTrampoline();
17
+ const removeFileButtonString = useMemo(() => () => {
18
+ var _a, _b;
19
+ return (_b = (_a = props.strings) === null || _a === void 0 ? void 0 : _a.removeAttachment) !== null && _b !== void 0 ? _b : localeStrings.removeAttachment;
20
+ }, [(_a = props.strings) === null || _a === void 0 ? void 0 : _a.removeAttachment, localeStrings.removeAttachment]);
14
21
  if (!attachments || attachments.length === 0) {
15
22
  return React.createElement(React.Fragment, null);
16
23
  }
17
24
  return (React.createElement(_AttachmentCardGroup, null, attachments &&
18
25
  attachments
19
26
  .filter((attachment) => !attachment.error)
20
- .map((attachment) => (React.createElement(_AttachmentCard, { attachmentName: attachment.filename, progress: attachment.progress, key: attachment.id, attachmentExtension: extension(attachment.filename), actionIcon: React.createElement(Icon, { iconName: "CancelFileUpload", className: mergeStyles(actionIconStyle) }), actionHandler: () => {
21
- props.onCancelFileUpload && props.onCancelFileUpload(attachment.id);
22
- }, strings: props.strings })))));
27
+ .map((attachment) => {
28
+ var _a, _b, _c, _d;
29
+ return (React.createElement(_AttachmentCard
30
+ // temp converter before upload is refactored
31
+ , {
32
+ // temp converter before upload is refactored
33
+ attachment: {
34
+ id: attachment.id,
35
+ name: attachment.filename,
36
+ extension: extension(attachment.filename),
37
+ progress: attachment.progress,
38
+ uploadStatus: attachment.error
39
+ ? {
40
+ message: (_a = attachment.error) === null || _a === void 0 ? void 0 : _a.message,
41
+ timestamp: (_b = attachment.error) === null || _b === void 0 ? void 0 : _b.timestamp
42
+ }
43
+ : undefined
44
+ }, progress: attachment.progress, key: attachment.id, menuActions: [
45
+ {
46
+ name: (_d = (_c = props.strings) === null || _c === void 0 ? void 0 : _c.removeAttachment) !== null && _d !== void 0 ? _d : 'Remove',
47
+ icon: (React.createElement("div", { "aria-label": removeFileButtonString() },
48
+ React.createElement(Icon, { iconName: "CancelAttachmentUpload", className: mergeStyles(actionIconStyle) }))),
49
+ onClick: () => {
50
+ props.onCancelFileUpload && props.onCancelFileUpload(attachment.id);
51
+ return Promise.resolve();
52
+ }
53
+ }
54
+ ], strings: props.strings }));
55
+ })));
23
56
  };
24
57
  //# sourceMappingURL=AttachmentUploadCards.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentUploadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/AttachmentUploadCards.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyEpC,MAAM,eAAe,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAA2B,EAAe,EAAE;IACjF,MAAM,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAE5C,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,yCAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,oBAAC,oBAAoB,QAClB,WAAW;QACV,WAAW;aACR,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;aACzC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CACnB,oBAAC,eAAe,IACd,cAAc,EAAE,UAAU,CAAC,QAAQ,EACnC,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAC7B,GAAG,EAAE,UAAU,CAAC,EAAE,EAClB,mBAAmB,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,EACnD,UAAU,EAAE,oBAAC,IAAI,IAAC,QAAQ,EAAC,kBAAkB,EAAC,SAAS,EAAE,WAAW,CAAC,eAAe,CAAC,GAAI,EACzF,aAAa,EAAE,GAAG,EAAE;gBAClB,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC,EACD,OAAO,EAAE,KAAK,CAAC,OAAO,GACtB,CACH,CAAC,CACe,CACxB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, mergeStyles } from '@fluentui/react';\nimport React from 'react';\nimport { _AttachmentCard } from './AttachmentCard';\nimport { _AttachmentCardGroup } from './AttachmentCardGroup';\nimport { extension } from './utils';\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\n\n/**\n * Attributes required for SendBox to show attachment uploads like name, progress etc.\n * @beta\n */\nexport interface ActiveFileUpload {\n /**\n * Unique identifier for the file upload.\n */\n id: string;\n\n /**\n * File name to be rendered for uploaded file.\n */\n filename: string;\n\n /**\n * A number between 0 and 1 indicating the progress of the upload.\n * This is unrelated to the `uploadComplete` property.\n * It is only used to show the progress of the upload.\n * Progress of 1 doesn't mark the upload as complete, set the `uploadComplete`\n * property to true to mark the upload as complete.\n */\n progress: number;\n\n /**\n * Error to be displayed to the user if the upload fails.\n */\n error?: SendBoxErrorBarError;\n\n /**\n * `true` means that the upload is completed.\n * This is independent of the upload `progress`.\n */\n uploadComplete?: boolean;\n}\n\n/**\n * Strings of _AttachmentUploadCards that can be overridden.\n *\n * @internal\n */\nexport interface _AttachmentUploadCardsStrings {\n /** Aria label to notify user when focus is on cancel attachment upload button. */\n removeAttachment: string;\n /** Aria label to notify user attachment uploading starts. */\n uploading: string;\n /** Aria label to notify user attachment is uploaded. */\n uploadCompleted: string;\n}\n\n/**\n * @internal\n */\nexport interface FileUploadCardsProps {\n /**\n * Optional array of active attachment uploads where each object has attibutes\n * of a attachment upload like name, progress, errormessage etc.\n */\n activeFileUploads?: ActiveFileUpload[];\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n */\n onCancelFileUpload?: (attachmentId: string) => void;\n /**\n * Optional arialabel strings for attachment upload cards\n */\n strings?: _AttachmentUploadCardsStrings;\n}\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _AttachmentUploadCards = (props: FileUploadCardsProps): JSX.Element => {\n const attachments = props.activeFileUploads;\n\n if (!attachments || attachments.length === 0) {\n return <></>;\n }\n\n return (\n <_AttachmentCardGroup>\n {attachments &&\n attachments\n .filter((attachment) => !attachment.error)\n .map((attachment) => (\n <_AttachmentCard\n attachmentName={attachment.filename}\n progress={attachment.progress}\n key={attachment.id}\n attachmentExtension={extension(attachment.filename)}\n actionIcon={<Icon iconName=\"CancelFileUpload\" className={mergeStyles(actionIconStyle)} />}\n actionHandler={() => {\n props.onCancelFileUpload && props.onCancelFileUpload(attachment.id);\n }}\n strings={props.strings}\n />\n ))}\n </_AttachmentCardGroup>\n );\n};\n"]}
1
+ {"version":3,"file":"AttachmentUploadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/AttachmentUploadCards.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,wCAAwC,EAAE,MAAM,gBAAgB,CAAC;AAwE1E,MAAM,eAAe,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAA2B,EAAe,EAAE;;IACjF,MAAM,WAAW,GAAG,KAAK,CAAC,iBAAiB,CAAC;IAC5C,MAAM,aAAa,GAAG,wCAAwC,EAAE,CAAC;IACjE,MAAM,sBAAsB,GAAG,OAAO,CACpC,GAAG,EAAE,CAAC,GAAG,EAAE;;QACT,OAAO,MAAA,MAAA,KAAK,CAAC,OAAO,0CAAE,gBAAgB,mCAAI,aAAa,CAAC,gBAAgB,CAAC;IAC3E,CAAC,EACD,CAAC,MAAA,KAAK,CAAC,OAAO,0CAAE,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAClE,CAAC;IAEF,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,yCAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,oBAAC,oBAAoB,QAClB,WAAW;QACV,WAAW;aACR,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;aACzC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;;YAAC,OAAA,CACnB,oBAAC,eAAe;YACd,6CAA6C;;gBAA7C,6CAA6C;gBAC7C,UAAU,EAAE;oBACV,EAAE,EAAE,UAAU,CAAC,EAAE;oBACjB,IAAI,EAAE,UAAU,CAAC,QAAQ;oBACzB,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC;oBACzC,QAAQ,EAAE,UAAU,CAAC,QAAQ;oBAC7B,YAAY,EAAE,UAAU,CAAC,KAAK;wBAC5B,CAAC,CAAC;4BACE,OAAO,EAAE,MAAA,UAAU,CAAC,KAAK,0CAAE,OAAO;4BAClC,SAAS,EAAE,MAAA,UAAU,CAAC,KAAK,0CAAE,SAAS;yBACvC;wBACH,CAAC,CAAC,SAAS;iBACd,EACD,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAC7B,GAAG,EAAE,UAAU,CAAC,EAAE,EAClB,WAAW,EAAE;oBACX;wBACE,IAAI,EAAE,MAAA,MAAA,KAAK,CAAC,OAAO,0CAAE,gBAAgB,mCAAI,QAAQ;wBACjD,IAAI,EAAE,CACJ,2CAAiB,sBAAsB,EAAE;4BACvC,oBAAC,IAAI,IAAC,QAAQ,EAAC,wBAAwB,EAAC,SAAS,EAAE,WAAW,CAAC,eAAe,CAAC,GAAI,CAC/E,CACP;wBACD,OAAO,EAAE,GAAG,EAAE;4BACZ,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;4BACpE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;wBAC3B,CAAC;qBACF;iBACF,EACD,OAAO,EAAE,KAAK,CAAC,OAAO,GACtB,CACH,CAAA;SAAA,CAAC,CACe,CACxB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Icon, mergeStyles } from '@fluentui/react';\nimport React, { useMemo } from 'react';\nimport { _AttachmentCard } from './AttachmentCard';\nimport { _AttachmentCardGroup } from './AttachmentCardGroup';\nimport { extension } from './utils';\nimport { SendBoxErrorBarError } from './SendBoxErrorBar';\nimport { useLocaleAttachmentCardStringsTrampoline } from './utils/common';\n\n/**\n * Attributes required for SendBox to show attachment uploads like name, progress etc.\n * @beta\n */\nexport interface ActiveFileUpload {\n /**\n * Unique identifier for the file upload.\n */\n id: string;\n\n /**\n * File name to be rendered for uploaded file.\n */\n filename: string;\n\n /**\n * A number between 0 and 1 indicating the progress of the upload.\n * This is unrelated to the `uploadComplete` property.\n * It is only used to show the progress of the upload.\n * Progress of 1 doesn't mark the upload as complete, set the `uploadComplete`\n * property to true to mark the upload as complete.\n */\n progress: number;\n\n /**\n * Error to be displayed to the user if the upload fails.\n */\n error?: SendBoxErrorBarError;\n\n /**\n * `true` means that the upload is completed.\n * This is independent of the upload `progress`.\n */\n uploadComplete?: boolean;\n}\n\n/**\n * Strings of _AttachmentUploadCards that can be overridden.\n *\n * @internal\n */\nexport interface _AttachmentUploadCardsStrings {\n /** Aria label to notify user when focus is on cancel attachment upload button. */\n removeAttachment: string;\n /** Aria label to notify user attachment uploading starts. */\n uploading: string;\n /** Aria label to notify user attachment is uploaded. */\n uploadCompleted: string;\n}\n\n/**\n * @internal\n */\nexport interface FileUploadCardsProps {\n /**\n * Optional array of active attachment uploads where each object has attibutes\n * of a attachment upload like name, progress, errormessage etc.\n */\n activeFileUploads?: ActiveFileUpload[];\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n */\n onCancelFileUpload?: (attachmentId: string) => void;\n /**\n * Optional arialabel strings for attachment upload cards\n */\n strings?: _AttachmentUploadCardsStrings;\n}\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _AttachmentUploadCards = (props: FileUploadCardsProps): JSX.Element => {\n const attachments = props.activeFileUploads;\n const localeStrings = useLocaleAttachmentCardStringsTrampoline();\n const removeFileButtonString = useMemo(\n () => () => {\n return props.strings?.removeAttachment ?? localeStrings.removeAttachment;\n },\n [props.strings?.removeAttachment, localeStrings.removeAttachment]\n );\n\n if (!attachments || attachments.length === 0) {\n return <></>;\n }\n\n return (\n <_AttachmentCardGroup>\n {attachments &&\n attachments\n .filter((attachment) => !attachment.error)\n .map((attachment) => (\n <_AttachmentCard\n // temp converter before upload is refactored\n attachment={{\n id: attachment.id,\n name: attachment.filename,\n extension: extension(attachment.filename),\n progress: attachment.progress,\n uploadStatus: attachment.error\n ? {\n message: attachment.error?.message,\n timestamp: attachment.error?.timestamp\n }\n : undefined\n }}\n progress={attachment.progress}\n key={attachment.id}\n menuActions={[\n {\n name: props.strings?.removeAttachment ?? 'Remove',\n icon: (\n <div aria-label={removeFileButtonString()}>\n <Icon iconName=\"CancelAttachmentUpload\" className={mergeStyles(actionIconStyle)} />\n </div>\n ),\n onClick: () => {\n props.onCancelFileUpload && props.onCancelFileUpload(attachment.id);\n return Promise.resolve();\n }\n }\n ]}\n strings={props.strings}\n />\n ))}\n </_AttachmentCardGroup>\n );\n};\n"]}
@@ -3,7 +3,7 @@ import { MessageStatus } from "../../../../acs-ui-common/src";
3
3
  import { MessageProps, MessageRenderer, MessageThreadStyles, _ChatMessageProps } from '../MessageThread';
4
4
  import { ChatMessage, OnRenderAvatarCallback } from '../../types';
5
5
  import { BlockedMessage } from '../../types';
6
- import { FileDownloadHandler } from '../../types/Attachment';
6
+ import { AttachmentMenuAction, AttachmentMetadata } from '../../types/Attachment';
7
7
  import { MentionOptions } from '../MentionPopover';
8
8
  import { MessageStatusIndicatorProps } from '../MessageStatusIndicator';
9
9
  import { InlineImageOptions } from './ChatMessageContent';
@@ -26,15 +26,18 @@ export type ChatMessageComponentWrapperProps = _ChatMessageProps & {
26
26
  showMessageStatus?: boolean;
27
27
  participantCount?: number;
28
28
  readCount?: number;
29
- onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;
30
29
  onActionButtonClick: (message: ChatMessage, setMessageReadBy: (readBy: {
31
30
  id: string;
32
31
  displayName: string;
33
32
  }[]) => void) => void;
34
- fileDownloadHandler?: FileDownloadHandler;
35
33
  onDisplayDateTimeString?: (messageDate: Date) => string;
36
34
  inlineImageOptions?: InlineImageOptions;
37
35
  mentionOptions?: MentionOptions;
36
+ onRenderAttachmentDownloads?: (userId: string, message: ChatMessage) => JSX.Element;
37
+ /**
38
+ * Optional callback to define custom actions for attachments.
39
+ */
40
+ actionsForAttachment?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[];
38
41
  };
39
42
  /**
40
43
  * The wrapper component to display different types of chat message.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessageComponentWrapper.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentWrapper.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { MessageStatus } from '@internal/acs-ui-common';\nimport React, { useMemo } from 'react';\nimport { MessageProps, MessageRenderer, MessageThreadStyles, _ChatMessageProps } from '../MessageThread';\nimport { ChatMessage, OnRenderAvatarCallback } from '../../types';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { FileDownloadHandler } from '../../types/Attachment';\n/* @conditional-compile-remove(mention) */\nimport { MentionOptions } from '../MentionPopover';\nimport { MessageStatusIndicatorProps } from '../MessageStatusIndicator';\nimport { FluentChatMessageComponentWrapperProps } from './MessageComponents/FluentChatMessageComponent';\nimport { DefaultSystemMessage } from './DefaultSystemMessage';\nimport { InlineImageOptions } from './ChatMessageContent';\nimport { FluentChatMyMessageComponent } from './MyMessageComponents/FluentChatMyMessageComponent';\nimport { FluentChatMessageComponent } from './MessageComponents/FluentChatMessageComponent';\n\n/**\n * Props for {@link ChatMessageComponentWrapper}\n *\n * @private\n */\nexport type ChatMessageComponentWrapperProps = _ChatMessageProps & {\n /**\n * UserId of the current user.\n */\n userId: string;\n styles: MessageThreadStyles | undefined;\n shouldOverlapAvatarAndMessage: boolean;\n onRenderMessageStatus: ((messageStatusIndicatorProps: MessageStatusIndicatorProps) => JSX.Element | null) | undefined;\n defaultStatusRenderer: (\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage,\n participantCount: number,\n readCount: number,\n status?: MessageStatus\n ) => JSX.Element;\n onRenderMessage?: (messageProps: MessageProps, messageRenderer?: MessageRenderer) => JSX.Element;\n onRenderAvatar?: OnRenderAvatarCallback;\n showMessageStatus?: boolean;\n participantCount?: number;\n readCount?: number;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (\n readBy: {\n id: string;\n displayName: string;\n }[]\n ) => void\n ) => void;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n fileDownloadHandler?: FileDownloadHandler;\n /* @conditional-compile-remove(date-time-customization) */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n inlineImageOptions?: InlineImageOptions;\n /* @conditional-compile-remove(mention) */\n mentionOptions?: MentionOptions;\n};\n\n/**\n * The wrapper component to display different types of chat message.\n *\n * @private\n */\nexport const ChatMessageComponentWrapper = (props: ChatMessageComponentWrapperProps): JSX.Element => {\n const { message, styles, onRenderMessage, key: messageKey } = props;\n\n const systemMessageStyle = useMemo(() => {\n return {\n paddingTop: '0.5rem'\n };\n }, []);\n\n const customMessageStyle = useMemo(() => {\n return { paddingTop: '1rem', paddingBottom: '0.25rem' };\n }, []);\n\n /* @conditional-compile-remove(data-loss-prevention) */\n // Similar logic as switch statement case 'chat', if statement for conditional compile (merge logic to switch case when stabilize)\n if (message.messageType === 'blocked') {\n const myChatMessageStyle =\n message.status === 'failed'\n ? styles?.failedMyChatMessageContainer ?? styles?.myChatMessageContainer\n : styles?.myChatMessageContainer;\n const blockedMessageStyle = styles?.blockedMessageContainer;\n const messageContainerStyle = message.mine ? myChatMessageStyle : blockedMessageStyle;\n return fluentChatComponent({ ...props, message: message, messageContainerStyle: messageContainerStyle });\n }\n\n switch (message.messageType) {\n case 'chat': {\n const myChatMessageStyle =\n message.status === 'failed'\n ? styles?.failedMyChatMessageContainer ?? styles?.myChatMessageContainer\n : styles?.myChatMessageContainer;\n const chatMessageStyle = styles?.chatMessageContainer;\n const messageContainerStyle = message.mine ? myChatMessageStyle : chatMessageStyle;\n return fluentChatComponent({ ...props, message: message, messageContainerStyle: messageContainerStyle });\n }\n\n case 'system': {\n const messageContainerStyle = styles?.systemMessageContainer;\n const systemMessageComponent =\n onRenderMessage === undefined ? (\n <DefaultSystemMessage {...props} />\n ) : (\n onRenderMessage({ ...props, messageContainerStyle }, (props) => <DefaultSystemMessage {...props} />)\n );\n return (\n <div key={messageKey} style={systemMessageStyle}>\n {systemMessageComponent}\n </div>\n );\n }\n\n default: {\n // We do not handle custom type message by default, users can handle custom type by using onRenderMessage function.\n const customMessageComponent = onRenderMessage === undefined ? <></> : onRenderMessage({ ...props });\n return (\n <div key={messageKey} style={customMessageStyle}>\n {customMessageComponent}\n </div>\n );\n }\n }\n};\n\nconst fluentChatComponent = (props: FluentChatMessageComponentWrapperProps): JSX.Element => {\n if (props.message.mine === true) {\n return <FluentChatMyMessageComponent {...props} />;\n } else {\n return <FluentChatMessageComponent {...props} />;\n }\n};\n"]}
1
+ {"version":3,"file":"ChatMessageComponentWrapper.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentWrapper.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { MessageStatus } from '@internal/acs-ui-common';\nimport React, { useMemo } from 'react';\nimport { MessageProps, MessageRenderer, MessageThreadStyles, _ChatMessageProps } from '../MessageThread';\nimport { ChatMessage, OnRenderAvatarCallback } from '../../types';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMenuAction, AttachmentMetadata } from '../../types/Attachment';\n/* @conditional-compile-remove(mention) */\nimport { MentionOptions } from '../MentionPopover';\nimport { MessageStatusIndicatorProps } from '../MessageStatusIndicator';\nimport { FluentChatMessageComponentWrapperProps } from './MessageComponents/FluentChatMessageComponent';\nimport { DefaultSystemMessage } from './DefaultSystemMessage';\nimport { InlineImageOptions } from './ChatMessageContent';\nimport { FluentChatMyMessageComponent } from './MyMessageComponents/FluentChatMyMessageComponent';\nimport { FluentChatMessageComponent } from './MessageComponents/FluentChatMessageComponent';\n\n/**\n * Props for {@link ChatMessageComponentWrapper}\n *\n * @private\n */\nexport type ChatMessageComponentWrapperProps = _ChatMessageProps & {\n /**\n * UserId of the current user.\n */\n userId: string;\n styles: MessageThreadStyles | undefined;\n shouldOverlapAvatarAndMessage: boolean;\n onRenderMessageStatus: ((messageStatusIndicatorProps: MessageStatusIndicatorProps) => JSX.Element | null) | undefined;\n defaultStatusRenderer: (\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage,\n participantCount: number,\n readCount: number,\n status?: MessageStatus\n ) => JSX.Element;\n onRenderMessage?: (messageProps: MessageProps, messageRenderer?: MessageRenderer) => JSX.Element;\n onRenderAvatar?: OnRenderAvatarCallback;\n showMessageStatus?: boolean;\n participantCount?: number;\n readCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (\n readBy: {\n id: string;\n displayName: string;\n }[]\n ) => void\n ) => void;\n /* @conditional-compile-remove(date-time-customization) */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n inlineImageOptions?: InlineImageOptions;\n /* @conditional-compile-remove(mention) */\n mentionOptions?: MentionOptions;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to define custom actions for attachments.\n */\n actionsForAttachment?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[];\n};\n\n/**\n * The wrapper component to display different types of chat message.\n *\n * @private\n */\nexport const ChatMessageComponentWrapper = (props: ChatMessageComponentWrapperProps): JSX.Element => {\n const { message, styles, onRenderMessage, key: messageKey } = props;\n\n const systemMessageStyle = useMemo(() => {\n return {\n paddingTop: '0.5rem'\n };\n }, []);\n\n const customMessageStyle = useMemo(() => {\n return { paddingTop: '1rem', paddingBottom: '0.25rem' };\n }, []);\n\n /* @conditional-compile-remove(data-loss-prevention) */\n // Similar logic as switch statement case 'chat', if statement for conditional compile (merge logic to switch case when stabilize)\n if (message.messageType === 'blocked') {\n const myChatMessageStyle =\n message.status === 'failed'\n ? styles?.failedMyChatMessageContainer ?? styles?.myChatMessageContainer\n : styles?.myChatMessageContainer;\n const blockedMessageStyle = styles?.blockedMessageContainer;\n const messageContainerStyle = message.mine ? myChatMessageStyle : blockedMessageStyle;\n return fluentChatComponent({ ...props, message: message, messageContainerStyle: messageContainerStyle });\n }\n\n switch (message.messageType) {\n case 'chat': {\n const myChatMessageStyle =\n message.status === 'failed'\n ? styles?.failedMyChatMessageContainer ?? styles?.myChatMessageContainer\n : styles?.myChatMessageContainer;\n const chatMessageStyle = styles?.chatMessageContainer;\n const messageContainerStyle = message.mine ? myChatMessageStyle : chatMessageStyle;\n return fluentChatComponent({ ...props, message: message, messageContainerStyle: messageContainerStyle });\n }\n\n case 'system': {\n const messageContainerStyle = styles?.systemMessageContainer;\n const systemMessageComponent =\n onRenderMessage === undefined ? (\n <DefaultSystemMessage {...props} />\n ) : (\n onRenderMessage({ ...props, messageContainerStyle }, (props) => <DefaultSystemMessage {...props} />)\n );\n return (\n <div key={messageKey} style={systemMessageStyle}>\n {systemMessageComponent}\n </div>\n );\n }\n\n default: {\n // We do not handle custom type message by default, users can handle custom type by using onRenderMessage function.\n const customMessageComponent = onRenderMessage === undefined ? <></> : onRenderMessage({ ...props });\n return (\n <div key={messageKey} style={customMessageStyle}>\n {customMessageComponent}\n </div>\n );\n }\n }\n};\n\nconst fluentChatComponent = (props: FluentChatMessageComponentWrapperProps): JSX.Element => {\n if (props.message.mine === true) {\n return <FluentChatMyMessageComponent {...props} />;\n } else {\n return <FluentChatMessageComponent {...props} />;\n }\n};\n"]}
@@ -4,7 +4,7 @@ import { ChatMessage } from '../../../types/ChatMessage';
4
4
  import { BlockedMessage } from '../../../types/ChatMessage';
5
5
  import { MessageThreadStrings } from '../../MessageThread';
6
6
  import { ComponentSlotStyle } from '../../../types';
7
- import { FileDownloadHandler } from '../../../types/Attachment';
7
+ import { AttachmentMenuAction, AttachmentMetadata } from '../../../types';
8
8
  import { MentionDisplayOptions } from '../../MentionPopover';
9
9
  type ChatMessageComponentAsMessageBubbleProps = {
10
10
  message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;
@@ -17,13 +17,13 @@ type ChatMessageComponentAsMessageBubbleProps = {
17
17
  */
18
18
  shouldOverlapAvatarAndMessage: boolean;
19
19
  /**
20
- * Optional callback to render uploaded files in the message component.
20
+ * Optional callback to render message attachments in the message component.
21
21
  */
22
- onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;
22
+ onRenderAttachmentDownloads?: (userId: string, message: ChatMessage) => JSX.Element;
23
23
  /**
24
- * Optional function called when someone clicks on the file download icon.
24
+ * Optional callback to define custom actions for attachments.
25
25
  */
26
- fileDownloadHandler?: FileDownloadHandler;
26
+ actionsForAttachment?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[];
27
27
  /**
28
28
  * Optional function to provide customized date format.
29
29
  * @beta
@@ -18,9 +18,9 @@ const MessageBubble = (props) => {
18
18
  const locale = useLocale();
19
19
  const { userId, message, showDate, messageContainerStyle, strings,
20
20
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
21
- fileDownloadHandler, inlineImageOptions, shouldOverlapAvatarAndMessage,
21
+ onRenderAttachmentDownloads, inlineImageOptions, shouldOverlapAvatarAndMessage,
22
22
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
23
- onRenderFileDownloads,
23
+ actionsForAttachment,
24
24
  /* @conditional-compile-remove(mention) */
25
25
  mentionDisplayOptions, onDisplayDateTimeString } = props;
26
26
  const formattedTimestamp = useMemo(() => {
@@ -37,18 +37,18 @@ const MessageBubble = (props) => {
37
37
  }, [strings.editedTag, theme, message]);
38
38
  const getContent = useCallback(() => {
39
39
  return getMessageBubbleContent(message, strings, userId, inlineImageOptions,
40
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
41
- onRenderFileDownloads,
42
40
  /* @conditional-compile-remove(mention) */
43
41
  mentionDisplayOptions,
44
42
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
45
- fileDownloadHandler);
43
+ onRenderAttachmentDownloads,
44
+ /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
45
+ actionsForAttachment);
46
46
  }, [
47
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ fileDownloadHandler,
47
+ /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ actionsForAttachment,
48
48
  inlineImageOptions,
49
49
  /* @conditional-compile-remove(mention) */ mentionDisplayOptions,
50
50
  message,
51
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ onRenderFileDownloads,
51
+ /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ onRenderAttachmentDownloads,
52
52
  strings,
53
53
  userId
54
54
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Text, mergeStyles } from '@fluentui/react';\nimport { ChatMessage as FluentChatMessage } from '@fluentui-contrib/react-chat';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useMemo } from 'react';\nimport { chatMessageDateStyle, chatMessageAuthorStyle } from '../../styles/ChatMessageComponent.styles';\nimport { useIdentifiers } from '../../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../../theming';\nimport { InlineImageOptions } from '../ChatMessageContent';\nimport { ChatMessage } from '../../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../../types/ChatMessage';\nimport { MessageThreadStrings } from '../../MessageThread';\nimport { ComponentSlotStyle } from '../../../types';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { FileDownloadHandler } from '../../../types/Attachment';\nimport { _AttachmentDownloadCards } from '../../AttachmentDownloadCards';\nimport { useLocale } from '../../../localization';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions } from '../../MentionPopover';\nimport { createStyleFromV8Style } from '../../styles/v8StyleShim';\nimport { mergeClasses } from '@fluentui/react-components';\nimport { useChatMessageStyles, useChatMessageCommonStyles } from '../../styles/MessageThread.styles';\nimport {\n generateCustomizedTimestamp,\n generateDefaultTimestamp,\n getMessageBubbleContent,\n getMessageEditedDetails\n} from '../../utils/ChatMessageComponentUtils';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n messageContainerStyle?: ComponentSlotStyle;\n showDate?: boolean;\n strings: MessageThreadStrings;\n userId: string;\n /**\n * Whether to overlap avatar and message when the view is width constrained.\n */\n shouldOverlapAvatarAndMessage: boolean;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to display suggestions in the mention scenario.\n * @internal\n */\n mentionDisplayOptions?: MentionDisplayOptions;\n /**\n * Optional callback called when an inline image is clicked.\n * @beta\n */\n inlineImageOptions?: InlineImageOptions;\n};\n\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n showDate,\n messageContainerStyle,\n strings,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n fileDownloadHandler,\n inlineImageOptions,\n shouldOverlapAvatarAndMessage,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderFileDownloads,\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions,\n onDisplayDateTimeString\n } = props;\n\n const formattedTimestamp = useMemo(() => {\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn\n ? generateCustomizedTimestamp(message.createdOn, locale, onDisplayDateTimeString)\n : '';\n\n return customTimestamp || defaultTimeStamp;\n }, [locale, message.createdOn, onDisplayDateTimeString, showDate, strings]);\n\n const getMessageDetails = useCallback(() => {\n return getMessageEditedDetails(message, theme, strings.editedTag);\n }, [strings.editedTag, theme, message]);\n\n const getContent = useCallback(() => {\n return getMessageBubbleContent(\n message,\n strings,\n userId,\n inlineImageOptions,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderFileDownloads,\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n fileDownloadHandler\n );\n }, [\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ fileDownloadHandler,\n inlineImageOptions,\n /* @conditional-compile-remove(mention) */ mentionDisplayOptions,\n message,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ onRenderFileDownloads,\n strings,\n userId\n ]);\n\n const isBlockedMessage =\n false || /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked';\n const chatMessageCommonStyles = useChatMessageCommonStyles();\n\n const chatMessageStyles = useChatMessageStyles();\n const chatItemMessageContainerClassName = mergeClasses(\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n chatMessageStyles.body,\n // disable placeholder functionality for GA releases as it might confuse users\n chatMessageStyles.bodyWithPlaceholderImage,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n shouldOverlapAvatarAndMessage ? chatMessageStyles.avatarOverlap : chatMessageStyles.avatarNoOverlap,\n message.attached === 'top' || message.attached === false\n ? chatMessageStyles.bodyWithAvatar\n : chatMessageStyles.bodyWithoutAvatar,\n mergeStyles(messageContainerStyle)\n );\n\n const attached = message.attached === true ? 'center' : message.attached === 'bottom' ? 'bottom' : 'top';\n const chatMessage = (\n <>\n <div key={props.message.messageId}>\n <FluentChatMessage\n attached={attached}\n key={props.message.messageId}\n root={{\n className: chatMessageStyles.root,\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n tabIndex: -1,\n role: 'none'\n }}\n author={<Text className={chatMessageAuthorStyle}>{message.senderDisplayName}</Text>}\n body={{\n className: chatItemMessageContainerClassName,\n style: { ...createStyleFromV8Style(messageContainerStyle) }\n }}\n data-ui-id=\"chat-composite-message\"\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n >\n {getContent()}\n </FluentChatMessage>\n </div>\n </>\n );\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n"]}
1
+ {"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { Text, mergeStyles } from '@fluentui/react';\nimport { ChatMessage as FluentChatMessage } from '@fluentui-contrib/react-chat';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useMemo } from 'react';\nimport { chatMessageDateStyle, chatMessageAuthorStyle } from '../../styles/ChatMessageComponent.styles';\nimport { useIdentifiers } from '../../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../../theming';\nimport { InlineImageOptions } from '../ChatMessageContent';\nimport { ChatMessage } from '../../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../../types/ChatMessage';\nimport { MessageThreadStrings } from '../../MessageThread';\nimport { ComponentSlotStyle } from '../../../types';\n/* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMenuAction, AttachmentMetadata } from '../../../types';\nimport { _AttachmentDownloadCards } from '../../AttachmentDownloadCards';\nimport { useLocale } from '../../../localization';\n/* @conditional-compile-remove(mention) */\nimport { MentionDisplayOptions } from '../../MentionPopover';\nimport { createStyleFromV8Style } from '../../styles/v8StyleShim';\nimport { mergeClasses } from '@fluentui/react-components';\nimport { useChatMessageStyles, useChatMessageCommonStyles } from '../../styles/MessageThread.styles';\nimport {\n generateCustomizedTimestamp,\n generateDefaultTimestamp,\n getMessageBubbleContent,\n getMessageEditedDetails\n} from '../../utils/ChatMessageComponentUtils';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n messageContainerStyle?: ComponentSlotStyle;\n showDate?: boolean;\n strings: MessageThreadStrings;\n userId: string;\n /**\n * Whether to overlap avatar and message when the view is width constrained.\n */\n shouldOverlapAvatarAndMessage: boolean;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to render message attachments in the message component.\n */\n onRenderAttachmentDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to define custom actions for attachments.\n */\n actionsForAttachment?: (attachment: AttachmentMetadata, message?: ChatMessage) => AttachmentMenuAction[];\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n /* @conditional-compile-remove(mention) */\n /**\n * Optional props needed to display suggestions in the mention scenario.\n * @internal\n */\n mentionDisplayOptions?: MentionDisplayOptions;\n /**\n * Optional callback called when an inline image is clicked.\n * @beta\n */\n inlineImageOptions?: InlineImageOptions;\n};\n\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n showDate,\n messageContainerStyle,\n strings,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentDownloads,\n inlineImageOptions,\n shouldOverlapAvatarAndMessage,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n actionsForAttachment,\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions,\n onDisplayDateTimeString\n } = props;\n\n const formattedTimestamp = useMemo(() => {\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn\n ? generateCustomizedTimestamp(message.createdOn, locale, onDisplayDateTimeString)\n : '';\n\n return customTimestamp || defaultTimeStamp;\n }, [locale, message.createdOn, onDisplayDateTimeString, showDate, strings]);\n\n const getMessageDetails = useCallback(() => {\n return getMessageEditedDetails(message, theme, strings.editedTag);\n }, [strings.editedTag, theme, message]);\n\n const getContent = useCallback(() => {\n return getMessageBubbleContent(\n message,\n strings,\n userId,\n inlineImageOptions,\n /* @conditional-compile-remove(mention) */\n mentionDisplayOptions,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentDownloads,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */\n actionsForAttachment\n );\n }, [\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ actionsForAttachment,\n inlineImageOptions,\n /* @conditional-compile-remove(mention) */ mentionDisplayOptions,\n message,\n /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ onRenderAttachmentDownloads,\n strings,\n userId\n ]);\n\n const isBlockedMessage =\n false || /* @conditional-compile-remove(data-loss-prevention) */ message.messageType === 'blocked';\n const chatMessageCommonStyles = useChatMessageCommonStyles();\n\n const chatMessageStyles = useChatMessageStyles();\n const chatItemMessageContainerClassName = mergeClasses(\n // messageContainerStyle used in className and style prop as style prop can't handle CSS selectors\n chatMessageStyles.body,\n // disable placeholder functionality for GA releases as it might confuse users\n chatMessageStyles.bodyWithPlaceholderImage,\n isBlockedMessage\n ? chatMessageCommonStyles.blocked\n : props.message.status === 'failed'\n ? chatMessageCommonStyles.failed\n : undefined,\n shouldOverlapAvatarAndMessage ? chatMessageStyles.avatarOverlap : chatMessageStyles.avatarNoOverlap,\n message.attached === 'top' || message.attached === false\n ? chatMessageStyles.bodyWithAvatar\n : chatMessageStyles.bodyWithoutAvatar,\n mergeStyles(messageContainerStyle)\n );\n\n const attached = message.attached === true ? 'center' : message.attached === 'bottom' ? 'bottom' : 'top';\n const chatMessage = (\n <>\n <div key={props.message.messageId}>\n <FluentChatMessage\n attached={attached}\n key={props.message.messageId}\n root={{\n className: chatMessageStyles.root,\n // make body not focusable to remove repetitions from narrators.\n // inner components are already focusable\n tabIndex: -1,\n role: 'none'\n }}\n author={<Text className={chatMessageAuthorStyle}>{message.senderDisplayName}</Text>}\n body={{\n className: chatItemMessageContainerClassName,\n style: { ...createStyleFromV8Style(messageContainerStyle) }\n }}\n data-ui-id=\"chat-composite-message\"\n timestamp={\n <Text className={chatMessageDateStyle} data-ui-id={ids.messageTimestamp}>\n {formattedTimestamp}\n </Text>\n }\n details={getMessageDetails()}\n >\n {getContent()}\n </FluentChatMessage>\n </div>\n </>\n );\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n"]}
@@ -21,19 +21,17 @@ export const FluentChatMessageComponent = (props) => {
21
21
  /* @conditional-compile-remove(date-time-customization) */
22
22
  onDisplayDateTimeString, inlineImageOptions,
23
23
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
24
- fileDownloadHandler, userId,
24
+ actionsForAttachment, userId,
25
25
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
26
- onRenderFileDownloads,
26
+ onRenderAttachmentDownloads,
27
27
  /* @conditional-compile-remove(mention) */
28
28
  mentionOptions } = props;
29
29
  const chatMessageRenderStyles = useChatMessageRenderStyles();
30
- const onRenderFileDownloadsMemo = useMemo(() => {
31
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
32
- return onRenderFileDownloads;
30
+ /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
31
+ const onRenderAttachmentDownloadsMemo = useMemo(() => {
32
+ return onRenderAttachmentDownloads;
33
33
  return undefined;
34
- }, [
35
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */ onRenderFileDownloads
36
- ]);
34
+ }, [onRenderAttachmentDownloads]);
37
35
  // To rerender the defaultChatMessageRenderer if app running across days(every new day chat time stamp
38
36
  // needs to be regenerated), the dependency on "new Date().toDateString()"" is added.
39
37
  const defaultChatMessageRenderer = useCallback((messageProps) => {
@@ -41,30 +39,27 @@ export const FluentChatMessageComponent = (props) => {
41
39
  /* @conditional-compile-remove(data-loss-prevention) */ messageProps.message.messageType === 'blocked') {
42
40
  return (React.createElement(ChatMessageComponentAsMessageBubble, Object.assign({}, messageProps, {
43
41
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
44
- onRenderFileDownloads: onRenderFileDownloadsMemo,
45
- /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
46
- strings: messageProps.strings, message: messageProps.message, userId: userId, shouldOverlapAvatarAndMessage: shouldOverlapAvatarAndMessage,
42
+ onRenderAttachmentDownloads: onRenderAttachmentDownloadsMemo, strings: messageProps.strings, message: messageProps.message, userId: userId, shouldOverlapAvatarAndMessage: shouldOverlapAvatarAndMessage,
47
43
  /* @conditional-compile-remove(date-time-customization) */
48
44
  onDisplayDateTimeString: onDisplayDateTimeString, inlineImageOptions: inlineImageOptions,
49
45
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
50
- fileDownloadHandler: fileDownloadHandler,
46
+ actionsForAttachment: actionsForAttachment,
51
47
  /* @conditional-compile-remove(mention) */
52
48
  mentionDisplayOptions: mentionOptions === null || mentionOptions === void 0 ? void 0 : mentionOptions.displayOptions })));
53
49
  }
54
50
  return React.createElement(React.Fragment, null);
55
51
  }, [
56
- onRenderFileDownloadsMemo,
57
- shouldOverlapAvatarAndMessage,
52
+ /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
53
+ onRenderAttachmentDownloadsMemo,
58
54
  userId,
55
+ shouldOverlapAvatarAndMessage,
59
56
  /* @conditional-compile-remove(date-time-customization) */
60
57
  onDisplayDateTimeString,
61
58
  inlineImageOptions,
62
59
  /* @conditional-compile-remove(attachment-download) @conditional-compile-remove(attachment-upload) */
63
- fileDownloadHandler,
60
+ actionsForAttachment,
64
61
  /* @conditional-compile-remove(mention) */
65
- mentionOptions,
66
- // eslint-disable-next-line react-hooks/exhaustive-deps
67
- new Date().toDateString()
62
+ mentionOptions === null || mentionOptions === void 0 ? void 0 : mentionOptions.displayOptions
68
63
  ]);
69
64
  const messageRenderer = useCallback((messageProps) => {
70
65
  return onRenderMessage === undefined