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

Fix edit a reply in rich text editor #9615

Merged
merged 5 commits into from
Nov 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -44,9 +44,9 @@ interface EditWysiwygComposerProps {

export function EditWysiwygComposer({ editorStateTransfer, className, ...props }: EditWysiwygComposerProps) {
const initialContent = useInitialContent(editorStateTransfer);
const isReady = !editorStateTransfer || Boolean(initialContent);
const isReady = !editorStateTransfer || initialContent !== undefined;

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

return isReady && <WysiwygComposer
className={classNames("mx_EditWysiwygComposer", className)}
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ import EditorStateTransfer from "../../../../../utils/EditorStateTransfer";
import { endEditing } from "../utils/editing";
import { editMessage } from "../utils/message";

export function useEditing(initialContent: string, editorStateTransfer: EditorStateTransfer) {
export function useEditing(editorStateTransfer: EditorStateTransfer, initialContent?: string) {
const roomContext = useRoomContext();
const mxClient = useMatrixClientContext();

@@ -34,7 +34,7 @@ export function useEditing(initialContent: string, editorStateTransfer: EditorSt
}, [initialContent]);

const editMessageMemoized = useCallback(() =>
editMessage(content, { roomContext, mxClient, editorStateTransfer }),
content !== undefined && editMessage(content, { roomContext, mxClient, editorStateTransfer }),
[content, roomContext, mxClient, editorStateTransfer],
);

Original file line number Diff line number Diff line change
@@ -24,6 +24,10 @@ import { CommandPartCreator, Part } from "../../../../../editor/parts";
import SettingsStore from "../../../../../settings/SettingsStore";
import EditorStateTransfer from "../../../../../utils/EditorStateTransfer";

function getFormattedContent(editorStateTransfer: EditorStateTransfer): string {
return editorStateTransfer.getEvent().getContent().formatted_body?.replace(/<mx-reply>.*<\/mx-reply>/, '') || '';
}

function parseEditorStateTransfer(
editorStateTransfer: EditorStateTransfer,
room: Room,
@@ -42,7 +46,7 @@ function parseEditorStateTransfer(
// const restoredParts = this.restoreStoredEditorState(partCreator);

if (editorStateTransfer.getEvent().getContent().format === 'org.matrix.custom.html') {
return editorStateTransfer.getEvent().getContent().formatted_body || "";
return getFormattedContent(editorStateTransfer);
}

parts = parseEvent(editorStateTransfer.getEvent(), partCreator, {
@@ -59,7 +63,7 @@ export function useInitialContent(editorStateTransfer: EditorStateTransfer) {
const roomContext = useRoomContext();
const mxClient = useMatrixClientContext();

return useMemo<string>(() => {
return useMemo<string | undefined>(() => {
if (editorStateTransfer && roomContext.room) {
return parseEditorStateTransfer(editorStateTransfer, roomContext.room, mxClient);
}
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ limitations under the License.

import "@testing-library/jest-dom";
import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";

import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
import RoomContext from "../../../../../src/contexts/RoomContext";
@@ -96,6 +96,53 @@ describe('EditWysiwygComposer', () => {
await waitFor(() =>
expect(screen.getByRole('textbox')).toContainHTML(mockEvent.getContent()['body']));
});

it('Should ignore when formatted_body is not filled', async () => {
// When
const mockEvent = mkEvent({
type: "m.room.message",
room: 'myfakeroom',
user: 'myfakeuser',
content: {
"msgtype": "m.text",
"body": "Replying to this",
"format": "org.matrix.custom.html",
},
event: true,
});

const editorStateTransfer = new EditorStateTransfer(mockEvent);
customRender(false, editorStateTransfer);

// Then
await waitFor(() => expect(screen.getByRole('textbox')).toHaveAttribute('contentEditable', "true"));
});

it('Should strip <mx-reply> tag from initial content', async () => {
// When
const mockEvent = mkEvent({
type: "m.room.message",
room: 'myfakeroom',
user: 'myfakeuser',
content: {
"msgtype": "m.text",
"body": "Replying to this",
"format": "org.matrix.custom.html",
"formatted_body": '<mx-reply>Reply</mx-reply>My content',
},
event: true,
});

const editorStateTransfer = new EditorStateTransfer(mockEvent);
customRender(false, editorStateTransfer);
await waitFor(() => expect(screen.getByRole('textbox')).toHaveAttribute('contentEditable', "true"));

// Then
await waitFor(() => {
expect(screen.getByRole('textbox')).not.toContainHTML("<mx-reply>Reply</mx-reply>");
expect(screen.getByRole('textbox')).toContainHTML("My content");
});
});
});

describe('Edit and save actions', () => {
@@ -180,14 +227,16 @@ describe('EditWysiwygComposer', () => {
expect(screen.getByRole('textbox')).not.toHaveFocus();

// When we send an action that would cause us to get focus
defaultDispatcher.dispatch({
action: Action.FocusEditMessageComposer,
context: null,
});
// (Send a second event to exercise the clearTimeout logic)
defaultDispatcher.dispatch({
action: Action.FocusEditMessageComposer,
context: null,
act(() => {
defaultDispatcher.dispatch({
action: Action.FocusEditMessageComposer,
context: null,
});
// (Send a second event to exercise the clearTimeout logic)
defaultDispatcher.dispatch({
action: Action.FocusEditMessageComposer,
context: null,
});
});

// Wait for event dispatch to happen