Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 0f34702

Browse files
[Backport staging] Load RTE component only when needed (#9807)
Use react lazy to load rte component (cherry picked from commit d6e447b) Co-authored-by: Florian Duros <[email protected]>
1 parent bf57a12 commit 0f34702

File tree

6 files changed

+92
-28
lines changed

6 files changed

+92
-28
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { ComponentProps, lazy, Suspense } from "react";
18+
19+
const SendComposer = lazy(() => import("./SendWysiwygComposer"));
20+
const EditComposer = lazy(() => import("./EditWysiwygComposer"));
21+
22+
export function DynamicImportSendWysiwygComposer(props: ComponentProps<typeof SendComposer>) {
23+
return (
24+
<Suspense fallback={<div />}>
25+
<SendComposer {...props} />
26+
</Suspense>
27+
);
28+
}
29+
30+
export function DynamicImportEditWysiwygComposer(props: ComponentProps<typeof EditComposer>) {
31+
return (
32+
<Suspense fallback={<div />}>
33+
<EditComposer {...props} />
34+
</Suspense>
35+
);
36+
}

src/components/views/rooms/wysiwyg_composer/EditWysiwygComposer.tsx

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,35 @@ interface EditWysiwygComposerProps {
4343
className?: string;
4444
}
4545

46-
export function EditWysiwygComposer({ editorStateTransfer, className, ...props }: EditWysiwygComposerProps) {
46+
// Default needed for React.lazy
47+
export default function EditWysiwygComposer({ editorStateTransfer, className, ...props }: EditWysiwygComposerProps) {
4748
const initialContent = useInitialContent(editorStateTransfer);
4849
const isReady = !editorStateTransfer || initialContent !== undefined;
4950

5051
const { editMessage, endEditing, onChange, isSaveDisabled } = useEditing(editorStateTransfer, initialContent);
5152

53+
if (!isReady) {
54+
return null;
55+
}
56+
5257
return (
53-
isReady && (
54-
<WysiwygComposer
55-
className={classNames("mx_EditWysiwygComposer", className)}
56-
initialContent={initialContent}
57-
onChange={onChange}
58-
onSend={editMessage}
59-
{...props}
60-
>
61-
{(ref) => (
62-
<>
63-
<Content disabled={props.disabled} ref={ref} />
64-
<EditionButtons
65-
onCancelClick={endEditing}
66-
onSaveClick={editMessage}
67-
isSaveDisabled={isSaveDisabled}
68-
/>
69-
</>
70-
)}
71-
</WysiwygComposer>
72-
)
58+
<WysiwygComposer
59+
className={classNames("mx_EditWysiwygComposer", className)}
60+
initialContent={initialContent}
61+
onChange={onChange}
62+
onSend={editMessage}
63+
{...props}
64+
>
65+
{(ref) => (
66+
<>
67+
<Content disabled={props.disabled} ref={ref} />
68+
<EditionButtons
69+
onCancelClick={endEditing}
70+
onSaveClick={editMessage}
71+
isSaveDisabled={isSaveDisabled}
72+
/>
73+
</>
74+
)}
75+
</WysiwygComposer>
7376
);
7477
}

src/components/views/rooms/wysiwyg_composer/SendWysiwygComposer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ interface SendWysiwygComposerProps {
4949
menuPosition: AboveLeftOf;
5050
}
5151

52-
export function SendWysiwygComposer({
52+
// Default needed for React.lazy
53+
export default function SendWysiwygComposer({
5354
isRichTextEnabled,
5455
e2eStatus,
5556
menuPosition,

src/components/views/rooms/wysiwyg_composer/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
export { SendWysiwygComposer } from "./SendWysiwygComposer";
18-
export { EditWysiwygComposer } from "./EditWysiwygComposer";
17+
export {
18+
DynamicImportSendWysiwygComposer as SendWysiwygComposer,
19+
DynamicImportEditWysiwygComposer as EditWysiwygComposer,
20+
} from "./DynamicImportWysiwygComposer";
1921
export { sendMessage } from "./utils/message";

test/components/views/rooms/wysiwyg_composer/EditWysiwygComposer-test.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,35 @@ describe("EditWysiwygComposer", () => {
6464
);
6565
};
6666

67+
it("Should not render the component when not ready", async () => {
68+
// When
69+
const { rerender } = customRender(false);
70+
await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"), {
71+
timeout: 2000,
72+
});
73+
74+
rerender(
75+
<MatrixClientContext.Provider value={mockClient}>
76+
<RoomContext.Provider value={{ ...defaultRoomContext, room: undefined }}>
77+
<EditWysiwygComposer disabled={false} editorStateTransfer={editorStateTransfer} />
78+
</RoomContext.Provider>
79+
</MatrixClientContext.Provider>,
80+
);
81+
82+
// Then
83+
await waitFor(() => expect(screen.queryByRole("textbox")).toBeNull());
84+
});
85+
6786
describe("Initialize with content", () => {
6887
it("Should initialize useWysiwyg with html content", async () => {
6988
// When
7089
customRender(false, editorStateTransfer);
71-
await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"));
7290

7391
// Then
92+
await waitFor(() => expect(screen.getByRole("textbox")).toHaveAttribute("contentEditable", "true"), {
93+
timeout: 2000,
94+
});
95+
7496
await waitFor(() =>
7597
expect(screen.getByRole("textbox")).toContainHTML(mockEvent.getContent()["formatted_body"]),
7698
);

test/components/views/rooms/wysiwyg_composer/SendWysiwygComposer-test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
2424
import { Action } from "../../../../../src/dispatcher/actions";
2525
import { IRoomState } from "../../../../../src/components/structures/RoomView";
2626
import { createTestClient, flushPromises, getRoomContext, mkEvent, mkStubRoom } from "../../../../test-utils";
27-
import { SendWysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer";
27+
import { SendWysiwygComposer } from "../../../../../src/components/views/rooms/wysiwyg_composer/";
2828
import { aboveLeftOf } from "../../../../../src/components/structures/ContextMenu";
2929
import { ComposerInsertPayload, ComposerType } from "../../../../../src/dispatcher/payloads/ComposerInsertPayload";
3030
import { setSelection } from "../../../../../src/components/views/rooms/wysiwyg_composer/utils/selection";
@@ -101,12 +101,12 @@ describe("SendWysiwygComposer", () => {
101101
);
102102
};
103103

104-
it("Should render WysiwygComposer when isRichTextEnabled is at true", () => {
104+
it("Should render WysiwygComposer when isRichTextEnabled is at true", async () => {
105105
// When
106106
customRender(jest.fn(), jest.fn(), false, true);
107107

108108
// Then
109-
expect(screen.getByTestId("WysiwygComposer")).toBeTruthy();
109+
await waitFor(() => expect(screen.getByTestId("WysiwygComposer")).toBeTruthy());
110110
});
111111

112112
it("Should render PlainTextComposer when isRichTextEnabled is at false", () => {

0 commit comments

Comments
 (0)