mirror of
https://github.com/element-hq/element-web
synced 2024-11-29 21:08:58 +03:00
Allow sending files as replies as per MSC3676 (#8020)
This commit is contained in:
parent
14653d1378
commit
dd53b226eb
4 changed files with 51 additions and 55 deletions
|
@ -16,7 +16,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { IUploadOpts } from "matrix-js-sdk/src/@types/requests";
|
||||
import { MsgType } from "matrix-js-sdk/src/@types/event";
|
||||
|
@ -24,7 +23,7 @@ import encrypt from "browser-encrypt-attachment";
|
|||
import extractPngChunks from "png-chunks-extract";
|
||||
import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { IEventRelation, ISendEventResponse } from "matrix-js-sdk/src/matrix";
|
||||
import { IEventRelation, ISendEventResponse, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
|
||||
|
||||
import { IEncryptedFile, IMediaEventInfo } from "./customisations/models/IMediaEventContent";
|
||||
|
@ -32,7 +31,6 @@ import dis from './dispatcher/dispatcher';
|
|||
import * as sdk from './index';
|
||||
import { _t } from './languageHandler';
|
||||
import Modal from './Modal';
|
||||
import RoomViewStore from './stores/RoomViewStore';
|
||||
import Spinner from "./components/views/elements/Spinner";
|
||||
import { Action } from "./dispatcher/actions";
|
||||
import {
|
||||
|
@ -47,6 +45,8 @@ import { BlurhashEncoder } from "./BlurhashEncoder";
|
|||
import SettingsStore from "./settings/SettingsStore";
|
||||
import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerformanceMetrics";
|
||||
import { TimelineRenderingType } from "./contexts/RoomContext";
|
||||
import RoomViewStore from "./stores/RoomViewStore";
|
||||
import { addReplyToMessageContent } from "./utils/Reply";
|
||||
|
||||
const MAX_WIDTH = 800;
|
||||
const MAX_HEIGHT = 600;
|
||||
|
@ -457,25 +457,7 @@ export default class ContentMessages {
|
|||
return;
|
||||
}
|
||||
|
||||
const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
|
||||
if (isQuoting) {
|
||||
// FIXME: Using an import will result in Element crashing
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, {
|
||||
title: _t('Replying With Files'),
|
||||
description: (
|
||||
<div>{ _t(
|
||||
'At this time it is not possible to reply with a file. ' +
|
||||
'Would you like to upload this file without replying?',
|
||||
) }</div>
|
||||
),
|
||||
hasCancelButton: true,
|
||||
button: _t("Continue"),
|
||||
});
|
||||
const [shouldUpload] = await finished;
|
||||
if (!shouldUpload) return;
|
||||
}
|
||||
|
||||
const replyToEvent = RoomViewStore.getQuotingEvent();
|
||||
if (!this.mediaConfig) { // hot-path optimization to not flash a spinner if we don't need to
|
||||
const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
|
||||
await this.ensureMediaConfigFetched(matrixClient);
|
||||
|
@ -528,7 +510,16 @@ export default class ContentMessages {
|
|||
}
|
||||
}
|
||||
|
||||
promBefore = this.sendContentToRoom(file, roomId, relation, matrixClient, promBefore);
|
||||
promBefore = this.sendContentToRoom(file, roomId, relation, matrixClient, replyToEvent, promBefore);
|
||||
}
|
||||
|
||||
if (replyToEvent) {
|
||||
// Clear event being replied to
|
||||
dis.dispatch({
|
||||
action: "reply_to_event",
|
||||
event: null,
|
||||
context,
|
||||
});
|
||||
}
|
||||
|
||||
// Focus the correct composer
|
||||
|
@ -569,6 +560,7 @@ export default class ContentMessages {
|
|||
roomId: string,
|
||||
relation: IEventRelation | undefined,
|
||||
matrixClient: MatrixClient,
|
||||
replyToEvent: MatrixEvent | undefined,
|
||||
promBefore: Promise<any>,
|
||||
) {
|
||||
const content: IContent = {
|
||||
|
@ -583,6 +575,12 @@ export default class ContentMessages {
|
|||
content["m.relates_to"] = relation;
|
||||
}
|
||||
|
||||
if (replyToEvent) {
|
||||
addReplyToMessageContent(content, replyToEvent, {
|
||||
includeLegacyFallback: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) {
|
||||
decorateStartSendingTime(content);
|
||||
}
|
|
@ -58,35 +58,7 @@ import { ComposerType } from "../../../dispatcher/payloads/ComposerInsertPayload
|
|||
import { getSlashCommand, isSlashCommand, runSlashCommand, shouldSendAnyway } from "../../../editor/commands";
|
||||
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
|
||||
import { PosthogAnalytics } from "../../../PosthogAnalytics";
|
||||
import { getNestedReplyText, makeReplyMixIn } from '../../../utils/Reply';
|
||||
|
||||
interface IAddReplyOpts {
|
||||
permalinkCreator?: RoomPermalinkCreator;
|
||||
includeLegacyFallback?: boolean;
|
||||
}
|
||||
|
||||
function addReplyToMessageContent(
|
||||
content: IContent,
|
||||
replyToEvent: MatrixEvent,
|
||||
opts: IAddReplyOpts = {
|
||||
includeLegacyFallback: true,
|
||||
},
|
||||
): void {
|
||||
const replyContent = makeReplyMixIn(replyToEvent);
|
||||
Object.assign(content, replyContent);
|
||||
|
||||
if (opts.includeLegacyFallback) {
|
||||
// Part of Replies fallback support - prepend the text we're sending
|
||||
// with the text we're replying to
|
||||
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
|
||||
if (nestedReply) {
|
||||
if (content.formatted_body) {
|
||||
content.formatted_body = nestedReply.html + content.formatted_body;
|
||||
}
|
||||
content.body = nestedReply.body + content.body;
|
||||
}
|
||||
}
|
||||
}
|
||||
import { addReplyToMessageContent } from '../../../utils/Reply';
|
||||
|
||||
export function attachRelation(
|
||||
content: IContent,
|
||||
|
|
|
@ -71,9 +71,6 @@
|
|||
"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",
|
||||
"End conference": "End conference",
|
||||
"This will end the conference for everyone. Continue?": "This will end the conference for everyone. Continue?",
|
||||
"Replying With Files": "Replying With Files",
|
||||
"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?",
|
||||
"Continue": "Continue",
|
||||
"The file '%(fileName)s' failed to upload.": "The file '%(fileName)s' failed to upload.",
|
||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "The file '%(fileName)s' exceeds this homeserver's size limit for uploads",
|
||||
"Upload Failed": "Upload Failed",
|
||||
|
@ -455,6 +452,7 @@
|
|||
"Invites user with given id to current room": "Invites user with given id to current room",
|
||||
"Use an identity server": "Use an identity server",
|
||||
"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.",
|
||||
"Continue": "Continue",
|
||||
"Use an identity server to invite by email. Manage in Settings.": "Use an identity server to invite by email. Manage in Settings.",
|
||||
"Joins room with given address": "Joins room with given address",
|
||||
"Leave room": "Leave room",
|
||||
|
|
|
@ -184,3 +184,31 @@ export function shouldDisplayReply(event: MatrixEvent): boolean {
|
|||
|
||||
return !!inReplyTo.event_id;
|
||||
}
|
||||
|
||||
interface IAddReplyOpts {
|
||||
permalinkCreator?: RoomPermalinkCreator;
|
||||
includeLegacyFallback?: boolean;
|
||||
}
|
||||
|
||||
export function addReplyToMessageContent(
|
||||
content: IContent,
|
||||
replyToEvent: MatrixEvent,
|
||||
opts: IAddReplyOpts = {
|
||||
includeLegacyFallback: true,
|
||||
},
|
||||
): void {
|
||||
const replyContent = makeReplyMixIn(replyToEvent);
|
||||
Object.assign(content, replyContent);
|
||||
|
||||
if (opts.includeLegacyFallback) {
|
||||
// Part of Replies fallback support - prepend the text we're sending
|
||||
// with the text we're replying to
|
||||
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
|
||||
if (nestedReply) {
|
||||
if (content.formatted_body) {
|
||||
content.formatted_body = nestedReply.html + content.formatted_body;
|
||||
}
|
||||
content.body = nestedReply.body + content.body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue