From 2d5912e0ac14e0894dd68f63bcd54b1f00c2aea3 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 20 Dec 2022 11:40:34 +0100 Subject: [PATCH 1/3] Use react lazy to load rte component --- .../DynamicImportWysiwygComposer.tsx | 36 +++++++++++++++ .../wysiwyg_composer/EditWysiwygComposer.tsx | 45 ++++++++++--------- .../wysiwyg_composer/SendWysiwygComposer.tsx | 3 +- .../views/rooms/wysiwyg_composer/index.ts | 6 ++- .../EditWysiwygComposer-test.tsx | 7 ++- .../SendWysiwygComposer-test.tsx | 6 +-- 6 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 src/components/views/rooms/wysiwyg_composer/DynamicImportWysiwygComposer.tsx diff --git a/src/components/views/rooms/wysiwyg_composer/DynamicImportWysiwygComposer.tsx b/src/components/views/rooms/wysiwyg_composer/DynamicImportWysiwygComposer.tsx new file mode 100644 index 00000000000..65a365b06da --- /dev/null +++ b/src/components/views/rooms/wysiwyg_composer/DynamicImportWysiwygComposer.tsx @@ -0,0 +1,36 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, { ComponentProps, lazy, Suspense } from "react"; + +const SendComposer = lazy(() => import("./SendWysiwygComposer")); +const EditComposer = lazy(() => import("./EditWysiwygComposer")); + +export function DynamicImportSendWysiwygComposer(props: ComponentProps) { + return ( + }> + + + ); +} + +export function DynamicImportEditWysiwygComposer(props: ComponentProps) { + return ( + }> + + + ); +} diff --git a/src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx b/src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx index 275d30bb1f4..36264b77639 100644 --- a/src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx +++ b/src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx @@ -43,32 +43,35 @@ interface EditWysiwygComposerProps { className?: string; } -export function EditWysiwygComposer({ editorStateTransfer, className, ...props }: EditWysiwygComposerProps) { +// Default needed for React.lazy +export default function EditWysiwygComposer({ editorStateTransfer, className, ...props }: EditWysiwygComposerProps) { const initialContent = useInitialContent(editorStateTransfer); const isReady = !editorStateTransfer || initialContent !== undefined; const { editMessage, endEditing, onChange, isSaveDisabled } = useEditing(editorStateTransfer, initialContent); + if (!isReady) { + return null; + } + return ( - isReady && ( - - {(ref) => ( - <> - - - - )} - - ) + + {(ref) => ( + <> + + + + )} + ); } diff --git a/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx b/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx index 4d726721674..78b24bb5072 100644 --- a/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx +++ b/src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx @@ -49,7 +49,8 @@ interface SendWysiwygComposerProps { menuPosition: AboveLeftOf; } -export function SendWysiwygComposer({ +// Default needed for React.lazy +export default function SendWysiwygComposer({ isRichTextEnabled, e2eStatus, menuPosition, diff --git a/src/components/views/rooms/wysiwyg_composer/index.ts b/src/components/views/rooms/wysiwyg_composer/index.ts index 55a3e79a19d..c82f59ca896 100644 --- a/src/components/views/rooms/wysiwyg_composer/index.ts +++ b/src/components/views/rooms/wysiwyg_composer/index.ts @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -export { SendWysiwygComposer } from "./SendWysiwygComposer"; -export { EditWysiwygComposer } from "./EditWysiwygComposer"; +export { + DynamicImportSendWysiwygComposer as SendWysiwygComposer, + DynamicImportEditWysiwygComposer as EditWysiwygComposer, +} from "./DynamicImportWysiwygComposer"; export { sendMessage } from "./utils/message"; diff --git a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx index cc53c88dc03..93628986f8a 100644 --- a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx +++ b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx @@ -68,9 +68,14 @@ describe("EditWysiwygComposer", () => { it("Should initialize useWysiwyg with html content", async () => { // When customRender(false, editorStateTransfer); - await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true")); // Then + expect(screen.queryByRole("textbox")).toBeNull(); + + await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"), { + timeout: 2000, + }); + await waitFor(() => expect(screen.getByRole("textbox")).toContainHTML(mockEvent.getContent()["formatted_body"]), ); diff --git a/test/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx b/test/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx index 669c611f8ce..cdaf76d499c 100644 --- a/test/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx +++ b/test/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx @@ -24,7 +24,7 @@ import defaultDispatcher from "../../../../../src/dispatcher/dispatcher"; import { Action } from "../../../../../src/dispatcher/actions"; import { IRoomState } from "../../../../../src/components/structures/RoomView"; import { createTestClient, flushPromises, getRoomContext, mkEvent, mkStubRoom } from "../../../../test-utils"; -import { SendWysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer"; +import { SendWysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer/"; import { aboveLeftOf } from "../../../../../src/components/structures/ContextMenu"; import { ComposerInsertPayload, ComposerType } from "../../../../../src/dispatcher/payloads/ComposerInsertPayload"; import { setSelection } from "../../../../../src/components/views/rooms/wysiwyg_composer/utils/selection"; @@ -101,12 +101,12 @@ describe("SendWysiwygComposer", () => { ); }; - it("Should render WysiwygComposer when isRichTextEnabled is at true", () => { + it("Should render WysiwygComposer when isRichTextEnabled is at true", async () => { // When customRender(jest.fn(), jest.fn(), false, true); // Then - expect(screen.getByTestId("WysiwygComposer")).toBeTruthy(); + await waitFor(() => expect(screen.getByTestId("WysiwygComposer")).toBeTruthy()); }); it("Should render PlainTextComposer when isRichTextEnabled is at false", () => { From 232b3de740893328d94db8c7a702434d3670fcff Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 20 Dec 2022 14:06:34 +0100 Subject: [PATCH 2/3] Add test to check null in case in EditWysiwygComposer component --- .../EditWysiwygComposer-test.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx index 93628986f8a..fe64e0d0039 100644 --- a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx +++ b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx @@ -64,6 +64,25 @@ describe("EditWysiwygComposer", () => { ); }; + it("Should not render the component when not ready", async () => { + // When + const { rerender } = customRender(false); + await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"), { + timeout: 2000, + }); + + rerender( + + + + + , + ); + + // Then + await waitFor(() => expect(screen.queryByRole("textbox")).toBeNull()); + }); + describe("Initialize with content", () => { it("Should initialize useWysiwyg with html content", async () => { // When From a23982924c1ec9bf72655aca4be7aa023838e769 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 20 Dec 2022 14:23:30 +0100 Subject: [PATCH 3/3] Fix strict typescript error --- .../views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx index fe64e0d0039..c0849145bf4 100644 --- a/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx +++ b/test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx @@ -73,7 +73,7 @@ describe("EditWysiwygComposer", () => { rerender( - + , @@ -89,8 +89,6 @@ describe("EditWysiwygComposer", () => { customRender(false, editorStateTransfer); // Then - expect(screen.queryByRole("textbox")).toBeNull(); - await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"), { timeout: 2000, });