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

Commit dd53b22

Browse files
authored
Allow sending files as replies as per MSC3676 (#8020)
1 parent 14653d1 commit dd53b22

File tree

4 files changed

+51
-55
lines changed

4 files changed

+51
-55
lines changed

src/ContentMessages.tsx renamed to src/ContentMessages.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,21 @@ See the License for the specific language governing permissions and
1616
limitations under the License.
1717
*/
1818

19-
import React from "react";
2019
import { MatrixClient } from "matrix-js-sdk/src/client";
2120
import { IUploadOpts } from "matrix-js-sdk/src/@types/requests";
2221
import { MsgType } from "matrix-js-sdk/src/@types/event";
2322
import encrypt from "browser-encrypt-attachment";
2423
import extractPngChunks from "png-chunks-extract";
2524
import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials";
2625
import { logger } from "matrix-js-sdk/src/logger";
27-
import { IEventRelation, ISendEventResponse } from "matrix-js-sdk/src/matrix";
26+
import { IEventRelation, ISendEventResponse, MatrixEvent } from "matrix-js-sdk/src/matrix";
2827
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
2928

3029
import { IEncryptedFile, IMediaEventInfo } from "./customisations/models/IMediaEventContent";
3130
import dis from './dispatcher/dispatcher';
3231
import * as sdk from './index';
3332
import { _t } from './languageHandler';
3433
import Modal from './Modal';
35-
import RoomViewStore from './stores/RoomViewStore';
3634
import Spinner from "./components/views/elements/Spinner";
3735
import { Action } from "./dispatcher/actions";
3836
import {
@@ -47,6 +45,8 @@ import { BlurhashEncoder } from "./BlurhashEncoder";
4745
import SettingsStore from "./settings/SettingsStore";
4846
import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerformanceMetrics";
4947
import { TimelineRenderingType } from "./contexts/RoomContext";
48+
import RoomViewStore from "./stores/RoomViewStore";
49+
import { addReplyToMessageContent } from "./utils/Reply";
5050

5151
const MAX_WIDTH = 800;
5252
const MAX_HEIGHT = 600;
@@ -457,25 +457,7 @@ export default class ContentMessages {
457457
return;
458458
}
459459

460-
const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
461-
if (isQuoting) {
462-
// FIXME: Using an import will result in Element crashing
463-
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
464-
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, {
465-
title: _t('Replying With Files'),
466-
description: (
467-
<div>{ _t(
468-
'At this time it is not possible to reply with a file. ' +
469-
'Would you like to upload this file without replying?',
470-
) }</div>
471-
),
472-
hasCancelButton: true,
473-
button: _t("Continue"),
474-
});
475-
const [shouldUpload] = await finished;
476-
if (!shouldUpload) return;
477-
}
478-
460+
const replyToEvent = RoomViewStore.getQuotingEvent();
479461
if (!this.mediaConfig) { // hot-path optimization to not flash a spinner if we don't need to
480462
const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
481463
await this.ensureMediaConfigFetched(matrixClient);
@@ -528,7 +510,16 @@ export default class ContentMessages {
528510
}
529511
}
530512

531-
promBefore = this.sendContentToRoom(file, roomId, relation, matrixClient, promBefore);
513+
promBefore = this.sendContentToRoom(file, roomId, relation, matrixClient, replyToEvent, promBefore);
514+
}
515+
516+
if (replyToEvent) {
517+
// Clear event being replied to
518+
dis.dispatch({
519+
action: "reply_to_event",
520+
event: null,
521+
context,
522+
});
532523
}
533524

