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

Commit 4ba3f99

Browse files
committed
Add reply support to WysiwygComposer
1 parent ba5bd74 commit 4ba3f99

File tree

2 files changed

+86
-16
lines changed

2 files changed

+86
-16
lines changed

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,23 @@ import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
2222
import { PosthogAnalytics } from "../../../../PosthogAnalytics";
2323
import SettingsStore from "../../../../settings/SettingsStore";
2424
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../../sendTimePerformanceMetrics";
25-
import { attachRelation } from "../SendMessageComposer";
2625
import { RoomPermalinkCreator } from "../../../../utils/permalinks/Permalinks";
2726
import { doMaybeLocalRoomAction } from "../../../../utils/local-room";
2827
import { CHAT_EFFECTS } from "../../../../effects";
2928
import { containsEmoji } from "../../../../effects/utils";
3029
import { IRoomState } from "../../../structures/RoomView";
3130
import dis from '../../../../dispatcher/dispatcher';
31+
import { addReplyToMessageContent } from "../../../../utils/Reply";
32+
33+
// Merges favouring the given relation
34+
function attachRelation(content: IContent, relation?: IEventRelation): void {
35+
if (relation) {
36+
content['m.relates_to'] = {
37+
...(content['m.relates_to'] || {}),
38+
...relation,
39+
};
40+
}
41+
}
3242

3343
interface SendMessageParams {
3444
mxClient: MatrixClient;
@@ -81,13 +91,12 @@ export function createMessageContent(
8191

8292
attachRelation(content, relation);
8393

84-
// TODO reply
85-
/*if (replyToEvent) {
94+
if (replyToEvent) {
8695
addReplyToMessageContent(content, replyToEvent, {
8796
permalinkCreator,
8897
includeLegacyFallback: includeReplyLegacyFallback,
8998
});
90-
}*/
99+
}
91100

92101
return content;
93102
}
@@ -148,16 +157,16 @@ export function sendMessage(
148157
mxClient,
149158
);
150159

151-
// TODO reply
152-
/*if (replyToEvent) {
160+
if (replyToEvent) {
153161
// Clear reply_to_event as we put the message into the queue
154162
// if the send fails, retry will handle resending.
155163
dis.dispatch({
156164
action: 'reply_to_event',
157165
event: null,
158166
context: roomContext.timelineRenderingType,
159167
});
160-
}*/
168+
}
169+
161170
dis.dispatch({ action: "message_sent" });
162171
CHAT_EFFECTS.forEach((effect) => {
163172
if (containsEmoji(content, effect.emojis)) {

test/components/views/rooms/wysiwyg_composer/message-test.ts

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ import { createTestClient, mkEvent, mkStubRoom } from "../../../../test-utils";
2222
import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
2323
import SettingsStore from "../../../../../src/settings/SettingsStore";
2424
import { SettingLevel } from "../../../../../src/settings/SettingLevel";
25+
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";
2526

2627
describe('message', () => {
27-
const permalinkCreator = jest.fn() as any;
28+
const permalinkCreator = {
29+
forEvent(eventId: string): string {
30+
return "$$permalink$$";
31+
},
32+
} as RoomPermalinkCreator;
2833
const message = '<i><b>hello</b> world</i>';
2934
const mockEvent = mkEvent({
3035
type: "m.room.message",
@@ -45,10 +50,28 @@ describe('message', () => {
4550

4651
// Then
4752
expect(content).toEqual({
48-
body: message,
49-
format: "org.matrix.custom.html",
50-
formatted_body: message,
51-
msgtype: "m.text",
53+
"body": message,
54+
"format": "org.matrix.custom.html",
55+
"formatted_body": message,
56+
"msgtype": "m.text",
57+
});
58+
});
59+
60+
it('Should add reply to message content', () => {
61+
// When
62+
const content = createMessageContent(message, { permalinkCreator, replyToEvent: mockEvent });
63+
64+
// Then
65+
expect(content).toEqual({
66+
"body": "> <myfakeuser> Replying to this\n\n<i><b>hello</b> world</i>",
67+
"format": "org.matrix.custom.html",
68+
"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>",
69+
"msgtype": "m.text",
70+
"m.relates_to": {
71+
"m.in_reply_to": {
72+
"event_id": mockEvent.getId(),
73+
},
74+
},
5275
});
5376
});
5477
});
@@ -102,6 +125,15 @@ describe('message', () => {
102125
const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch");
103126

104127
it('Should not send empty html message', async () => {
128+
// When
129+
await sendMessage('', { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
130+
131+
// Then
132+
expect(mockClient.sendMessage).toBeCalledTimes(0);
133+
expect(spyDispatcher).toBeCalledTimes(0);
134+
});
135+
136+
it('Should send html message', async () => {
105137
// When
106138
await sendMessage(message, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
107139

@@ -116,13 +148,42 @@ describe('message', () => {
116148
expect(spyDispatcher).toBeCalledWith({ action: 'message_sent' });
117149
});
118150

119-
it('Should send html message', async () => {
151+
it('Should send reply to html message', async () => {
152+
const mockReplyEvent = mkEvent({
153+
type: "m.room.message",
154+
room: 'myfakeroom',
155+
user: 'myfakeuser2',
156+
content: { "msgtype": "m.text", "body": "My reply" },
157+
event: true,
158+
});
159+
120160
// When
121-
await sendMessage('', { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
161+
await sendMessage(message, {
162+
roomContext: defaultRoomContext,
163+
mxClient: mockClient,
164+
permalinkCreator,
165+
replyToEvent: mockReplyEvent,
166+
});
122167

123168
// Then
124-
expect(mockClient.sendMessage).toBeCalledTimes(0);
125-
expect(spyDispatcher).toBeCalledTimes(0);
169+
expect(spyDispatcher).toBeCalledWith({
170+
action: 'reply_to_event',
171+
event: null,
172+
context: defaultRoomContext.timelineRenderingType,
173+
});
174+
175+
const expectedContent = {
176+
"body": "> <myfakeuser2> My reply\n\n<i><b>hello</b> world</i>",
177+
"format": "org.matrix.custom.html",
178+
"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>",
179+
"msgtype": "m.text",
180+
"m.relates_to": {
181+
"m.in_reply_to": {
182+
"event_id": mockReplyEvent.getId(),
183+
},
184+
},
185+
};
186+
expect(mockClient.sendMessage).toBeCalledWith('myfakeroom', null, expectedContent);
126187
});
127188

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

0 commit comments

Comments
 (0)