@azure/communication-react 1.19.0-alpha-202407310012 → 1.19.0-alpha-202408020014

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 (98) hide show
  1. package/dist/communication-react.d.ts +42 -33
  2. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-CsHqT8dY.js → ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js} +52 -33
  3. package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js.map +1 -0
  4. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-TGDmjXvl.js → RichTextSendBoxWrapper-8FsFMpKF.js} +3 -3
  5. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-TGDmjXvl.js.map → RichTextSendBoxWrapper-8FsFMpKF.js.map} +1 -1
  6. package/dist/dist-cjs/communication-react/{index-BBPqvw4B.js → index-D84PSTZV.js} +573 -198
  7. package/dist/dist-cjs/communication-react/index-D84PSTZV.js.map +1 -0
  8. package/dist/dist-cjs/communication-react/index.js +2 -2
  9. package/dist/dist-esm/acs-ui-common/src/constants.d.ts +5 -0
  10. package/dist/dist-esm/acs-ui-common/src/constants.js +6 -0
  11. package/dist/dist-esm/acs-ui-common/src/constants.js.map +1 -1
  12. package/dist/dist-esm/acs-ui-common/src/index.d.ts +1 -0
  13. package/dist/dist-esm/acs-ui-common/src/index.js +2 -0
  14. package/dist/dist-esm/acs-ui-common/src/index.js.map +1 -1
  15. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  16. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  17. package/dist/dist-esm/calling-stateful-client/src/BreakoutRoomsSubscriber.d.ts +1 -0
  18. package/dist/dist-esm/calling-stateful-client/src/BreakoutRoomsSubscriber.js +6 -0
  19. package/dist/dist-esm/calling-stateful-client/src/BreakoutRoomsSubscriber.js.map +1 -1
  20. package/dist/dist-esm/calling-stateful-client/src/CallClientState.d.ts +1 -0
  21. package/dist/dist-esm/calling-stateful-client/src/CallClientState.js.map +1 -1
  22. package/dist/dist-esm/calling-stateful-client/src/CallContext.d.ts +1 -0
  23. package/dist/dist-esm/calling-stateful-client/src/CallContext.js +9 -0
  24. package/dist/dist-esm/calling-stateful-client/src/CallContext.js.map +1 -1
  25. package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js +6 -1
  26. package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js.map +1 -1
  27. package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
  28. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  29. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.d.ts +3 -3
  30. package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.js.map +1 -1
  31. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBoxPicker.d.ts +3 -3
  32. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBoxPicker.js.map +1 -1
  33. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.d.ts +3 -3
  34. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js +53 -32
  35. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js.map +1 -1
  36. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.d.ts +3 -3
  37. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.js +2 -2
  38. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.js.map +1 -1
  39. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js +6 -6
  40. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js.map +1 -1
  41. package/dist/dist-esm/react-components/src/components/MessageThread.d.ts +18 -6
  42. package/dist/dist-esm/react-components/src/components/MessageThread.js +3 -3
  43. package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
  44. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +2 -2
  45. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +18 -34
  46. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
  47. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.d.ts +14 -0
  48. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.js +56 -0
  49. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.js.map +1 -0
  50. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.d.ts +1 -1
  51. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +10 -16
  52. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -1
  53. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +2 -2
  54. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +85 -8
  55. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
  56. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +2 -2
  57. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
  58. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.d.ts +16 -27
  59. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +33 -35
  60. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
  61. package/dist/dist-esm/react-components/src/components/index.d.ts +1 -1
  62. package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
  63. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.d.ts +34 -0
  64. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +121 -0
  65. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -1
  66. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +15 -13
  67. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +42 -32
  68. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -1
  69. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.d.ts +3 -0
  70. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +41 -0
  71. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
  72. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.d.ts +4 -0
  73. package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
  74. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js +19 -6
  75. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js.map +1 -1
  76. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.d.ts +1 -0
  77. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +6 -0
  78. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js.map +1 -1
  79. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.d.ts +4 -0
  80. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
  81. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.d.ts +1 -0
  82. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.js +6 -0
  83. package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.js.map +1 -1
  84. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +30 -17
  85. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
  86. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.d.ts +5 -5
  87. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js +61 -31
  88. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js.map +1 -1
  89. package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.d.ts +32 -2
  90. package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js +3 -3
  91. package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js.map +1 -1
  92. package/dist/dist-esm/react-composites/src/composites/common/constants.d.ts +5 -0
  93. package/dist/dist-esm/react-composites/src/composites/common/constants.js +6 -0
  94. package/dist/dist-esm/react-composites/src/composites/common/constants.js.map +1 -1
  95. package/dist/tsdoc-metadata.json +1 -1
  96. package/package.json +7 -7
  97. package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-CsHqT8dY.js.map +0 -1
  98. package/dist/dist-cjs/communication-react/index-BBPqvw4B.js.map +0 -1
@@ -16,12 +16,12 @@ var textareaCaretTs = require('textarea-caret-ts');
16
16
  var useDebounce = require('use-debounce');
17
17
  var reactFileTypeIcons = require('@fluentui/react-file-type-icons');
18
18
  var react$1 = require('@griffel/react');
19
+ var uuid = require('uuid');
19
20
  var roosterjsContentModelCore = require('roosterjs-content-model-core');
20
21
  var roosterjsContentModelDom = require('roosterjs-content-model-dom');
21
22
  var roosterjsContentModelPlugins = require('roosterjs-content-model-plugins');
22
23
  var roosterjsContentModelApi = require('roosterjs-content-model-api');
23
24
  var reactChat = require('@fluentui-contrib/react-chat');
24
- var uuid = require('uuid');
25
25
  var parse = require('html-react-parser');
26
26
  var Linkify = require('react-linkify');
27
27
  var DOMPurify = require('dompurify');
@@ -189,7 +189,7 @@ function getDefaultExportFromCjs (x) {
189
189
  // Copyright (c) Microsoft Corporation.
190
190
  // Licensed under the MIT License.
191
191
  // GENERATED FILE. DO NOT EDIT MANUALLY.
192
- var telemetryVersion = '1.19.0-alpha-202407310012';
192
+ var telemetryVersion = '1.19.0-alpha-202408020014';
193
193
 
194
194
 
195
195
  var telemetryVersion$1 = /*@__PURE__*/getDefaultExportFromCjs(telemetryVersion);
@@ -400,6 +400,19 @@ const removeImageTags = (event) => {
400
400
  });
401
401
  };
402
402
 
403
+ // Copyright (c) Microsoft Corporation.
404
+ // Licensed under the MIT License.
405
+ /**
406
+ * Default max listeners for use with {@link EventEmitter.setMaxListeners} function
407
+ * @internal
408
+ */
409
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
410
+ /**
411
+ * The key for the rich text editor inline image file name attribute
412
+ * @internal
413
+ */
414
+ const _IMAGE_ATTRIBUTE_INLINE_IMAGE_FILE_NAME_KEY = 'data-image-file-name';
415
+
403
416
  // Copyright (c) Microsoft Corporation.
404
417
  // Licensed under the MIT License.
405
418
  /**
@@ -1817,7 +1830,12 @@ const createDefaultChatHandlers = memoizeOne((chatClient, chatThreadClient) => {
1817
1830
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
1818
1831
  onDeleteImage: function (imageId) {
1819
1832
  return __awaiter$T(this, void 0, void 0, function* () {
1820
- yield chatThreadClient.deleteImage(imageId);
1833
+ try {
1834
+ yield chatThreadClient.deleteImage(imageId);
1835
+ }
1836
+ catch (e) {
1837
+ console.log(`Error deleting image message: ${e}`);
1838
+ }
1821
1839
  return;
1822
1840
  });
1823
1841
  },
@@ -5634,33 +5652,41 @@ const isAttachmentUploadCompleted = (attachmentsWithProgress) => {
5634
5652
  return !!(attachmentsWithProgress === null || attachmentsWithProgress === void 0 ? void 0 : attachmentsWithProgress.find((attachment) => !attachment.error));
5635
5653
  };
5636
5654
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
5655
+ /**
5656
+ * Check if the content has inline image.
5657
+ * @internal
5658
+ */
5659
+ const hasInlineImageContent = (content) => {
5660
+ const document = new DOMParser().parseFromString(content, 'text/html');
5661
+ return !!document.querySelector('img');
5662
+ };
5663
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
5637
5664
  /**
5638
5665
  * @internal
5666
+ *
5667
+ * @param message - The message content to update.
5668
+ * @param initialInlineImages - The initial inline images that comes with the message before editing.
5669
+ *
5670
+ * @returns The updated message content.
5639
5671
  */
