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

Add reply support to WysiwygComposer #9422

Merged
merged 5 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
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
23 changes: 16 additions & 7 deletions src/components/views/rooms/wysiwyg_composer/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,23 @@ import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
import { PosthogAnalytics } from "../../../../PosthogAnalytics";
import SettingsStore from "../../../../settings/SettingsStore";
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../../sendTimePerformanceMetrics";
import { attachRelation } from "../SendMessageComposer";
import { RoomPermalinkCreator } from "../../../../utils/permalinks/Permalinks";
import { doMaybeLocalRoomAction } from "../../../../utils/local-room";
import { CHAT_EFFECTS } from "../../../../effects";
import { containsEmoji } from "../../../../effects/utils";
import { IRoomState } from "../../../structures/RoomView";
import dis from '../../../../dispatcher/dispatcher';
import { addReplyToMessageContent } from "../../../../utils/Reply";

// Merges favouring the given relation
function attachRelation(content: IContent, relation?: IEventRelation): void {
if (relation) {
content['m.relates_to'] = {
...(content['m.relates_to'] || {}),
...relation,
};
}
}

interface SendMessageParams {
mxClient: MatrixClient;
Expand Down Expand Up @@ -81,13 +91,12 @@ export function createMessageContent(

attachRelation(content, relation);

// TODO reply
/*if (replyToEvent) {
if (replyToEvent) {
addReplyToMessageContent(content, replyToEvent, {
permalinkCreator,
includeLegacyFallback: includeReplyLegacyFallback,
});
}*/
}

return content;
}
Expand Down Expand Up @@ -148,16 +157,16 @@ export function sendMessage(
mxClient,
);

// TODO reply
/*if (replyToEvent) {
if (replyToEvent) {
// Clear reply_to_event as we put the message into the queue
// if the send fails, retry will handle resending.
dis.dispatch({
action: 'reply_to_event',
event: null,
context: roomContext.timelineRenderingType,
});
}*/
}

dis.dispatch({ action: "message_sent" });
CHAT_EFFECTS.forEach((effect) => {
if (containsEmoji(content, effect.emojis)) {
Expand Down
104 changes: 95 additions & 9 deletions test/components/views/rooms/wysiwyg_composer/message-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ import { createTestClient, mkEvent, mkStubRoom } from "../../../../test-utils";
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { SettingLevel } from "../../../../../src/settings/SettingLevel";
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";

describe('message', () => {
const permalinkCreator = jest.fn() as any;
const permalinkCreator = {
forEvent(eventId: string): string {
return "$$permalink$$";
},
} as RoomPermalinkCreator;
const message = '<i><b>hello</b> world</i>';
const mockEvent = mkEvent({
type: "m.room.message",
Expand All @@ -45,10 +50,51 @@ describe('message', () => {

// Then
expect(content).toEqual({
body: message,
format: "org.matrix.custom.html",
formatted_body: message,
msgtype: "m.text",
"body": message,
"format": "org.matrix.custom.html",
"formatted_body": message,
"msgtype": "m.text",
});
});

it('Should add reply to message content', () => {
// When
const content = createMessageContent(message, { permalinkCreator, replyToEvent: mockEvent });

// Then
expect(content).toEqual({
"body": "> <myfakeuser> Replying to this\n\n<i><b>hello</b> world</i>",
"format": "org.matrix.custom.html",
"formatted_body": "<mx-reply><blockquote><a href=\"$$permalink$$\">In reply to</a>" +
" <a href=\"https://matrix.to/#/myfakeuser\">myfakeuser</a>"+
"<br>Replying to this</blockquote></mx-reply><i><b>hello</b> world</i>",
"msgtype": "m.text",
"m.relates_to": {
"m.in_reply_to": {
"event_id": mockEvent.getId(),
},
},
});
});

it("Should add relation to message", () => {
// When
const relation = {
rel_type: "m.thread",
event_id: "myFakeThreadId",
};
const content = createMessageContent(message, { permalinkCreator, relation });

// Then
expect(content).toEqual({
"body": message,
"format": "org.matrix.custom.html",
"formatted_body": message,
"msgtype": "m.text",
"m.relates_to": {
"event_id": "myFakeThreadId",
"rel_type": "m.thread",
},
});
});
});
Expand Down Expand Up @@ -102,6 +148,15 @@ describe('message', () => {
const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch");

it('Should not send empty html message', async () => {
// When
await sendMessage('', { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });

// Then
expect(mockClient.sendMessage).toBeCalledTimes(0);
expect(spyDispatcher).toBeCalledTimes(0);
});

it('Should send html message', async () => {
// When
await sendMessage(message, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });

Expand All @@ -116,13 +171,44 @@ describe('message', () => {
expect(spyDispatcher).toBeCalledWith({ action: 'message_sent' });
});

it('Should send html message', async () => {
it('Should send reply to html message', async () => {
const mockReplyEvent = mkEvent({
type: "m.room.message",
room: 'myfakeroom',
user: 'myfakeuser2',
content: { "msgtype": "m.text", "body": "My reply" },
event: true,
});

// When
await sendMessage('', { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
await sendMessage(message, {
roomContext: defaultRoomContext,
mxClient: mockClient,
permalinkCreator,
replyToEvent: mockReplyEvent,
});

// Then
expect(mockClient.sendMessage).toBeCalledTimes(0);
expect(spyDispatcher).toBeCalledTimes(0);
expect(spyDispatcher).toBeCalledWith({
action: 'reply_to_event',
event: null,
context: defaultRoomContext.timelineRenderingType,
});

const expectedContent = {
"body": "> <myfakeuser2> My reply\n\n<i><b>hello</b> world</i>",
"format": "org.matrix.custom.html",
"formatted_body": "<mx-reply><blockquote><a href=\"$$permalink$$\">In reply to</a>" +
" <a href=\"https://matrix.to/#/myfakeuser2\">myfakeuser2</a>" +
"<br>My reply</blockquote></mx-reply><i><b>hello</b> world</i>",
"msgtype": "m.text",
"m.relates_to": {
"m.in_reply_to": {
"event_id": mockReplyEvent.getId(),
},
},
};
expect(mockClient.sendMessage).toBeCalledWith('myfakeroom', null, expectedContent);
});

it('Should scroll to bottom after sending a html message', async () => {
Expand Down