UNPKG

communication-react-19

Version:

React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)

221 lines 9.06 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /** * @private */ export const MAXIMUM_LENGTH_OF_MESSAGE = 8000; const EMPTY_MESSAGE_REGEX = /^\s*$/; /* @conditional-compile-remove(file-sharing-acs) */ /** * @private */ export const hasIncompleteAttachmentUploads = (attachmentsWithProgress) => { return !!((attachmentsWithProgress === null || attachmentsWithProgress === void 0 ? void 0 : attachmentsWithProgress.length) && !attachmentsWithProgress .filter((attachmentUpload) => !attachmentUpload.error) .every((attachmentUpload) => attachmentUpload.progress === 1 && attachmentUpload.progress !== undefined)); }; /* @conditional-compile-remove(file-sharing-acs) */ /** * @private */ export const isAttachmentUploadCompleted = (attachmentsWithProgress) => { return !!(attachmentsWithProgress === null || attachmentsWithProgress === void 0 ? void 0 : attachmentsWithProgress.find((attachment) => !attachment.error)); }; /* @conditional-compile-remove(rich-text-editor-image-upload) */ /** * Obtain any image nodes from the content DOM passed in * returns a list of image IDs * @internal */ export const inlineImageIds = (content) => { if (!content) { return []; } const document = new DOMParser().parseFromString(content, 'text/html'); const imageTags = document.querySelectorAll('img'); const ids = []; imageTags.forEach((node) => { const id = node.id; const url = node.src; if (id) { ids.push({ id, url }); } }); return ids; }; /* @conditional-compile-remove(rich-text-editor-image-upload) */ /** * Check if the content has inline image. * @internal */ export const hasInlineImageContent = (content) => { return inlineImageIds(content).length > 0; }; /* @conditional-compile-remove(rich-text-editor-image-upload) */ /** * @internal * * @param message - The message content to update. * @param initialInlineImages - The initial inline images that comes with the message before editing. * * @returns The updated message content. */ export const updateStylesOfInlineImages = (message, initialInlineImages) => __awaiter(void 0, void 0, void 0, function* () { if (message === '') { return message; } const initialInlineImagesIds = initialInlineImages.map((initialInlineImage) => initialInlineImage.id); const document = new DOMParser().parseFromString(message !== null && message !== void 0 ? message : '', 'text/html'); const imagesPromise = Array.from(document.querySelectorAll('img')).map((img) => { return new Promise((resolve, rejects) => { // The message might content images that comes with the message before editing. // This function should only modify the message content for images that are newly added. if (initialInlineImagesIds.includes(img.id)) { resolve(); return; } const imageElement = new Image(); imageElement.src = img.src; imageElement.onload = () => { // imageElement is a copy of original img element, so changes need to be made to the original img element img.width = imageElement.width; img.height = imageElement.height; img.style.aspectRatio = `${imageElement.width} / ${imageElement.height}`; // Clear maxWidth and maxHeight styles that are set by roosterJS. // This is so that they can be set in messageThread styles without using the important flag. img.style.maxWidth = ''; img.style.maxHeight = ''; resolve(); }; imageElement.onerror = () => { rejects(`Error loading image ${img.id}`); }; }); }); yield Promise.all(imagesPromise); const newMessage = document.body.innerHTML; return newMessage; }); /** * @private */ export const isMessageTooLong = (valueLength) => { return valueLength > MAXIMUM_LENGTH_OF_MESSAGE; }; /** * @private */ export const sanitizeText = (message) => { if (EMPTY_MESSAGE_REGEX.test(message)) { return ''; } else { return message; } }; /** * Determines whether the send box should be disabled. * * @param hasContent - Indicates whether the send box has content. * @param hasCompletedAttachmentUploads - Indicates whether attachment uploads have completed. * @param hasError - Indicates whether there is an error. * @param disabled - Indicates whether the send box is disabled. * @returns A boolean value indicating whether the send box should be disabled. */ export const isSendBoxButtonDisabled = ({ hasContent, /* @conditional-compile-remove(file-sharing-acs) */ hasCompletedAttachmentUploads, hasError, disabled }) => { return ( // no content !(hasContent || /* @conditional-compile-remove(file-sharing-acs) */ hasCompletedAttachmentUploads) || //error message exists hasError || disabled); }; /* @conditional-compile-remove(file-sharing-acs) */ /** * @internal */ export const toAttachmentMetadata = (attachmentsWithProgress) => { return attachmentsWithProgress === null || attachmentsWithProgress === void 0 ? void 0 : attachmentsWithProgress.filter((attachment) => { var _a; return !('error' in attachment) && !((_a = attachment.error) === null || _a === void 0 ? void 0 : _a.message); }).map((attachment) => { var _a; return { id: attachment.id, name: attachment.name, url: (_a = attachment.url) !== null && _a !== void 0 ? _a : '' }; }); }; /** * @internal */ export const modifyInlineImagesInContentString = (content, initialInlineImages, onCompleted) => __awaiter(void 0, void 0, void 0, function* () { let newContent = content; /* @conditional-compile-remove(rich-text-editor-image-upload) */ try { newContent = yield updateStylesOfInlineImages(content, initialInlineImages); } catch (error) { console.error('Error updating inline images: ', error); } onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(newContent); }); /* @conditional-compile-remove(rich-text-editor-image-upload) */ /** * @internal */ export const removeBrokenImageContentAndClearImageSizeStyles = (content) => { const document = new DOMParser().parseFromString(content, 'text/html'); document.querySelectorAll('img').forEach((img) => { // Before submitting/resend the message, we need to trim the unnecessary attributes such as src, // which is set to a local svg of a broken image icon at this point. // Once message is submitted/resent, it will be fetched again and might not be a broken image anymore, // That's why we need to remove the class and data-ui-id attribute of 'broken-image-wrapper' if (img.className === 'broken-image-wrapper') { img.removeAttribute('class'); img.removeAttribute('src'); img.removeAttribute('data-ui-id'); } // Clear maxWidth and maxHeight styles that are set by roosterJS. // Clear width and height styles as the width and height is set in attributes // This is so that they can be set in messageThread styles without using the important flag. img.style.width = ''; img.style.height = ''; img.style.maxWidth = ''; img.style.maxHeight = ''; }); return document.body.innerHTML; }; /* @conditional-compile-remove(rich-text-editor-image-upload) */ /** * @internal */ export const getContentWithUpdatedInlineImagesInfo = (content, inlineImageWithProgress) => { if (!inlineImageWithProgress || inlineImageWithProgress.length <= 0) { return content; } const document = new DOMParser().parseFromString(content, 'text/html'); document.querySelectorAll('img').forEach((img) => { const imageId = img.id; const inlineImage = inlineImageWithProgress.find((image) => !image.error && image.progress === 1 && image.id === imageId); if (inlineImage) { img.id = inlineImage.id; img.src = inlineImage.url || img.src; } }); return document.body.innerHTML; }; //# sourceMappingURL=SendBoxUtils.js.map