5640
- // Before sending the image, we need to add the image id we get back after uploading the images to the message content.
5641
- const addUploadedImagesToMessage = (message, inlineImages) => __awaiter$Q(void 0, void 0, void 0, function* () {
5672
+ const updateStylesOfInlineImages = (message, initialInlineImages) => __awaiter$Q(void 0, void 0, void 0, function* () {
5642
5673
  if (message === '') {
5643
5674
  return message;
5644
5675
  }
5676
+ const initialInlineImagesIds = initialInlineImages.map((initialInlineImage) => initialInlineImage.id);
5645
5677
  const document = new DOMParser().parseFromString(message !== null && message !== void 0 ? message : '', 'text/html');
5646
5678
  const imagesPromise = Array.from(document.querySelectorAll('img')).map((img) => {
5647
5679
  return new Promise((resolve, rejects) => {
5648
- const uploadInlineImage = inlineImages.find((inlineImage) => !inlineImage.error && (inlineImage.url === img.src || inlineImage.id === img.id));
5649
- // The message might content images that comes with the message before editing, those images are not in the uploadInlineImages array.
5650
- // This function should only modify the message content for images in the uploadInlineImages array.
5651
- if (!uploadInlineImage) {
5680
+ // The message might content images that comes with the message before editing.
5681
+ // This function should only modify the message content for images that are newly added.
5682
+ if (initialInlineImagesIds.includes(img.id)) {
5652
5683
  resolve();
5653
5684
  return;
5654
5685
  }
5655
5686
  const imageElement = new Image();
5656
5687
  imageElement.src = img.src;
5657
5688
  imageElement.onload = () => {
5658
- var _a;
5659
5689
  // imageElement is a copy of original img element, so changes need to be made to the original img element
5660
- img.id = (_a = uploadInlineImage === null || uploadInlineImage === void 0 ? void 0 : uploadInlineImage.id) !== null && _a !== void 0 ? _a : '';
5661
- if (uploadInlineImage === null || uploadInlineImage === void 0 ? void 0 : uploadInlineImage.url) {
5662
- img.src = uploadInlineImage.url;
5663
- }
5664
5690
  img.width = imageElement.width;
5665
5691
  img.height = imageElement.height;
5666
5692
  img.style.aspectRatio = `${imageElement.width} / ${imageElement.height}`;
@@ -5716,21 +5742,6 @@ hasCompletedAttachmentUploads, hasError, disabled }) => {
5716
5742
  hasError ||
5717
5743
  disabled);
5718
5744
  };
5719
- /* @conditional-compile-remove(rich-text-editor-image-upload) */
5720
- /**
5721
- * @internal
5722
- */
5723
- const cancelInlineImageUpload$1 = (props) => {
5724
- const { imageSrcArray, inlineImages, messageId, editBoxOnCancelInlineImageUpload, sendBoxOnCancelInlineImageUpload } = props;
5725
- if (imageSrcArray && inlineImages && (inlineImages === null || inlineImages === void 0 ? void 0 : inlineImages.length) > 0) {
5726
- inlineImages === null || inlineImages === void 0 ? void 0 : inlineImages.map((inlineImage) => {
5727
- if (inlineImage.url && !(imageSrcArray === null || imageSrcArray === void 0 ? void 0 : imageSrcArray.includes(inlineImage.url))) {
5728
- sendBoxOnCancelInlineImageUpload && sendBoxOnCancelInlineImageUpload(inlineImage.id);
5729
- editBoxOnCancelInlineImageUpload && editBoxOnCancelInlineImageUpload(inlineImage.id, messageId || '');
5730
- }
5731
- });
5732
- }
5733
- };
5734
5745
  /* @conditional-compile-remove(file-sharing-acs) */
5735
5746
  /**
5736
5747
  * @internal
@@ -5748,15 +5759,13 @@ const toAttachmentMetadata = (attachmentsWithProgress) => {
5748
5759
  };
5749
5760
  });
5750
5761
  };
5751
- /* @conditional-compile-remove(rich-text-editor-image-upload) */
5752
5762
  /**
5753
5763
  * @internal
5754
5764
  */
5755
- const insertImagesToContentString = (content, inlineImages, onCompleted) => __awaiter$Q(void 0, void 0, void 0, function* () {
5756
- if (!inlineImages || inlineImages.length <= 0) {
5757
- onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(content);
5758
- }
5759
- const newContent = yield addUploadedImagesToMessage(content, inlineImages !== null && inlineImages !== void 0 ? inlineImages : []);
5765
+ const modifyInlineImagesInContentString = (content, initialInlineImages, onCompleted) => __awaiter$Q(void 0, void 0, void 0, function* () {
5766
+ let newContent = content;
5767
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
5768
+ newContent = yield updateStylesOfInlineImages(content, initialInlineImages);
5760
5769
  onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(newContent);
5761
5770
  });
5762
5771
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
@@ -5785,6 +5794,25 @@ const removeBrokenImageContentAndClearImageSizeStyles = (content) => {
5785
5794
  });
5786
5795
  return document.body.innerHTML;
5787
5796
  };
5797
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
5798
+ /**
5799
+ * @internal
5800
+ */
5801
+ const getContentWithUpdatedInlineImagesInfo = (content, inlineImageWithProgress) => {
5802
+ if (!inlineImageWithProgress || inlineImageWithProgress.length <= 0) {
5803
+ return content;
5804
+ }
5805
+ const document = new DOMParser().parseFromString(content, 'text/html');
5806
+ document.querySelectorAll('img').forEach((img) => {
5807
+ const imageId = img.id;
5808
+ const inlineImage = inlineImageWithProgress.find((image) => !image.error && image.progress === 1 && image.id === imageId);
5809
+ if (inlineImage) {
5810
+ img.id = inlineImage.id;
5811
+ img.src = inlineImage.url || img.src;
5812
+ }
5813
+ });
5814
+ return document.body.innerHTML;
5815
+ };
5788
5816
 
5789
5817
  // Copyright (c) Microsoft Corporation.
5790
5818
  // Licensed under the MIT License.
@@ -6850,6 +6878,7 @@ var PluginEventType;
6850
6878
  PluginEventType["EditorReady"] = "editorReady";
6851
6879
  PluginEventType["BeforeDispose"] = "beforeDispose";
6852
6880
  PluginEventType["ContentChanged"] = "contentChanged";
6881
+ PluginEventType["BeforeSetContent"] = "beforeSetContent";
6853
6882
  PluginEventType["Input"] = "input";
6854
6883
  PluginEventType["KeyDown"] = "keyDown";
6855
6884
  PluginEventType["BeforePaste"] = "beforePaste";
@@ -6890,7 +6919,128 @@ const dataSetApplier = (format, element, context) => {
6890
6919
  context.defaultFormatAppliers.dataset(format, element, context);
6891
6920
  }
6892
6921
  };
6922
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
6923
+ /**
6924
+ * @internal
6925
+ */
6926
+ const getPreviousInlineImages = (content) => {
6927
+ if (!content) {
6928
+ return [];
6929
+ }
6930
+ const previousInlineImages = [];
6931
+ const document = new DOMParser().parseFromString(content !== null && content !== void 0 ? content : '', 'text/html');
6932
+ document.querySelectorAll('img').forEach((img) => {
6933
+ const imageAttributes = getInlineImageAttributes(img);
6934
+ previousInlineImages.push(imageAttributes);
6935
+ });
6936
+ return previousInlineImages;
6937
+ };
6938
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
6939
+ /**
6940
+ * @internal
6941
+ */
6942
+ const getRemovedInlineImages = (content, previousInlineImages) => {
6943
+ const document = new DOMParser().parseFromString(content !== null && content !== void 0 ? content : '', 'text/html');
6944
+ const currentContentIds = Array.from(document.querySelectorAll('img')).map((img) => img.id);
6945
+ previousInlineImages = previousInlineImages === null || previousInlineImages === void 0 ? void 0 : previousInlineImages.filter((img) => !(currentContentIds === null || currentContentIds === void 0 ? void 0 : currentContentIds.includes(img.id)));
6946
+ const removedInlineImages = [...previousInlineImages];
6947
+ return removedInlineImages;
6948
+ };
6949
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
6950
+ /**
6951
+ * @internal
6952
+ */
6953
+ const getInsertedInlineImages = (content, previousInlineImages) => {
6954
+ const document = new DOMParser().parseFromString(content !== null && content !== void 0 ? content : '', 'text/html');
6955
+ const currentContentInlineImages = Array.from(document.querySelectorAll('img'));
6956
+ const previousContentIds = Array.from(previousInlineImages).map((img) => img.id);
6957
+ // if check is updated, also update getRemovedInlineImages
6958
+ const insertedInlineImages = currentContentInlineImages.filter((img) => !previousContentIds.includes(img.id));
6959
+ return insertedInlineImages;
6960
+ };
6961
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
6962
+ /**
6963
+ * @internal
6964
+ */
6965
+ const getInlineImageAttributes = (image) => {
6966
+ const imageAttributes = {};
6967
+ image.getAttributeNames().forEach((attrName) => {
6968
+ const attrValue = image.getAttribute(attrName);
6969
+ if (attrValue) {
6970
+ imageAttributes[attrName] = attrValue;
6971
+ }
6972
+ });
6973
+ return imageAttributes;
6974
+ };
6975
+ /* @conditional-compile-remove(rich-text-editor) */
6976
+ /**
6977
+ * @internal
6978
+ */
6979
+ /**
6980
+ * Update the scroll position of the editor to ensure the content is visible.
6981
+ */
6982
+ const scrollToBottomRichTextEditor = () => {
6983
+ // Get the current selection in the document
6984
+ const selection = document.getSelection();
6985
+ // Check if a selection exists and it has at least one range
6986
+ if (!selection || selection.rangeCount <= 0) {
6987
+ // If no selection or range, exit the function
6988
+ return;
6989
+ }
6990
+ // Get the first range of the selection
6991
+ // A user can normally only select one range at a time, so the rangeCount will usually be 1
6992
+ const range = selection.getRangeAt(0);
6993
+ // If the common ancestor container of the range is the document itself,
6994
+ // it might mean that the editable element is getting removed from the DOM
6995
+ // In such cases, especially in Safari, trying to modify the range might throw a HierarchyRequest error
6996
+ if (range.commonAncestorContainer === document) {
6997
+ return;
6998
+ }
6999
+ // Create a temporary span element to use as an anchor for scrolling
7000
+ // We can't use the anchor node directly because if it's a Text node, calling scrollIntoView() on it will throw an error
7001
+ const tempElement = document.createElement('span');
7002
+ // Collapse the range to its end point
7003
+ // This means the start and end points of the range will be the same, and it will not contain any content
7004
+ range.collapse(false);
7005
+ // Insert the temporary element at the cursor's position at the end of the range
7006
+ range.insertNode(tempElement);
7007
+ // Scroll the temporary element into view
7008
+ // the element will be aligned at the center of the scroll container, otherwise, text and images may be positioned incorrectly
7009
+ tempElement.scrollIntoView({
7010
+ block: 'center'
7011
+ });
7012
+ tempElement.remove();
7013
+ };
7014
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7015
+ /**
7016
+ * Revoke the blob urls in the removedInlineImages and remove them from the currentLocalBlobMap
7017
+ * @internal
7018
+ */
7019
+ const removeLocalBlobs = (currentLocalBlobMap, removedInlineImages) => {
7020
+ removedInlineImages.forEach((image) => {
7021
+ removeSingleLocalBlob(currentLocalBlobMap, image.id);
7022
+ });
7023
+ };
7024
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7025
+ /**
7026
+ * Revoke all the blob urls in the currentLocalBlobMap and clean up the currentLocalBlobMap
7027
+ * @internal
7028
+ */
7029
+ const cleanAllLocalBlobs = (currentLocalBlobMap) => {
7030
+ Object.keys(currentLocalBlobMap).forEach((imageId) => {
7031
+ removeSingleLocalBlob(currentLocalBlobMap, imageId);
7032
+ });
7033
+ };
7034
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7035
+ const removeSingleLocalBlob = (currentLocalBlobMap, imageId) => {
7036
+ const blobUrl = currentLocalBlobMap[imageId];
7037
+ if (blobUrl) {
7038
+ URL.revokeObjectURL(blobUrl);
7039
+ delete currentLocalBlobMap[imageId];
7040
+ }
7041
+ };
6893
7042
 
7043
+ /* @conditional-compile-remove(rich-text-editor) */
6894
7044
  /**
6895
7045
  * CopyPastePlugin is a plugin for handling copy and paste events in the editor.
6896
7046
  */
@@ -6945,16 +7095,24 @@ const handleInlineImage = (event, onInsertInlineImage) => {
6945
7095
  if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal' && onInsertInlineImage) {
6946
7096
  event.fragment.querySelectorAll('img').forEach((image) => {
6947
7097
  const clipboardImage = event.clipboardData.image;
6948
- const fileName = (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.name) || (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.type.replace('/', '.')) || 'image.png';
7098
+ const fileName = (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.name) ||
7099
+ (clipboardImage === null || clipboardImage === void 0 ? void 0 : clipboardImage.type.replace('/', '.')) ||
7100
+ image.getAttribute(_IMAGE_ATTRIBUTE_INLINE_IMAGE_FILE_NAME_KEY) ||
7101
+ '';
6949
7102
  // If the image src is an external url, call the onInsertInlineImage callback with the url.
6950
7103
  let imageUrl = image.src;
6951
7104
  if (image.src.startsWith('data:image/')) {
6952
7105
  const blobImage = _base64ToBlob(image.src);
6953
7106
  imageUrl = URL.createObjectURL(blobImage);
6954
7107
  }
6955
- onInsertInlineImage(imageUrl, fileName);
6956
7108
  image.src = imageUrl;
6957
7109
  image.alt = image.alt || 'image';
7110
+ // Assign a unique id to the image element so Contosos can identify the image element.
7111
+ // We also use it internally such as in getRemovedInlineImages to compare images in the content with previous images
7112
+ image.id = uuid.v1();
7113
+ image.dataset.imageFileName = fileName;
7114
+ const imageAttributes = getInlineImageAttributes(image);
7115
+ onInsertInlineImage(imageAttributes);
6958
7116
  });
6959
7117
  }
6960
7118
  };
@@ -6964,36 +7122,8 @@ const handleInlineImage = (event, onInsertInlineImage) => {
6964
7122
  */
6965
7123
  const scrollToBottomAfterContentPaste = (event) => {
6966
7124
  if (event.eventType === PluginEventType.ContentChanged && event.source === ContentChangedEventSource.Paste) {
6967
- // Get the current selection in the document
6968
- const selection = document.getSelection();
6969
- // Check if a selection exists and it has at least one range
6970
- if (!selection || selection.rangeCount <= 0) {
6971
- // If no selection or range, exit the function
6972
- return;
6973
- }
6974
- // Get the first range of the selection
6975
- // A user can normally only select one range at a time, so the rangeCount will usually be 1
6976
- const range = selection.getRangeAt(0);
6977
- // If the common ancestor container of the range is the document itself,
6978
- // it might mean that the editable element is getting removed from the DOM
6979
- // In such cases, especially in Safari, trying to modify the range might throw a HierarchyRequest error
6980
- if (range.commonAncestorContainer === document) {
6981
- return;
6982
- }
6983
- // Create a temporary span element to use as an anchor for scrolling
6984
- // We can't use the anchor node directly because if it's a Text node, calling scrollIntoView() on it will throw an error
6985
- const tempElement = document.createElement('span');
6986
- // Collapse the range to its end point
6987
- // This means the start and end points of the range will be the same, and it will not contain any content
6988
- range.collapse(false);
6989
- // Insert the temporary element at the cursor's position at the end of the range
6990
- range.insertNode(tempElement);
6991
- // Scroll the temporary element into view
6992
- // the element will be aligned at the center of the scroll container, otherwise, text and images may be positioned incorrectly
6993
- tempElement.scrollIntoView({
6994
- block: 'center'
6995
- });
6996
- tempElement.remove();
7125
+ /* @conditional-compile-remove(rich-text-editor) */
7126
+ scrollToBottomRichTextEditor();
6997
7127
  }
6998
7128
  };
6999
7129
 
@@ -7074,11 +7204,9 @@ class UpdateContentPlugin {
7074
7204
  }
7075
7205
  }
7076
7206
  onPluginEvent(event) {
7077
- var _a;
7078
7207
  if (this.onUpdate === null) {
7079
7208
  return;
7080
7209
  }
7081
- let imageSrcArray;
7082
7210
  switch (event.eventType) {
7083
7211
  case PluginEventType.EditorReady:
7084
7212
  this.onUpdate(UpdateEvent.Init);
@@ -7087,21 +7215,16 @@ class UpdateContentPlugin {
7087
7215
  this.onUpdate(UpdateEvent.Dispose);
7088
7216
  break;
7089
7217
  case PluginEventType.ContentChanged:
7090
- if (event.source.toLowerCase() === 'cut' ||
7091
- (event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))) {
7092
- imageSrcArray = [];
7093
- (_a = event.contentModel) === null || _a === void 0 ? void 0 : _a.blocks.map((block) => {
7094
- if (block.blockType === 'Paragraph') {
7095
- const segments = block.segments;
7096
- segments.map((segment) => {
7097
- if (segment.segmentType === 'Image') {
7098
- imageSrcArray === null || imageSrcArray === void 0 ? void 0 : imageSrcArray.push(segment.src);
7099
- }
7100
- });
7101
- }
7102
- });
7218
+ if (event.source === roosterjsContentModelDom.ChangeSource.Cut ||
7219
+ // We need to add the paste source here for an edge case:
7220
+ // when user select an image that's already in the editor, then paste in an image to replace the selected one,
7221
+ // we will only get a paste event.
7222
+ // In this case, we need to update the removedInlineImage array to include the replaced image.
7223
+ event.source === roosterjsContentModelDom.ChangeSource.Paste ||
7224
+ (event.source === roosterjsContentModelDom.ChangeSource.Keyboard && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))) {
7225
+ this.onUpdate(UpdateEvent.ContentChanged, true);
7103
7226
  }
7104
- this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);
7227
+ this.onUpdate(UpdateEvent.ContentChanged);
7105
7228
  break;
7106
7229
  case PluginEventType.Input:
7107
7230
  this.onUpdate(UpdateEvent.UserInput);
@@ -7750,6 +7873,57 @@ class PlaceholderPlugin extends roosterjsContentModelPlugins.WatermarkPlugin {
7750
7873
  }
7751
7874
  }
7752
7875
 
7876
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7877
+ /**
7878
+ * UndoRedoPlugin is a plugin for additional handling undo and redo events in the editor.
7879
+ */
7880
+ class UndoRedoPlugin {
7881
+ constructor() {
7882
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7883
+ this.editor = null;
7884
+ this.onUpdateContent = null;
7885
+ }
7886
+ getName() {
7887
+ return 'CustomUndoRedoPlugin';
7888
+ }
7889
+ initialize(editor) {
7890
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7891
+ this.editor = editor;
7892
+ }
7893
+ dispose() { }
7894
+ onPluginEvent(event) {
7895
+ // handle when new images are added to the editor because of undo/redo
7896
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7897
+ if (this.editor && event.eventType === PluginEventType.BeforeSetContent && this.onInsertInlineImage) {
7898
+ handleBeforeSetEvent(event, this.editor, this.onInsertInlineImage);
7899
+ }
7900
+ // handle deleted images and updated content
7901
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7902
+ if (this.onUpdateContent &&
7903
+ event.eventType === PluginEventType.ContentChanged &&
7904
+ event.source === roosterjsContentModelDom.ChangeSource.SetContent) {
7905
+ this.onUpdateContent();
7906
+ }
7907
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7908
+ if (this.editor &&
7909
+ !this.editor.isDisposed() &&
7910
+ event.eventType === PluginEventType.ContentChanged &&
7911
+ event.source === roosterjsContentModelDom.ChangeSource.SetContent) {
7912
+ // scroll the editor to the correct position after undo/redo actions
7913
+ scrollToBottomRichTextEditor();
7914
+ }
7915
+ }
7916
+ }
7917
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7918
+ const handleBeforeSetEvent = (event, editor, onInsertInlineImage) => {
7919
+ const currentImagesList = editor.getDocument().querySelectorAll('img');
7920
+ const insertedImages = getInsertedInlineImages(event.newContent, currentImagesList);
7921
+ insertedImages.forEach((image) => {
7922
+ const imageAttributes = getInlineImageAttributes(image);
7923
+ onInsertInlineImage(imageAttributes);
7924
+ });
7925
+ };
7926
+
7753
7927
  // Copyright (c) Microsoft Corporation.
7754
7928
  // Licensed under the MIT License.
7755
7929
  /**
@@ -7768,6 +7942,20 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7768
7942
  const theme = useTheme();
7769
7943
  const [contextMenuProps, setContextMenuProps] = React.useState(null);
7770
7944
  const previousThemeDirection = React.useRef(themeDirection(theme));
7945
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7946
+ // This will be set when the editor is initialized and when the content is updated.
7947
+ const [previousInlineImages, setPreviousInlineImages] = React.useState([]);
7948
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7949
+ const [inlineImageLocalBlobs, setInlineImageLocalBlobs] = React.useState({});
7950
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7951
+ React.useEffect(() => {
7952
+ return () => {
7953
+ // Cleanup Local Blob URLs when the component is unmounted
7954
+ cleanAllLocalBlobs(inlineImageLocalBlobs);
7955
+ };
7956
+ // This effect should only run once when the component is unmounted, so we don't need to add any dependencies
7957
+ // eslint-disable-next-line react-hooks/exhaustive-deps
7958
+ }, []);
7771
7959
  React.useImperativeHandle(ref, () => {
7772
7960
  return {
7773
7961
  focus() {
@@ -7776,6 +7964,10 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7776
7964
  }
7777
7965
  },
7778
7966
  setEmptyContent() {
7967
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7968
+ setPreviousInlineImages([]);
7969
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
7970
+ cleanAllLocalBlobs(inlineImageLocalBlobs);
7779
7971
  if (editor.current) {
7780
7972
  // remove all content from the editor and update the model
7781
7973
  // ContentChanged event will be sent by RoosterJS automatically
@@ -7799,7 +7991,7 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7799
7991
  }
7800
7992
  }
7801
7993
  };
7802
- }, [onContentModelUpdate]);
7994
+ }, [/* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImageLocalBlobs, onContentModelUpdate]);
7803
7995
  const toolbarPlugin = React.useMemo(() => {
7804
7996
  return new RichTextToolbarPlugin();
7805
7997
  }, []);
@@ -7826,9 +8018,27 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7826
8018
  const copyPastePlugin = React.useMemo(() => {
7827
8019
  return new CopyPastePlugin();
7828
8020
  }, []);
8021
+ const onChangeContent = React.useCallback((/* @conditional-compile-remove(rich-text-editor-image-upload) */ shouldUpdateInlineImages) => {
8022
+ if (editor.current === null) {
8023
+ return;
8024
+ }
8025
+ const content = roosterjsContentModelCore.exportContent(editor.current);
8026
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8027
+ let removedInlineImages = [];
8028
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8029
+ if (shouldUpdateInlineImages) {
8030
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8031
+ removedInlineImages = getRemovedInlineImages(content, previousInlineImages);
8032
+ }
8033
+ onChange &&
8034
+ onChange(content, /* @conditional-compile-remove(rich-text-editor-image-upload) */ removedInlineImages);
8035
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8036
+ setPreviousInlineImages(getPreviousInlineImages(content));
8037
+ }, [onChange, /* @conditional-compile-remove(rich-text-editor-image-upload) */ previousInlineImages]);
7829
8038
  React.useEffect(() => {
7830
8039
  // don't set callback in plugin constructor to update callback without plugin recreation
7831
- updatePlugin.onUpdate = (event, imageSrcArray) => {
8040
+ updatePlugin.onUpdate = (event,
8041
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ shouldRemoveInlineImages) => {
7832
8042
  if (editor.current === null) {
7833
8043
  return;
7834
8044
  }
@@ -7836,14 +8046,46 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7836
8046
  onContentModelUpdate && onContentModelUpdate(editor.current.getContentModelCopy('disconnected'));
7837
8047
  }
7838
8048
  else {
7839
- onChange && onChange(roosterjsContentModelCore.exportContent(editor.current), imageSrcArray);
8049
+ const content = roosterjsContentModelCore.exportContent(editor.current);
8050
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8051
+ let removedInlineImages = [];
8052
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8053
+ if (shouldRemoveInlineImages) {
8054
+ removedInlineImages = getRemovedInlineImages(content, previousInlineImages);
8055
+ if (removedInlineImages.length > 0) {
8056
+ removeLocalBlobs(inlineImageLocalBlobs, removedInlineImages);
8057
+ }
8058
+ }
8059
+ onChange &&
8060
+ onChange(content, /* @conditional-compile-remove(rich-text-editor-image-upload) */ removedInlineImages);
8061
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8062
+ setPreviousInlineImages(getPreviousInlineImages(content));
7840
8063
  }
7841
8064
  };
7842
- }, [onChange, onContentModelUpdate, updatePlugin]);
8065
+ }, [
8066
+ onChange,
8067
+ onContentModelUpdate,
8068
+ updatePlugin,
8069
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ previousInlineImages,
8070
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImageLocalBlobs
8071
+ ]);
8072
+ const undoRedoPlugin = React.useMemo(() => {
8073
+ return new UndoRedoPlugin();
8074
+ }, []);
7843
8075
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
7844
8076
  React.useEffect(() => {
7845
- copyPastePlugin.onInsertInlineImage = onInsertInlineImage;
7846
- }, [copyPastePlugin, onInsertInlineImage]);
8077
+ copyPastePlugin.onInsertInlineImage = (imageAttributes) => {
8078
+ const { id, src } = imageAttributes;
8079
+ setInlineImageLocalBlobs(Object.assign(Object.assign({}, inlineImageLocalBlobs), { [id]: src }));
8080
+ onInsertInlineImage && onInsertInlineImage(imageAttributes);
8081
+ };
8082
+ undoRedoPlugin.onInsertInlineImage = onInsertInlineImage;
8083
+ }, [copyPastePlugin, inlineImageLocalBlobs, onInsertInlineImage, undoRedoPlugin]);
8084
+ React.useEffect(() => {
8085
+ undoRedoPlugin.onUpdateContent = () => {
8086
+ onChangeContent(/* @conditional-compile-remove(rich-text-editor-image-upload) */ true);
8087
+ };
8088
+ }, [onChangeContent, undoRedoPlugin]);
7847
8089
  const keyboardInputPlugin = React.useMemo(() => {
7848
8090
  return new KeyboardInputPlugin();
7849
8091
  }, []);
@@ -7895,7 +8137,8 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7895
8137
  shortcutPlugin,
7896
8138
  // contextPlugin and tableEditMenuProvider allow to show insert/delete menu for the table
7897
8139
  contextMenuPlugin,
7898
- tableContextMenuPlugin
8140
+ tableContextMenuPlugin,
8141
+ undoRedoPlugin
7899
8142
  ];
7900
8143
  }, [
7901
8144
  onContextMenuRender,
@@ -7905,7 +8148,8 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7905
8148
  updatePlugin,
7906
8149
  copyPastePlugin,
7907
8150
  toolbarPlugin,
7908
- tableContextMenuPlugin
8151
+ tableContextMenuPlugin,
8152
+ undoRedoPlugin
7909
8153
  ]);
7910
8154
  const announcerStringGetter = React.useCallback((key) => {
7911
8155
  var _a, _b;
@@ -7920,6 +8164,10 @@ const RichTextEditor = React.forwardRef((props, ref) => {
7920
8164
  }, [strings.richTextNewBulletedListItemAnnouncement, strings.richTextNewNumberedListItemAnnouncement]);
7921
8165
  React.useEffect(() => {
7922
8166
  var _a;
8167
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8168
+ const prevInlineImage = getPreviousInlineImages(initialContent);
8169
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8170
+ setPreviousInlineImages(prevInlineImage);
7923
8171
  const initialModel = createEditorInitialModel(initialContent, contentModel);
7924
8172
  if (editorDiv.current) {
7925
8173
  editor.current = new roosterjsContentModelCore.Editor(editorDiv.current, {
@@ -8228,9 +8476,9 @@ const RichTextSendBox = (props) => {
8228
8476
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8229
8477
  onInsertInlineImage,
8230
8478
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8231
- inlineImages,
8479
+ inlineImagesWithProgress,
8232
8480
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8233
- onCancelInlineImageUpload } = props;
8481
+ onRemoveInlineImage } = props;
8234
8482
  const theme = useTheme();
8235
8483
  const locale = useLocale$1();
8236
8484
  const localeStrings = React.useMemo(() => {
@@ -8256,29 +8504,34 @@ const RichTextSendBox = (props) => {
8256
8504
  setContentValue(newValue);
8257
8505
  }, []);
8258
8506
  const onChangeHandler = React.useCallback((newValue,
8259
- /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageSrcArray) => {
8507
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ removedInlineImages) => {
8260
8508
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8261
- cancelInlineImageUpload$1({
8262
- imageSrcArray,
8263
- inlineImages,
8264
- messageId: undefined,
8265
- editBoxOnCancelInlineImageUpload: undefined,
8266
- sendBoxOnCancelInlineImageUpload: onCancelInlineImageUpload
8267
- });
8509
+ removedInlineImages === null || removedInlineImages === void 0 ? void 0 : removedInlineImages.forEach((removedInlineImage) => onRemoveInlineImage && onRemoveInlineImage(removedInlineImage));
8268
8510
  setContent(newValue);
8269
- }, [
8270
- setContent,
8271
- /* @conditional-compile-remove(rich-text-editor-image-upload) */ onCancelInlineImageUpload,
8272
- /* @conditional-compile-remove(rich-text-editor-image-upload) */ inlineImages
8273
- ]);
8511
+ }, [setContent, /* @conditional-compile-remove(rich-text-editor-image-upload) */ onRemoveInlineImage]);
8274
8512
  const hasContent = React.useMemo(() => {
8275
8513
  var _a;
8276
8514
  // get plain text content from the editor to check if the message is empty
8277
8515
  // as the content may contain tags even when the content is empty
8278
8516
  const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
8279
- return sanitizeText(contentValue !== null && contentValue !== void 0 ? contentValue : '').length > 0 && sanitizeText(plainTextContent !== null && plainTextContent !== void 0 ? plainTextContent : '').length > 0;
8517
+ const hasPlainText = sanitizeText(contentValue !== null && contentValue !== void 0 ? contentValue : '').length > 0 && sanitizeText(plainTextContent !== null && plainTextContent !== void 0 ? plainTextContent : '').length > 0;
8518
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8519
+ const hasInlineImages = hasInlineImageContent(contentValue);
8520
+ return hasPlainText || /* @conditional-compile-remove(rich-text-editor-image-upload) */ hasInlineImages;
8280
8521
  }, [contentValue]);
8281
8522
  const sendMessageOnClick = React.useCallback(() => {
8523
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
8524
+ if (inlineImagesWithProgress && inlineImagesWithProgress.length > 0) {
8525
+ const contentWithUpdatedInlineImagesInfo = getContentWithUpdatedInlineImagesInfo(contentValue, inlineImagesWithProgress);
8526
+ const messageTooLong = isMessageTooLong(contentWithUpdatedInlineImagesInfo.length);
8527
+ // Set contentValueOverflow state to display the error bar
8528
+ setContentValueOverflow(messageTooLong);
8529
+ // The change from the setContentValueOverflow in the previous line will not kick in yet.
8530
+ // We need to relay on the local value of messageTooLong to return early if the message is too long.
8531
+ if (messageTooLong) {
8532
+ return;
8533
+ }
8534
+ }
8282
8535
  if (disabled || contentValueOverflow) {
8283
8536
  return;
8284
8537
  }
@@ -8286,7 +8539,7 @@ const RichTextSendBox = (props) => {
8286
8539
  /* @conditional-compile-remove(file-sharing-acs) */
8287
8540
  setAttachmentUploadsPendingError(undefined);
8288
8541
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8289
- const hasIncompleteImageUploads = hasIncompleteAttachmentUploads(inlineImages);
8542
+ const hasIncompleteImageUploads = hasIncompleteAttachmentUploads(inlineImagesWithProgress);
8290
8543
  /* @conditional-compile-remove(file-sharing-acs) */
8291
8544
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8292
8545
  if (
@@ -8308,9 +8561,7 @@ const RichTextSendBox = (props) => {
8308
8561
  }
8309
8562
  // we don't want to send empty messages including spaces, newlines, tabs
8310
8563
  // Message can be empty if there is a valid attachment upload
8311
- if (hasContent ||
8312
- /* @conditional-compile-remove(file-sharing-acs) */ isAttachmentUploadCompleted(attachments) ||
8313
- /* @conditional-compile-remove(rich-text-editor-image-upload) */ isAttachmentUploadCompleted(inlineImages)) {
8564
+ if (hasContent || /* @conditional-compile-remove(file-sharing-acs) */ isAttachmentUploadCompleted(attachments)) {
8314
8565
  const sendMessage = (content) => {
8315
8566
  var _a, _b;
8316
8567
  onSendMessage(content,
@@ -8325,14 +8576,9 @@ const RichTextSendBox = (props) => {
8325
8576
  (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.setEmptyContent();
8326
8577
  (_b = editorComponentRef.current) === null || _b === void 0 ? void 0 : _b.focus();
8327
8578
  };
8328
- /* @conditional-compile-remove(rich-text-editor-image-upload) */
8329
- if (isAttachmentUploadCompleted(inlineImages)) {
8330
- insertImagesToContentString(contentValue, inlineImages, (content) => {
8331
- sendMessage(content);
8332
- });
8333
- return;
8334
- }
8335
- sendMessage(contentValue);
8579
+ modifyInlineImagesInContentString(contentValue, [], (content) => {
8580
+ sendMessage(content);
8581
+ });
8336
8582
  }
8337
8583
  }, [
8338
8584
  disabled,
@@ -8340,7 +8586,7 @@ const RichTextSendBox = (props) => {
8340
8586
  /* @conditional-compile-remove(file-sharing-acs) */
8341
8587
  attachments,
8342
8588
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8343
- inlineImages,
8589
+ inlineImagesWithProgress,
8344
8590
  contentValue,
8345
8591
  hasContent,
8346
8592
  /* @conditional-compile-remove(file-sharing-acs) */
@@ -8358,7 +8604,7 @@ const RichTextSendBox = (props) => {
8358
8604
  /* @conditional-compile-remove(file-sharing-acs) */
8359
8605
  !!((_a = attachments === null || attachments === void 0 ? void 0 : attachments.filter((attachmentUpload) => attachmentUpload.error).pop()) === null || _a === void 0 ? void 0 : _a.error) ||
8360
8606
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8361
- !!((_b = inlineImages === null || inlineImages === void 0 ? void 0 : inlineImages.filter((image) => image.error).pop()) === null || _b === void 0 ? void 0 : _b.error));
8607
+ !!((_b = inlineImagesWithProgress === null || inlineImagesWithProgress === void 0 ? void 0 : inlineImagesWithProgress.filter((image) => image.error).pop()) === null || _b === void 0 ? void 0 : _b.error));
8362
8608
  }, [
8363
8609
  /* @conditional-compile-remove(file-sharing-acs) */
8364
8610
  attachments,
@@ -8367,7 +8613,7 @@ const RichTextSendBox = (props) => {
8367
8613
  attachmentUploadsPendingError,
8368
8614
  systemMessage,
8369
8615
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8370
- inlineImages
8616
+ inlineImagesWithProgress
8371
8617
  ]);
8372
8618
  const onRenderSendIcon = React.useCallback((isHover) => {
8373
8619
  return (React.createElement(react.Icon, { iconName: isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend', className: sendIconStyle({
@@ -8385,7 +8631,7 @@ const RichTextSendBox = (props) => {
8385
8631
  /* @conditional-compile-remove(file-sharing-acs) */
8386
8632
  const uploadErrorMessage = (_b = (_a = attachments === null || attachments === void 0 ? void 0 : attachments.filter((attachmentUpload) => attachmentUpload.error).pop()) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.message;
8387
8633
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8388
- const imageUploadErrorMessage = (_d = (_c = inlineImages === null || inlineImages === void 0 ? void 0 : inlineImages.filter((image) => image.error).pop()) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.message;
8634
+ const imageUploadErrorMessage = (_d = (_c = inlineImagesWithProgress === null || inlineImagesWithProgress === void 0 ? void 0 : inlineImagesWithProgress.filter((image) => image.error).pop()) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.message;
8389
8635
  /* @conditional-compile-remove(file-sharing-acs) */
8390
8636
  const errorMessage = uploadErrorMessage || /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageUploadErrorMessage;
8391
8637
  return {
@@ -8410,7 +8656,7 @@ const RichTextSendBox = (props) => {
8410
8656
  /* @conditional-compile-remove(file-sharing-acs) */
8411
8657
  attachmentUploadsPendingError,
8412
8658
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
8413
- inlineImages,
8659
+ inlineImagesWithProgress,
8414
8660
  systemMessage
8415
8661
  ]);
8416
8662
  /* @conditional-compile-remove(file-sharing-acs) */
@@ -10473,7 +10719,7 @@ class _ErrorBoundary extends React.Component {
10473
10719
  // Copyright (c) Microsoft Corporation.
10474
10720
  // Licensed under the MIT License.
10475
10721
  /* @conditional-compile-remove(rich-text-editor) */
10476
- const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-CsHqT8dY.js'); }));
10722
+ const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js'); }));
10477
10723
  /**
10478
10724
  * @private
10479
10725
  * Use this function to load RoosterJS dependencies early in the lifecycle.
@@ -10481,7 +10727,7 @@ const ChatMessageComponentAsRichTextEditBox = React.lazy(() => Promise.resolve()
10481
10727
  *
10482
10728
  * @conditional-compile-remove(rich-text-editor)
10483
10729
  */
10484
- const loadChatMessageComponentAsRichTextEditBox = () => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-CsHqT8dY.js'); });
10730
+ const loadChatMessageComponentAsRichTextEditBox = () => Promise.resolve().then(function () { return require('./ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js'); });
10485
10731
  /**
10486
10732
  * @private
10487
10733
  */
@@ -10583,9 +10829,9 @@ const ChatMyMessageComponent = (props) => {
10583
10829
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10584
10830
  onInsertInlineImage: props.onInsertInlineImage,
10585
10831
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10586
- inlineImages: props.inlineImages,
10832
+ inlineImagesWithProgress: props.inlineImagesWithProgress,
10587
10833
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10588
- onCancelInlineImageUpload: props.onCancelInlineImageUpload }));
10834
+ onRemoveInlineImage: props.onRemoveInlineImage }));
10589
10835
  }
10590
10836
  else {
10591
10837
  return (React.createElement(ChatMyMessageComponentAsMessageBubble, Object.assign({}, props, { onRemoveClick: onRemoveClick, onEditClick: onEditClick, onResendClick: onResendClick, onRenderAvatar: props.onRenderAvatar,
@@ -10621,9 +10867,9 @@ const FluentChatMyMessageComponent = (props) => {
10621
10867
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10622
10868
  onPaste,
10623
10869
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10624
- inlineImages,
10870
+ inlineImagesWithProgress,
10625
10871
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10626
- onCancelInlineImageUpload,
10872
+ onRemoveInlineImage,
10627
10873
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10628
10874
  onInsertInlineImage } = props;
10629
10875
  const chatMessageRenderStyles = useChatMessageRenderStyles();
@@ -10655,11 +10901,11 @@ const FluentChatMyMessageComponent = (props) => {
10655
10901
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10656
10902
  onPaste: onPaste,
10657
10903
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10658
- onCancelInlineImageUpload: onCancelInlineImageUpload,
10904
+ onRemoveInlineImage: onRemoveInlineImage,
10659
10905
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10660
10906
  onInsertInlineImage: onInsertInlineImage,
10661
10907
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10662
- inlineImages: inlineImages })));
10908
+ inlineImagesWithProgress: inlineImagesWithProgress })));
10663
10909
  }
10664
10910
  return React.createElement(React.Fragment, null);
10665
10911
  }, [
@@ -10685,11 +10931,11 @@ const FluentChatMyMessageComponent = (props) => {
10685
10931
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10686
10932
  onPaste,
10687
10933
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10688
- onCancelInlineImageUpload,
10934
+ onRemoveInlineImage,
10689
10935
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10690
10936
  onInsertInlineImage,
10691
10937
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
10692
- inlineImages
10938
+ inlineImagesWithProgress
10693
10939
  ]);
10694
10940
  const messageRenderer = React.useCallback((messageProps) => {
10695
10941
  return onRenderMessage === undefined
@@ -11515,10 +11761,10 @@ const MessageThreadWrapper = (props) => {
11515
11761
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
11516
11762
  onInsertInlineImage: richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.onInsertInlineImage,
11517
11763
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
11518
- inlineImages: (richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.messagesInlineImages) &&
11519
- (richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.messagesInlineImages[message.message.messageId]),
11764
+ inlineImagesWithProgress: (richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.messagesInlineImagesWithProgress) &&
11765
+ (richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.messagesInlineImagesWithProgress[message.message.messageId]),
11520
11766
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
11521
- onCancelInlineImageUpload: richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.onCancelInlineImageUpload })));
11767
+ onRemoveInlineImage: richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.onRemoveInlineImage })));
11522
11768
  }))))));
