@azure/communication-react 1.19.0-alpha-202408010015 → 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.
- package/dist/communication-react.d.ts +33 -33
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-B0zbyF6Z.js → ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js} +52 -33
- package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-DM13Kp5W.js.map +1 -0
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BVOysnsq.js → RichTextSendBoxWrapper-8FsFMpKF.js} +3 -3
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BVOysnsq.js.map → RichTextSendBoxWrapper-8FsFMpKF.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-YIP5Cyt3.js → index-D84PSTZV.js} +496 -193
- package/dist/dist-cjs/communication-react/index-D84PSTZV.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +2 -2
- package/dist/dist-esm/acs-ui-common/src/constants.d.ts +5 -0
- package/dist/dist-esm/acs-ui-common/src/constants.js +6 -0
- package/dist/dist-esm/acs-ui-common/src/constants.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/index.d.ts +1 -0
- package/dist/dist-esm/acs-ui-common/src/index.js +2 -0
- package/dist/dist-esm/acs-ui-common/src/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js +6 -1
- package/dist/dist-esm/chat-component-bindings/src/handlers/createHandlers.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -1
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentWrapper.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBoxPicker.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBoxPicker.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js +53 -32
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.js +2 -2
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js +6 -6
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/FluentChatMyMessageComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageThread.d.ts +18 -6
- package/dist/dist-esm/react-components/src/components/MessageThread.js +3 -3
- package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +18 -34
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.d.ts +14 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.js +56 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UndoRedoPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +10 -16
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +85 -8
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.d.ts +16 -27
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +33 -35
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.d.ts +34 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +121 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.d.ts +15 -13
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +42 -32
- package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js +19 -6
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/TrackCapabilityChangedNotifications.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +21 -12
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.d.ts +5 -5
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js +61 -31
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.d.ts +32 -2
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/common/SendBoxPicker.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/constants.d.ts +5 -0
- package/dist/dist-esm/react-composites/src/composites/common/constants.js +6 -0
- package/dist/dist-esm/react-composites/src/composites/common/constants.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-B0zbyF6Z.js.map +0 -1
- package/dist/dist-cjs/communication-react/index-YIP5Cyt3.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-
|
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
|
-
|
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
|
-
|
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
|
-
|
5649
|
-
//
|
5650
|
-
|
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
|
5756
|
-
|
5757
|
-
|
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) ||
|
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
|
-
|
6968
|
-
|
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
|
7091
|
-
|
7092
|
-
|
7093
|
-
|
7094
|
-
|
7095
|
-
|
7096
|
-
|
7097
|
-
|
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
|
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,
|
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
|
-
|
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
|
-
}, [
|
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 =
|
7846
|
-
|
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
|
-
|
8479
|
+
inlineImagesWithProgress,
|
8232
8480
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
8233
|
-
|
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) */
|
8507
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */ removedInlineImages) => {
|
8260
8508
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
8261
|
-
|
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
|
-
|
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(
|
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
|
-
|
8329
|
-
|
8330
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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 =
|
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
|
-
|
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-
|
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-
|
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
|
-
|
10832
|
+
inlineImagesWithProgress: props.inlineImagesWithProgress,
|
10587
10833
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
10588
|
-
|
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
|
-
|
10870
|
+
inlineImagesWithProgress,
|
10625
10871
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
10626
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
11519
|
-
(richTextEditorOptions === null || richTextEditorOptions === void 0 ? void 0 : richTextEditorOptions.
|
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
|
-
|
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-
|
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-
|
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,
|
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
|
-
|
23010
|
+
inlineImagesWithProgress: inlineImagesWithProgress,
|
22759
23011
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
22760
|
-
|
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
|
23068
|
+
const messagesInlineImagesWithProgress = {};
|
22817
23069
|
messageIds.map((messageId) => {
|
22818
23070
|
const messageUploads = editBoxInlineImageUploads[messageId].map((upload) => {
|
22819
23071
|
return upload.metadata;
|
22820
23072
|
});
|
22821
|
-
|
23073
|
+
messagesInlineImagesWithProgress[messageId] = messageUploads;
|
22822
23074
|
});
|
22823
|
-
return
|
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
|
-
|
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 = (
|
22868
|
-
const imageData = yield getInlineImageData(
|
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:
|
23132
|
+
id: imageAttributes.id,
|
22878
23133
|
name: fileName,
|
22879
|
-
url:
|
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 = (
|
22915
|
-
const uploadTask = yield generateUploadTask(
|
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 = (
|
22931
|
-
const uploadTask = yield generateUploadTask(
|
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 = (
|
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
|
-
|
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);
|
22963
23218
|
}
|
22964
23219
|
};
|
22965
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);
|
23227
|
+
}
|
23228
|
+
};
|
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
|
22970
|
-
if (!
|
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
|
22974
|
-
|
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
|
22981
|
-
|
22982
|
-
|
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
|
-
|
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,10 +23627,16 @@ const ChatScreen = (props) => {
|
|
23345
23627
|
/* @conditional-compile-remove(file-sharing-acs) */
|
23346
23628
|
return;
|
23347
23629
|
});
|
23348
|
-
}, [
|
23630
|
+
}, [
|
23631
|
+
adapter,
|
23632
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */ handleSendBoxInlineImageUploadAction,
|
23633
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */ sendBoxInlineImageUploads
|
23634
|
+
]);
|
23349
23635
|
const onUpdateMessageHandler = React.useCallback(function (messageId, content,
|
23350
23636
|
/* @conditional-compile-remove(file-sharing-acs) */ options) {
|
23351
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);
|
23352
23640
|
yield messageThreadProps.onUpdateMessage(messageId, content,
|
23353
23641
|
/* @conditional-compile-remove(file-sharing-acs) */ options);
|
23354
23642
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
@@ -23356,6 +23644,7 @@ const ChatScreen = (props) => {
|
|
23356
23644
|
});
|
23357
23645
|
}, [
|
23358
23646
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */ handleEditBoxInlineImageUploadAction,
|
23647
|
+
/* @conditional-compile-remove(rich-text-editor-image-upload) */ editBoxInlineImageUploads,
|
23359
23648
|
messageThreadProps
|
23360
23649
|
]);
|
23361
23650
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
@@ -23389,14 +23678,14 @@ const ChatScreen = (props) => {
|
|
23389
23678
|
return (options === null || options === void 0 ? void 0 : options.richTextEditor)
|
23390
23679
|
? Object.assign(Object.assign({}, richTextEditorOptions), {
|
23391
23680
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23392
|
-
onInsertInlineImage: (
|
23393
|
-
onInsertInlineImageForEditBox(
|
23681
|
+
onInsertInlineImage: (imageAttributes, messageId) => {
|
23682
|
+
onInsertInlineImageForEditBox(imageAttributes, getImageFileNameFromAttributes(imageAttributes), messageId, adapter, handleEditBoxInlineImageUploadAction, localeStrings.chat);
|
23394
23683
|
},
|
23395
23684
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23396
|
-
|
23685
|
+
messagesInlineImagesWithProgress: getEditBoxMessagesInlineImages(editBoxInlineImageUploads),
|
23397
23686
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23398
|
-
|
23399
|
-
|
23687
|
+
onRemoveInlineImage: (imageAttributes, messageId) => {
|
23688
|
+
cancelInlineImageUpload(imageAttributes, editBoxInlineImageUploads, messageId, handleEditBoxInlineImageUploadAction, adapter);
|
23400
23689
|
} }) : undefined;
|
23401
23690
|
}, [
|
23402
23691
|
options === null || options === void 0 ? void 0 : options.richTextEditor,
|
@@ -23410,14 +23699,14 @@ const ChatScreen = (props) => {
|
|
23410
23699
|
return (options === null || options === void 0 ? void 0 : options.richTextEditor)
|
23411
23700
|
? Object.assign(Object.assign({}, richTextEditorOptions), {
|
23412
23701
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23413
|
-
onInsertInlineImage: (
|
23414
|
-
onInsertInlineImageForSendBox(
|
23702
|
+
onInsertInlineImage: (imageAttributes) => {
|
23703
|
+
onInsertInlineImageForSendBox(imageAttributes, getImageFileNameFromAttributes(imageAttributes), adapter, handleSendBoxInlineImageUploadAction, localeStrings.chat);
|
23415
23704
|
},
|
23416
23705
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23417
|
-
|
23706
|
+
inlineImagesWithProgress: getSendBoxInlineImages(sendBoxInlineImageUploads),
|
23418
23707
|
/* @conditional-compile-remove(rich-text-editor-image-upload) */
|
23419
|
-
|
23420
|
-
|
23708
|
+
onRemoveInlineImage: (imageAttributes) => {
|
23709
|
+
cancelInlineImageUpload(imageAttributes, sendBoxInlineImageUploads, SEND_BOX_UPLOADS_KEY_VALUE, handleSendBoxInlineImageUploadAction, adapter);
|
23421
23710
|
} }) : undefined;
|
23422
23711
|
}, [
|
23423
23712
|
options === null || options === void 0 ? void 0 : options.richTextEditor,
|
@@ -38367,12 +38656,7 @@ const capabilitiesChangedInfoAndRoleSelector = reselect__namespace.createSelecto
|
|
38367
38656
|
*/
|
38368
38657
|
const useTrackedCapabilityChangedNotifications = (capabilitiesChangedAndRoleInfo) => {
|
38369
38658
|
const [trackedCapabilityChangedNotifications, setTrackedCapabilityChangedNotifications] = React.useState({});
|
38370
|
-
|
38371
|
-
// share screen capability changed info from the Calling SDK when joining Teams interop will be ignored because
|
38372
|
-
// being able to share screen is assumed by default. This is inline with what Teams is doing.
|
38373
|
-
const activeNotifications = React.useRef({
|
38374
|
-
shareScreen: { capabilityName: 'shareScreen', isPresent: true, changedReason: 'RoleChanged' }
|
38375
|
-
});
|
38659
|
+
const activeNotifications = React.useRef({});
|
38376
38660
|
React.useEffect(() => {
|
38377
38661
|
activeNotifications.current = updateLatestCapabilityChangedNotificationMap(capabilitiesChangedAndRoleInfo, activeNotifications.current);
|
38378
38662
|
setTrackedCapabilityChangedNotifications((prev) => updateTrackedCapabilityChangedNotificationsWithActiveNotifications(prev, Object.values(activeNotifications.current)));
|
@@ -38446,6 +38730,24 @@ const updateLatestCapabilityChangedNotificationMap = (capabilitiesChangedInfoAnd
|
|
38446
38730
|
((_b = activeNotifications[capabilityName]) === null || _b === void 0 ? void 0 : _b.changedReason)) {
|
38447
38731
|
continue;
|
38448
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
|
+
}
|
38449
38751
|
const newCapabilityChangeNotification = {
|
38450
38752
|
capabilityName: capabilityName,
|
38451
38753
|
isPresent: newCapabilityValue.isPresent,
|
@@ -43227,7 +43529,6 @@ exports._IdentifierProvider = _IdentifierProvider;
|
|
43227
43529
|
exports._formatString = _formatString;
|
43228
43530
|
exports.attachmentMetadataReducer = attachmentMetadataReducer;
|
43229
43531
|
exports.attachmentUploadCardsStyles = attachmentUploadCardsStyles;
|
43230
|
-
exports.cancelInlineImageUpload = cancelInlineImageUpload$1;
|
43231
43532
|
exports.createAzureCommunicationCallAdapter = createAzureCommunicationCallAdapter;
|
43232
43533
|
exports.createAzureCommunicationCallAdapterFromClient = createAzureCommunicationCallAdapterFromClient;
|
43233
43534
|
exports.createAzureCommunicationCallWithChatAdapter = createAzureCommunicationCallWithChatAdapter;
|
@@ -43247,19 +43548,21 @@ exports.doesMessageContainMultipleAttachments = doesMessageContainMultipleAttach
|
|
43247
43548
|
exports.editBoxRichTextEditorStyle = editBoxRichTextEditorStyle;
|
43248
43549
|
exports.editBoxWidthStyles = editBoxWidthStyles;
|
43249
43550
|
exports.fromFlatCommunicationIdentifier = fromFlatCommunicationIdentifier;
|
43551
|
+
exports.getContentWithUpdatedInlineImagesInfo = getContentWithUpdatedInlineImagesInfo;
|
43250
43552
|
exports.getMessageState = getMessageState;
|
43251
43553
|
exports.getMessageWithAttachmentMetadata = getMessageWithAttachmentMetadata;
|
43554
|
+
exports.getPreviousInlineImages = getPreviousInlineImages;
|
43252
43555
|
exports.getSelector = getSelector;
|
43253
43556
|
exports.getSelector$1 = getSelector$1;
|
43254
43557
|
exports.hasIncompleteAttachmentUploads = hasIncompleteAttachmentUploads;
|
43255
43558
|
exports.imageOverlayTheme = imageOverlayTheme;
|
43256
|
-
exports.
|
43257
|
-
exports.isAttachmentUploadCompleted = isAttachmentUploadCompleted;
|
43559
|
+
exports.isMessageTooLong = isMessageTooLong;
|
43258
43560
|
exports.lightTheme = lightTheme;
|
43259
43561
|
exports.loadCallComposite = loadCallComposite;
|
43260
43562
|
exports.loadCallWithChatComposite = loadCallWithChatComposite;
|
43261
43563
|
exports.loadChatComposite = loadChatComposite;
|
43262
43564
|
exports.loadOutboundCallComposite = loadOutboundCallComposite;
|
43565
|
+
exports.modifyInlineImagesInContentString = modifyInlineImagesInContentString;
|
43263
43566
|
exports.onRenderCancelIcon = onRenderCancelIcon;
|
43264
43567
|
exports.onRenderSubmitIcon = onRenderSubmitIcon;
|
43265
43568
|
exports.onResolveVideoEffectDependency = onResolveVideoEffectDependency;
|
@@ -43287,4 +43590,4 @@ exports.useTeamsCall = useTeamsCall;
|
|
43287
43590
|
exports.useTeamsCallAdapter = useTeamsCallAdapter;
|
43288
43591
|
exports.useTeamsCallAgent = useTeamsCallAgent;
|
43289
43592
|
exports.useTheme = useTheme;
|
43290
|
-
//# sourceMappingURL=index-
|
43593
|
+
//# sourceMappingURL=index-D84PSTZV.js.map
|