534525
// Focus the correct composer
@@ -569,6 +560,7 @@ export default class ContentMessages {
569560
roomId: string,
570561
relation: IEventRelation | undefined,
571562
matrixClient: MatrixClient,
563+
replyToEvent: MatrixEvent | undefined,
572564
promBefore: Promise<any>,
573565
) {
574566
const content: IContent = {
@@ -583,6 +575,12 @@ export default class ContentMessages {
583575
content["m.relates_to"] = relation;
584576
}
585577

578+
if (replyToEvent) {
579+
addReplyToMessageContent(content, replyToEvent, {
580+
includeLegacyFallback: false,
581+
});
582+
}
583+
586584
if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) {
587585
decorateStartSendingTime(content);
588586
}

src/components/views/rooms/SendMessageComposer.tsx

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,35 +58,7 @@ import { ComposerType } from "../../../dispatcher/payloads/ComposerInsertPayload
5858
import { getSlashCommand, isSlashCommand, runSlashCommand, shouldSendAnyway } from "../../../editor/commands";
5959
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
6060
import { PosthogAnalytics } from "../../../PosthogAnalytics";
61-
import { getNestedReplyText, makeReplyMixIn } from '../../../utils/Reply';
62-
63-
interface IAddReplyOpts {
64-
permalinkCreator?: RoomPermalinkCreator;
65-
includeLegacyFallback?: boolean;
66-
}
67-
68-
function addReplyToMessageContent(
69-
content: IContent,
70-
replyToEvent: MatrixEvent,
71-
opts: IAddReplyOpts = {
72-
includeLegacyFallback: true,
73-
},
74-
): void {
75-
const replyContent = makeReplyMixIn(replyToEvent);
76-
Object.assign(content, replyContent);
77-
78-
if (opts.includeLegacyFallback) {
79-
// Part of Replies fallback support - prepend the text we're sending
80-
// with the text we're replying to
81-
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
82-
if (nestedReply) {
83-
if (content.formatted_body) {
84-
content.formatted_body = nestedReply.html + content.formatted_body;
85-
}
86-
content.body = nestedReply.body + content.body;
87-
}
88-
}
89-
}
61+
import { addReplyToMessageContent } from '../../../utils/Reply';
9062

9163
export function attachRelation(
9264
content: IContent,

src/i18n/strings/en_EN.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@
7171
"You do not have permission to start a conference call in this room": "You do not have permission to start a conference call in this room",
7272
"End conference": "End conference",
7373
"This will end the conference for everyone. Continue?": "This will end the conference for everyone. Continue?",
74-
"Replying With Files": "Replying With Files",
75-
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "At this time it is not possible to reply with a file. Would you like to upload this file without replying?",
76-
"Continue": "Continue",
7774
"The file '%(fileName)s' failed to upload.": "The file '%(fileName)s' failed to upload.",
7875
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "The file '%(fileName)s' exceeds this homeserver's size limit for uploads",
7976
"Upload Failed": "Upload Failed",
@@ -455,6 +452,7 @@
455452
"Invites user with given id to current room": "Invites user with given id to current room",
456453
"Use an identity server": "Use an identity server",
457454
"Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.",
455+
"Continue": "Continue",
458456
"Use an identity server to invite by email. Manage in Settings.": "Use an identity server to invite by email. Manage in Settings.",
459457
"Joins room with given address": "Joins room with given address",
460458
"Leave room": "Leave room",

src/utils/Reply.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,31 @@ export function shouldDisplayReply(event: MatrixEvent): boolean {
184184

185185
return !!inReplyTo.event_id;
186186
}
187+
188+
interface IAddReplyOpts {
189+
permalinkCreator?: RoomPermalinkCreator;
190+
includeLegacyFallback?: boolean;
191+
}
192+
193+
export function addReplyToMessageContent(
194+
content: IContent,
195+
replyToEvent: MatrixEvent,
196+
opts: IAddReplyOpts = {
197+
includeLegacyFallback: true,
198+
},
199+
): void {
200+
const replyContent = makeReplyMixIn(replyToEvent);
201+
Object.assign(content, replyContent);
202+
203+
if (opts.includeLegacyFallback) {
204+
// Part of Replies fallback support - prepend the text we're sending
205+
// with the text we're replying to
206+
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
207+
if (nestedReply) {
208+
if (content.formatted_body) {
209+
content.formatted_body = nestedReply.html + content.formatted_body;
210+
}
211+
content.body = nestedReply.body + content.body;
212+
}
213+
}
214+
}

0 commit comments

Comments
 (0)