11523
11769
  };
11524
11770
  const MemoChatMessageComponentWrapper = React.memo((obj) => {
@@ -21223,6 +21469,12 @@ const CHAT_CONTAINER_MIN_WIDTH_REM = 17.5;
21223
21469
  * @private
21224
21470
  */
21225
21471
  const SEND_BOX_UPLOADS_KEY_VALUE = 'send-box';
21472
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
21473
+ /**
21474
+ * Default rich text editor inline image file name
21475
+ * @internal
21476
+ */
21477
+ const _DEFAULT_INLINE_IMAGE_FILE_NAME = 'image.png';
21226
21478
 
21227
21479
  // Copyright (c) Microsoft Corporation.
21228
21480
  // Licensed under the MIT License.
@@ -22722,7 +22974,7 @@ const AttachmentDownloadErrorBar = (props) => {
22722
22974
  /**
22723
22975
  * Wrapper for RichTextSendBox component to allow us to use usePropsFor with richTextSendBox with lazy loading
22724
22976
  */
22725
- const RichTextSendBoxWrapper = React.lazy(() => Promise.resolve().then(function () { return require('./RichTextSendBoxWrapper-TGDmjXvl.js'); }).then((module) => ({ default: module.RichTextSendBoxWrapper })));
22977
+ const RichTextSendBoxWrapper = React.lazy(() => Promise.resolve().then(function () { return require('./RichTextSendBoxWrapper-8FsFMpKF.js'); }).then((module) => ({ default: module.RichTextSendBoxWrapper })));
22726
22978
  /**
22727
22979
  * @private
22728
22980
  * Use this function to load RoosterJS dependencies early in the lifecycle.
@@ -22730,7 +22982,7 @@ const RichTextSendBoxWrapper = React.lazy(() => Promise.resolve().then(function
22730
22982
  *
22731
22983
  /* @conditional-compile-remove(rich-text-editor-composite-support)
22732
22984
  */
22733
- const loadRichTextSendBox = () => Promise.resolve().then(function () { return require('./RichTextSendBoxWrapper-TGDmjXvl.js'); }).then((module) => ({ default: module.RichTextSendBoxWrapper }));
22985
+ const loadRichTextSendBox = () => Promise.resolve().then(function () { return require('./RichTextSendBoxWrapper-8FsFMpKF.js'); }).then((module) => ({ default: module.RichTextSendBoxWrapper }));
22734
22986
  /**
22735
22987
  * @private
22736
22988
  */
@@ -22738,7 +22990,7 @@ const SendBoxPicker = (props) => {
22738
22990
  /* @conditional-compile-remove(rich-text-editor-composite-support) */
22739
22991
  const { richTextEditorOptions } = props;
22740
22992
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22741
- const { onPaste, onInsertInlineImage, inlineImages, onCancelInlineImageUpload } = richTextEditorOptions || {};
22993
+ const { onPaste, onInsertInlineImage, inlineImagesWithProgress, onRemoveInlineImage } = richTextEditorOptions || {};
22742
22994
  const sendBoxProps = usePropsFor$2(SendBox);
22743
22995
  /* @conditional-compile-remove(rich-text-editor-composite-support) */
22744
22996
  const isRichTextEditorEnabled = React.useMemo(() => {
@@ -22755,9 +23007,9 @@ const SendBoxPicker = (props) => {
22755
23007
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22756
23008
  onInsertInlineImage: onInsertInlineImage,
22757
23009
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22758
- inlineImages: inlineImages,
23010
+ inlineImagesWithProgress: inlineImagesWithProgress,
22759
23011
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22760
- onCancelInlineImageUpload: onCancelInlineImageUpload })))));
23012
+ onRemoveInlineImage: onRemoveInlineImage })))));
22761
23013
  }
22762
23014
  return sendBox;
22763
23015
  };
@@ -22813,14 +23065,14 @@ const getEditBoxMessagesInlineImages = (editBoxInlineImageUploads) => {
22813
23065
  return;
22814
23066
  }
22815
23067
  const messageIds = Object.keys(editBoxInlineImageUploads || {});
22816
- const messagesInlineImages = {};
23068
+ const messagesInlineImagesWithProgress = {};
22817
23069
  messageIds.map((messageId) => {
22818
23070
  const messageUploads = editBoxInlineImageUploads[messageId].map((upload) => {
22819
23071
  return upload.metadata;
22820
23072
  });
22821
- messagesInlineImages[messageId] = messageUploads;
23073
+ messagesInlineImagesWithProgress[messageId] = messageUploads;
22822
23074
  });
22823
- return messagesInlineImages;
23075
+ return messagesInlineImagesWithProgress;
22824
23076
  };
22825
23077
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22826
23078
  /**
@@ -22855,7 +23107,10 @@ const inlineImageUploadHandler = (uploadTasks, adapter, strings) => __awaiter$G(
22855
23107
  }
22856
23108
  try {
22857
23109
  const response = yield adapter.uploadImage(image, (_c = task.metadata) === null || _c === void 0 ? void 0 : _c.name);
22858
- uploadTask.notifyUploadCompleted(response.id, task.metadata.url || '');
23110
+ // Use response id as the image src because we need to keep the original image id as a reference to find the image.
23111
+ // Also the html content we send to ChatSDK does not need image src,
23112
+ // it only need the response id to match the uploaded image, url is not needed.
23113
+ uploadTask.notifyUploadCompleted(task.metadata.id, response.id);
22859
23114
  }
22860
23115
  catch (error) {
22861
23116
  console.error(error);
@@ -22864,8 +23119,8 @@ const inlineImageUploadHandler = (uploadTasks, adapter, strings) => __awaiter$G(
22864
23119
  }
22865
23120
  });
22866
23121
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22867
- const generateUploadTask = (image, fileName, messageId, inlineImageUploadActionHandler) => __awaiter$G(void 0, void 0, void 0, function* () {
22868
- const imageData = yield getInlineImageData(image);
23122
+ const generateUploadTask = (imageAttributes, fileName, messageId, inlineImageUploadActionHandler) => __awaiter$G(void 0, void 0, void 0, function* () {
23123
+ const imageData = yield getInlineImageData(imageAttributes.src);
22869
23124
  if (!imageData) {
22870
23125
  return;
22871
23126
  }
@@ -22874,9 +23129,9 @@ const generateUploadTask = (image, fileName, messageId, inlineImageUploadActionH
22874
23129
  image: imageData,
22875
23130
  taskId,
22876
23131
  metadata: {
22877
- id: taskId,
23132
+ id: imageAttributes.id,
22878
23133
  name: fileName,
22879
- url: image,
23134
+ url: imageAttributes.src,
22880
23135
  progress: 0
22881
23136
  },
22882
23137
  notifyUploadProgressChanged: (value) => {
@@ -22911,8 +23166,8 @@ const generateUploadTask = (image, fileName, messageId, inlineImageUploadActionH
22911
23166
  /**
22912
23167
  * @internal
22913
23168
  */
22914
- const onInsertInlineImageForEditBox = (image, fileName, messageId, adapter, handleEditBoxInlineImageUploadAction, chatCompositeStrings) => __awaiter$G(void 0, void 0, void 0, function* () {
22915
- const uploadTask = yield generateUploadTask(image, fileName, messageId, handleEditBoxInlineImageUploadAction);
23169
+ const onInsertInlineImageForEditBox = (imageAttributes, fileName, messageId, adapter, handleEditBoxInlineImageUploadAction, chatCompositeStrings) => __awaiter$G(void 0, void 0, void 0, function* () {
23170
+ const uploadTask = yield generateUploadTask(imageAttributes, fileName, messageId, handleEditBoxInlineImageUploadAction);
22916
23171
  if (!uploadTask) {
22917
23172
  return;
22918
23173
  }
@@ -22927,8 +23182,8 @@ const onInsertInlineImageForEditBox = (image, fileName, messageId, adapter, hand
22927
23182
  /**
22928
23183
  * @internal
22929
23184
  */
22930
- const onInsertInlineImageForSendBox = (image, fileName, adapter, handleSendBoxInlineImageUploadAction, chatCompositeStrings) => __awaiter$G(void 0, void 0, void 0, function* () {
22931
- const uploadTask = yield generateUploadTask(image, fileName, SEND_BOX_UPLOADS_KEY_VALUE, handleSendBoxInlineImageUploadAction);
23185
+ const onInsertInlineImageForSendBox = (imageAttributes, fileName, adapter, handleSendBoxInlineImageUploadAction, chatCompositeStrings) => __awaiter$G(void 0, void 0, void 0, function* () {
23186
+ const uploadTask = yield generateUploadTask(imageAttributes, fileName, SEND_BOX_UPLOADS_KEY_VALUE, handleSendBoxInlineImageUploadAction);
22932
23187
  if (!uploadTask) {
22933
23188
  return;
22934
23189
  }
@@ -22943,8 +23198,14 @@ const onInsertInlineImageForSendBox = (image, fileName, adapter, handleSendBoxIn
22943
23198
  /**
22944
23199
  * @internal
22945
23200
  */
22946
- const cancelInlineImageUpload = (imageId, imageUpload, messageId, inlineImageUploadActionHandler, adapter) => {
23201
+ const cancelInlineImageUpload = (imageAttributes, imageUploads, messageId, inlineImageUploadActionHandler, adapter) => {
23202
+ if (!imageUploads || !imageUploads[messageId]) {
23203
+ deleteExistingInlineImageForEditBox(imageAttributes.id, messageId, adapter);
23204
+ return;
23205
+ }
23206
+ const imageUpload = imageUploads[messageId].find((upload) => upload.metadata.id === imageAttributes.id);
22947
23207
  if (!imageUpload || !(imageUpload === null || imageUpload === void 0 ? void 0 : imageUpload.metadata.id)) {
23208
+ deleteExistingInlineImageForEditBox(imageAttributes.id, messageId, adapter);
22948
23209
  return;
22949
23210
  }
22950
23211
  inlineImageUploadActionHandler({
@@ -22952,37 +23213,56 @@ const cancelInlineImageUpload = (imageId, imageUpload, messageId, inlineImageUpl
22952
23213
  id: imageUpload === null || imageUpload === void 0 ? void 0 : imageUpload.metadata.id,
22953
23214
  messageId
22954
23215
  });
22955
- // TODO: remove local blob
22956
23216
  if ((imageUpload === null || imageUpload === void 0 ? void 0 : imageUpload.metadata.progress) === 1) {
22957
- try {
22958
- adapter.deleteImage(imageId);
22959
- }
22960
- catch (error) {
22961
- console.error(error);
22962
- }
23217
+ deleteInlineImageFromServer(imageUpload === null || imageUpload === void 0 ? void 0 : imageUpload.metadata.id, adapter);
23218
+ }
23219
+ };
23220
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
23221
+ const deleteInlineImageFromServer = (imageId, adapter) => {
23222
+ try {
23223
+ adapter.deleteImage(imageId);
23224
+ }
23225
+ catch (error) {
23226
+ console.error(error);
22963
23227
  }
22964
23228
  };
22965
23229
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23230
+ // This function is used to delete the inline image that existed before editing starts
23231
+ const deleteExistingInlineImageForEditBox = (imageId, messageId, adapter) => {
23232
+ messageId !== SEND_BOX_UPLOADS_KEY_VALUE && deleteInlineImageFromServer(imageId, adapter);
23233
+ };
23234
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
22966
23235
  /**
22967
23236
  * @internal
22968
23237
  */
22969
- const onCancelInlineImageUploadHandlerForEditBox = (imageId, messageId, editBoxInlineImageUploads, adapter, handleEditBoxInlineImageUploadAction) => {
22970
- if (!editBoxInlineImageUploads) {
22971
- return;
23238
+ const updateContentStringWithUploadedInlineImages = (content, imageUploads, messageId = SEND_BOX_UPLOADS_KEY_VALUE) => {
23239
+ if (!imageUploads || !imageUploads[messageId]) {
23240
+ return content;
22972
23241
  }
22973
- const imageUpload = editBoxInlineImageUploads[messageId].find((upload) => upload.metadata.id === imageId);
22974
- cancelInlineImageUpload(imageId, imageUpload, messageId, handleEditBoxInlineImageUploadAction, adapter);
23242
+ const messageUploads = imageUploads[messageId];
23243
+ const document = new DOMParser().parseFromString(content !== null && content !== void 0 ? content : '', 'text/html');
23244
+ document.querySelectorAll('img').forEach((img) => {
23245
+ var _a;
23246
+ const uploadInlineImage = messageUploads.find((upload) => !upload.metadata.error && upload.metadata.progress === 1 && upload.metadata.id === img.id);
23247
+ if (uploadInlineImage) {
23248
+ // ChatSDK uses the respond id provided by the upload response. We store the response id in the image src attribute previously.
23249
+ img.id = (_a = uploadInlineImage.metadata.url) !== null && _a !== void 0 ? _a : img.id;
23250
+ img.src = '';
23251
+ }
23252
+ });
23253
+ content = document.body.innerHTML;
23254
+ return content;
22975
23255
  };
22976
23256
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
22977
23257
  /**
22978
23258
  * @internal
22979
23259
  */
22980
- const onCancelInlineImageUploadHandlerForSendBox = (imageId, sendBoxInlineImageUploads, adapter, handleSendBoxInlineImageUploadAction) => {
22981
- if (!sendBoxInlineImageUploads) {
22982
- return;
23260
+ const getImageFileNameFromAttributes = (imageAttributes) => {
23261
+ const fileName = imageAttributes[_IMAGE_ATTRIBUTE_INLINE_IMAGE_FILE_NAME_KEY];
23262
+ if (!fileName || fileName === '' || fileName === 'undefined' || fileName === 'null') {
23263
+ return _DEFAULT_INLINE_IMAGE_FILE_NAME;
22983
23264
  }
22984
- const imageUpload = sendBoxInlineImageUploads[SEND_BOX_UPLOADS_KEY_VALUE].find((upload) => upload.metadata.id === imageId);
22985
- cancelInlineImageUpload(imageId, imageUpload, SEND_BOX_UPLOADS_KEY_VALUE, handleSendBoxInlineImageUploadAction, adapter);
23265
+ return fileName;
22986
23266
  };
22987
23267
 
22988
23268
  // Copyright (c) Microsoft Corporation.
@@ -23327,6 +23607,8 @@ const ChatScreen = (props) => {
23327
23607
  /* @conditional-compile-remove(file-sharing-acs) */ /* @conditional-compile-remove(rich-text-editor-composite-support) */ options) {
23328
23608
  return __awaiter$F(this, void 0, void 0, function* () {
23329
23609
  var _a;
23610
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
23611
+ content = updateContentStringWithUploadedInlineImages(content, sendBoxInlineImageUploads);
23330
23612
  /* @conditional-compile-remove(file-sharing-acs) */
23331
23613
  const attachments = (_a = options === null || options === void 0 ? void 0 : options.attachments) !== null && _a !== void 0 ? _a : [];
23332
23614
  /* @conditional-compile-remove(file-sharing-acs) */
@@ -23345,13 +23627,24 @@ const ChatScreen = (props) => {
23345
23627
  /* @conditional-compile-remove(file-sharing-acs) */
23346
23628
  return;
23347
23629
  });
23348
- }, [adapter, /* @conditional-compile-remove(rich-text-editor-image-upload) */ handleSendBoxInlineImageUploadAction]);
23349
- const onUpdateMessageHandler = React.useCallback((messageId, content) => __awaiter$F(void 0, void 0, void 0, function* () {
23350
- yield messageThreadProps.onUpdateMessage(messageId, content);
23351
- /* @conditional-compile-remove(rich-text-editor-image-upload) */
23352
- handleEditBoxInlineImageUploadAction({ type: AttachmentUploadActionType.Clear, messageId });
23353
- }), [
23630
+ }, [
23631
+ adapter,
23632
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ handleSendBoxInlineImageUploadAction,
23633
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ sendBoxInlineImageUploads
23634
+ ]);
23635
+ const onUpdateMessageHandler = React.useCallback(function (messageId, content,
23636
+ /* @conditional-compile-remove(file-sharing-acs) */ options) {
23637
+ return __awaiter$F(this, void 0, void 0, function* () {
23638
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
23639
+ content = updateContentStringWithUploadedInlineImages(content, editBoxInlineImageUploads, messageId);
23640
+ yield messageThreadProps.onUpdateMessage(messageId, content,
23641
+ /* @conditional-compile-remove(file-sharing-acs) */ options);
23642
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */
23643
+ handleEditBoxInlineImageUploadAction({ type: AttachmentUploadActionType.Clear, messageId });
23644
+ });
23645
+ }, [
23354
23646
  /* @conditional-compile-remove(rich-text-editor-image-upload) */ handleEditBoxInlineImageUploadAction,
23647
+ /* @conditional-compile-remove(rich-text-editor-image-upload) */ editBoxInlineImageUploads,
23355
23648
  messageThreadProps
23356
23649
  ]);
23357
23650
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
@@ -23385,14 +23678,14 @@ const ChatScreen = (props) => {
23385
23678
  return (options === null || options === void 0 ? void 0 : options.richTextEditor)
23386
23679
  ? Object.assign(Object.assign({}, richTextEditorOptions), {
23387
23680
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23388
- onInsertInlineImage: (imageUrl, imageFileName, messageId) => {
23389
- onInsertInlineImageForEditBox(imageUrl, imageFileName, messageId, adapter, handleEditBoxInlineImageUploadAction, localeStrings.chat);
23681
+ onInsertInlineImage: (imageAttributes, messageId) => {
23682
+ onInsertInlineImageForEditBox(imageAttributes, getImageFileNameFromAttributes(imageAttributes), messageId, adapter, handleEditBoxInlineImageUploadAction, localeStrings.chat);
23390
23683
  },
23391
23684
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23392
- messagesInlineImages: getEditBoxMessagesInlineImages(editBoxInlineImageUploads),
23685
+ messagesInlineImagesWithProgress: getEditBoxMessagesInlineImages(editBoxInlineImageUploads),
23393
23686
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23394
- onCancelInlineImageUpload: (imageId, messageId) => {
23395
- onCancelInlineImageUploadHandlerForEditBox(imageId, messageId, editBoxInlineImageUploads, adapter, handleEditBoxInlineImageUploadAction);
23687
+ onRemoveInlineImage: (imageAttributes, messageId) => {
23688
+ cancelInlineImageUpload(imageAttributes, editBoxInlineImageUploads, messageId, handleEditBoxInlineImageUploadAction, adapter);
23396
23689
  } }) : undefined;
23397
23690
  }, [
23398
23691
  options === null || options === void 0 ? void 0 : options.richTextEditor,
@@ -23406,14 +23699,14 @@ const ChatScreen = (props) => {
23406
23699
  return (options === null || options === void 0 ? void 0 : options.richTextEditor)
23407
23700
  ? Object.assign(Object.assign({}, richTextEditorOptions), {
23408
23701
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23409
- onInsertInlineImage: (imageUrl, imageFileName) => {
23410
- onInsertInlineImageForSendBox(imageUrl, imageFileName, adapter, handleSendBoxInlineImageUploadAction, localeStrings.chat);
23702
+ onInsertInlineImage: (imageAttributes) => {
23703
+ onInsertInlineImageForSendBox(imageAttributes, getImageFileNameFromAttributes(imageAttributes), adapter, handleSendBoxInlineImageUploadAction, localeStrings.chat);
23411
23704
  },
23412
23705
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23413
- inlineImages: getSendBoxInlineImages(sendBoxInlineImageUploads),
23706
+ inlineImagesWithProgress: getSendBoxInlineImages(sendBoxInlineImageUploads),
23414
23707
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
23415
- onCancelInlineImageUpload: (imageId) => {
23416
- onCancelInlineImageUploadHandlerForSendBox(imageId, sendBoxInlineImageUploads, adapter, handleSendBoxInlineImageUploadAction);
23708
+ onRemoveInlineImage: (imageAttributes) => {
23709
+ cancelInlineImageUpload(imageAttributes, sendBoxInlineImageUploads, SEND_BOX_UPLOADS_KEY_VALUE, handleSendBoxInlineImageUploadAction, adapter);
23417
23710
  } }) : undefined;
23418
23711
  }, [
23419
23712
  options === null || options === void 0 ? void 0 : options.richTextEditor,
@@ -25866,6 +26159,15 @@ let CallContext$2 = class CallContext {
25866
26159
  });
25867
26160
  }
25868
26161
  /* @conditional-compile-remove(breakout-rooms) */
26162
+ setBreakoutRoomOriginCallId(callId, breakoutRoomCallId) {
26163
+ this.modifyState((draft) => {
26164
+ const call = draft.calls[this._callIdHistory.latestCallId(breakoutRoomCallId)];
26165
+ if (call) {
26166
+ call.breakoutRooms = Object.assign(Object.assign({}, call.breakoutRooms), { breakoutRoomOriginCallId: callId });
26167
+ }
26168
+ });
26169
+ }
26170
+ /* @conditional-compile-remove(breakout-rooms) */
25869
26171
  setBreakoutRoomSettings(callId, breakoutRoomSettings) {
25870
26172
  this.modifyState((draft) => {
25871
26173
  const call = draft.calls[this._callIdHistory.latestCallId(callId)];
@@ -27675,6 +27977,9 @@ class BreakoutRoomsSubscriber {
27675
27977
  if (eventData.type === 'assignedBreakoutRooms') {
27676
27978
  this.onAssignedBreakoutRoomUpdated(eventData.data);
27677
27979
  }
27980
+ else if (eventData.type === 'join') {
27981
+ this.onBreakoutRoomsJoined(eventData.data);
27982
+ }
27678
27983
  else if (eventData.type === 'breakoutRoomsSettings') {
27679
27984
  this.onBreakoutRoomSettingsUpdated(eventData.data);
27680
27985
  }
@@ -27682,6 +27987,9 @@ class BreakoutRoomsSubscriber {
27682
27987
  this.onAssignedBreakoutRoomUpdated = (breakoutRoom) => {
27683
27988
  this._context.setAssignedBreakoutRoom(this._callIdRef.callId, breakoutRoom);
27684
27989
  };
27990
+ this.onBreakoutRoomsJoined = (call) => {
27991
+ this._context.setBreakoutRoomOriginCallId(this._callIdRef.callId, call.id);
27992
+ };
27685
27993
  this.onBreakoutRoomSettingsUpdated = (breakoutRoomSettings) => {
27686
27994
  this._context.setBreakoutRoomSettings(this._callIdRef.callId, breakoutRoomSettings);
27687
27995
  };
@@ -38348,12 +38656,7 @@ const capabilitiesChangedInfoAndRoleSelector = reselect__namespace.createSelecto
38348
38656
  */
38349
38657
  const useTrackedCapabilityChangedNotifications = (capabilitiesChangedAndRoleInfo) => {
38350
38658
  const [trackedCapabilityChangedNotifications, setTrackedCapabilityChangedNotifications] = React.useState({});
38351
- // Initialize a share screen capability changed notification with 'RoleChanged' reason so that the initial
38352
- // share screen capability changed info from the Calling SDK when joining Teams interop will be ignored because
38353
- // being able to share screen is assumed by default. This is inline with what Teams is doing.
38354
- const activeNotifications = React.useRef({
38355
- shareScreen: { capabilityName: 'shareScreen', isPresent: true, changedReason: 'RoleChanged' }
38356
- });
38659
+ const activeNotifications = React.useRef({});
38357
38660
  React.useEffect(() => {
38358
38661
  activeNotifications.current = updateLatestCapabilityChangedNotificationMap(capabilitiesChangedAndRoleInfo, activeNotifications.current);
38359
38662
  setTrackedCapabilityChangedNotifications((prev) => updateTrackedCapabilityChangedNotificationsWithActiveNotifications(prev, Object.values(activeNotifications.current)));
@@ -38427,6 +38730,24 @@ const updateLatestCapabilityChangedNotificationMap = (capabilitiesChangedInfoAnd
38427
38730
  ((_b = activeNotifications[capabilityName]) === null || _b === void 0 ? void 0 : _b.changedReason)) {
38428
38731
  continue;
38429
38732
  }
38733
+ // All initial values of capabilities are not present with reason 'FeatureNotSupported'. So we should not show a
38734
+ // notification for them when they initially become present at the start of the call
38735
+ const oldCapabilityValue = capabilitiesChangedInfoAndRole.capabilitiesChangeInfo.oldValue[capabilityName];
38736
+ if (newCapabilityValue.isPresent === true &&
38737
+ (oldCapabilityValue === null || oldCapabilityValue === void 0 ? void 0 : oldCapabilityValue.isPresent) === false &&
38738
+ (oldCapabilityValue === null || oldCapabilityValue === void 0 ? void 0 : oldCapabilityValue.reason) === 'FeatureNotSupported' &&
38739
+ capabilitiesChangedInfoAndRole.capabilitiesChangeInfo.reason === 'MeetingOptionOrOrganizerPolicyChanged') {
38740
+ continue;
38741
+ }
38742
+ // Do not show the first time the screenshare capability is present when the user's role is resolved to mirror
38743
+ // Teams behaviour
38744
+ if (capabilityName === 'shareScreen' &&
38745
+ activeNotifications['shareScreen'] === undefined &&
38746
+ newCapabilityValue.isPresent === true &&
38747
+ (oldCapabilityValue === null || oldCapabilityValue === void 0 ? void 0 : oldCapabilityValue.isPresent) === false &&
38748
+ capabilitiesChangedInfoAndRole.capabilitiesChangeInfo.reason === 'RoleChanged') {
38749
+ continue;
38750
+ }
38430
38751
  const newCapabilityChangeNotification = {
38431
38752
  capabilityName: capabilityName,
38432
38753
  isPresent: newCapabilityValue.isPresent,
@@ -40056,6 +40377,29 @@ class AzureCommunicationCallAdapter {
40056
40377
  this.handlers.onStopAllSpotlight();
40057
40378
  });
40058
40379
  }
40380
+ /* @conditional-compile-remove(breakout-rooms) */
40381
+ returnFromBreakoutRoom() {
40382
+ return __awaiter$9(this, void 0, void 0, function* () {
40383
+ var _a;
40384
+ if (this.call === undefined) {
40385
+ return;
40386
+ }
40387
+ // Find call state of current call from stateful layer
40388
+ const callState = this.call
40389
+ ? Object.values(this.callClient.getState().calls).find((call) => { var _a; return call.id === ((_a = this.call) === null || _a === void 0 ? void 0 : _a.id); })
40390
+ : undefined;
40391
+ // Find main meeting call from call agent from the this call state
40392
+ const mainMeetingCall = (_a = this.callAgent) === null || _a === void 0 ? void 0 : _a.calls.find((callAgentCall) => {
40393
+ var _a;
40394
+ return callAgentCall.id === ((_a = callState === null || callState === void 0 ? void 0 : callState.breakoutRooms) === null || _a === void 0 ? void 0 : _a.breakoutRoomOriginCallId);
40395
+ });
40396
+ // If a main meeting call exists then process that call and resume
40397
+ if (mainMeetingCall) {
40398
+ this.processNewCall(mainMeetingCall);
40399
+ yield this.resumeCall();
40400
+ }
40401
+ });
40402
+ }
40059
40403
  getState() {
40060
40404
  return this.context.getState();
40061
40405
  }
@@ -40252,8 +40596,26 @@ class AzureCommunicationCallAdapter {
40252
40596
  }
40253
40597
  /* @conditional-compile-remove(breakout-rooms) */
40254
40598
  breakoutRoomsUpdated(eventData) {
40599
+ if (eventData.data) {
40600
+ if (eventData.type === 'assignedBreakoutRooms') {
40601
+ this.assignedBreakoutRoomUpdated(eventData.data);
40602
+ }
40603
+ else if (eventData.type === 'join') {
40604
+ this.breakoutRoomJoined(eventData.data);
40605
+ }
40606
+ }
40255
40607
  this.emitter.emit('breakoutRoomsUpdated', eventData);
40256
40608
  }
40609
+ /* @conditional-compile-remove(breakout-rooms) */
40610
+ assignedBreakoutRoomUpdated(breakoutRoom) {
40611
+ if (breakoutRoom.state === 'closed') {
40612
+ this.returnFromBreakoutRoom();
40613
+ }
40614
+ }
40615
+ /* @conditional-compile-remove(breakout-rooms) */
40616
+ breakoutRoomJoined(call) {
40617
+ this.processNewCall(call);
40618
+ }
40257
40619
  callIdChanged() {
40258
40620
  var _a;
40259
40621
  ((_a = this.call) === null || _a === void 0 ? void 0 : _a.id) && this.emitter.emit('callIdChanged', { callId: this.call.id });
@@ -40874,6 +41236,12 @@ class CallWithChatBackedCallAdapter {
40874
41236
  return this.callWithChatAdapter.muteAllRemoteParticipants();
40875
41237
  });
40876
41238
  }
41239
+ /* @conditional-compile-remove(breakout-rooms) */
41240
+ returnFromBreakoutRoom() {
41241
+ return __awaiter$8(this, void 0, void 0, function* () {
41242
+ return this.callWithChatAdapter.returnFromBreakoutRoom();
41243
+ });
41244
+ }
40877
41245
  }
40878
41246
  function callAdapterStateFromCallWithChatAdapterState(callWithChatAdapterState) {
40879
41247
  return {
@@ -41994,6 +42362,12 @@ class AzureCommunicationCallWithChatAdapter {
41994
42362
  return this.callAdapter.muteAllRemoteParticipants();
41995
42363
  });
41996
42364
  }
42365
+ /* @conditional-compile-remove(breakout-rooms) */
42366
+ returnFromBreakoutRoom() {
42367
+ return __awaiter$6(this, void 0, void 0, function* () {
42368
+ return this.callAdapter.returnFromBreakoutRoom();
42369
+ });
42370
+ }
41997
42371
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41998
42372
  on(event, listener) {
41999
42373
  switch (event) {
@@ -43155,7 +43529,6 @@ exports._IdentifierProvider = _IdentifierProvider;
43155
43529
  exports._formatString = _formatString;
43156
43530
  exports.attachmentMetadataReducer = attachmentMetadataReducer;
43157
43531
  exports.attachmentUploadCardsStyles = attachmentUploadCardsStyles;
43158
- exports.cancelInlineImageUpload = cancelInlineImageUpload$1;
43159
43532
  exports.createAzureCommunicationCallAdapter = createAzureCommunicationCallAdapter;
43160
43533
  exports.createAzureCommunicationCallAdapterFromClient = createAzureCommunicationCallAdapterFromClient;
43161
43534
  exports.createAzureCommunicationCallWithChatAdapter = createAzureCommunicationCallWithChatAdapter;
@@ -43175,19 +43548,21 @@ exports.doesMessageContainMultipleAttachments = doesMessageContainMultipleAttach
43175
43548
  exports.editBoxRichTextEditorStyle = editBoxRichTextEditorStyle;
43176
43549
  exports.editBoxWidthStyles = editBoxWidthStyles;
43177
43550
  exports.fromFlatCommunicationIdentifier = fromFlatCommunicationIdentifier;
43551
+ exports.getContentWithUpdatedInlineImagesInfo = getContentWithUpdatedInlineImagesInfo;
43178
43552
  exports.getMessageState = getMessageState;
43179
43553
  exports.getMessageWithAttachmentMetadata = getMessageWithAttachmentMetadata;
43554
+ exports.getPreviousInlineImages = getPreviousInlineImages;
43180
43555
  exports.getSelector = getSelector;
43181
43556
  exports.getSelector$1 = getSelector$1;
43182
43557
  exports.hasIncompleteAttachmentUploads = hasIncompleteAttachmentUploads;
43183
43558
  exports.imageOverlayTheme = imageOverlayTheme;
43184
- exports.insertImagesToContentString = insertImagesToContentString;
43185
- exports.isAttachmentUploadCompleted = isAttachmentUploadCompleted;
43559
+ exports.isMessageTooLong = isMessageTooLong;
43186
43560
  exports.lightTheme = lightTheme;
43187
43561
  exports.loadCallComposite = loadCallComposite;
43188
43562
  exports.loadCallWithChatComposite = loadCallWithChatComposite;
43189
43563
  exports.loadChatComposite = loadChatComposite;
43190
43564
  exports.loadOutboundCallComposite = loadOutboundCallComposite;
43565
+ exports.modifyInlineImagesInContentString = modifyInlineImagesInContentString;
43191
43566
  exports.onRenderCancelIcon = onRenderCancelIcon;
43192
43567
  exports.onRenderSubmitIcon = onRenderSubmitIcon;
43193
43568
  exports.onResolveVideoEffectDependency = onResolveVideoEffectDependency;
@@ -43215,4 +43590,4 @@ exports.useTeamsCall = useTeamsCall;
43215
43590
  exports.useTeamsCallAdapter = useTeamsCallAdapter;
43216
43591
  exports.useTeamsCallAgent = useTeamsCallAgent;
43217
43592
  exports.useTheme = useTheme;
43218
- //# sourceMappingURL=index-BBPqvw4B.js.map
43593
+ //# sourceMappingURL=index-D84PSTZV.js.map