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

Commit

Permalink
Allow replying to messages with files (temporarily without m.relates_to)
Browse files Browse the repository at this point in the history
  • Loading branch information
chayleaf committed Aug 26, 2021
1 parent d489ba7 commit 108b0a7
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/ContentMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
import { IUpload } from "./models/IUpload";
import { IAbortablePromise, IImageInfo } from "matrix-js-sdk/src/@types/partials";
import { BlurhashEncoder } from "./BlurhashEncoder";
import SettingsStore from "./settings/SettingsStore";

const MAX_WIDTH = 800;
const MAX_HEIGHT = 600;
Expand Down Expand Up @@ -442,7 +443,7 @@ export default class ContentMessages {
}

const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
if (isQuoting) {
if (isQuoting && !SettingsStore.getValue("feature_message_attachments")) {
// FIXME: Using an import will result in Element crashing
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, {
Expand Down
5 changes: 3 additions & 2 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ export default class RoomView extends React.Component<IProps, IState> {
break;
case 'picture_snapshot': {
const promAfter = (SettingsStore.getValue("feature_message_attachments") && this.messageComposer
&& !this.messageComposer.state.isComposerEmpty) ?
&& (!this.messageComposer.state.isComposerEmpty || this.messageComposer.props.replyToEvent)) ?
(event: ISendEventResponse) => {
return this.messageComposer.sendMessage(event.event_id);
} : null;
Expand Down Expand Up @@ -1255,7 +1255,8 @@ export default class RoomView extends React.Component<IProps, IState> {
ev.stopPropagation();
ev.preventDefault();
const promAfter = (SettingsStore.getValue("feature_message_attachments") && this.messageComposer
&& ev.dataTransfer.files.length === 1 && !this.messageComposer.state.isComposerEmpty) ?
&& ev.dataTransfer.files.length === 1
&& (!this.messageComposer.state.isComposerEmpty || this.messageComposer.props.replyToEvent)) ?
(event: ISendEventResponse) => {
return this.messageComposer.sendMessage(event.event_id);
} : null;
Expand Down
3 changes: 2 additions & 1 deletion src/components/views/rooms/MessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ class UploadButton extends React.Component<IUploadButtonProps> {
}

const promAfter = (SettingsStore.getValue("feature_message_attachments") && this.props.composer
&& ev.target.files.length === 1 && !this.props.composer.state.isComposerEmpty) ?
&& ev.target.files.length === 1
&& (!this.props.composer.state.isComposerEmpty || this.props.composer.props.replyToEvent)) ?
(event: ISendEventResponse) => {
return this.props.composer.sendMessage(event.event_id);
} : null;
Expand Down
19 changes: 14 additions & 5 deletions src/components/views/rooms/SendMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import ErrorDialog from "../dialogs/ErrorDialog";
import QuestionDialog from "../dialogs/QuestionDialog";
import { ActionPayload } from "../../../dispatcher/payloads";
import { ISendEventResponse } from 'matrix-js-sdk/src/@types/requests';
import DocumentOffset from '../../../editor/offset';

function addReplyToMessageContent(
content: IContent,
Expand Down Expand Up @@ -110,15 +111,18 @@ export function createMessageContent(
body: body,
};
const formattedBody = htmlSerializeIfNeeded(model, { forceHTML: !!replyToEvent });
if (formattedBody) {
if (formattedBody || replyToEvent) {
content.format = "org.matrix.custom.html";
content.formatted_body = formattedBody;
content.formatted_body = formattedBody || body;
}

if (replyToEvent) {
addReplyToMessageContent(content, replyToEvent, permalinkCreator);
}

// TODO: Currently, an attachment will override a reply.
// This allows replying with images, but removes the reply relation from the message.
// When/if we get the ability to add multiple relations, this will be fixed.
if (attachEventId) {
addAttachmentToMessageContent(content, attachEventId);
}
Expand Down Expand Up @@ -363,7 +367,12 @@ export default class SendMessageComposer extends React.Component<IProps> {

public async sendMessage(attachmentEventId?: string): Promise<void> {
if (this.model.isEmpty) {
return;
if (!attachmentEventId) {
return;
}
// If replying with just an attachment, add empty text to model so it has at least one part.
// Otherwise, various functions expecting at least one part will fail.
this.model.update(" ", "insertText", new DocumentOffset(1, true));
}

const replyToEvent = this.props.replyToEvent;
Expand Down Expand Up @@ -543,8 +552,8 @@ export default class SendMessageComposer extends React.Component<IProps> {
// We check text/rtf instead of text/plain as when copy+pasting a file from Finder or Gnome Image Viewer
// it puts the filename in as text/plain which we want to ignore.
if (clipboardData.files.length && !clipboardData.types.includes("text/rtf")) {
const promAfter = (SettingsStore.getValue("feature_message_attachents")
&& clipboardData.files.length === 1 && !this.model.isEmpty) ?
const promAfter = (SettingsStore.getValue("feature_message_attachments")
&& clipboardData.files.length === 1 && (!this.model.isEmpty || this.props.replyToEvent)) ?
(event: ISendEventResponse) => {
return this.sendMessage(event.event_id);
} : null;
Expand Down

0 comments on commit 108b0a7

Please sign in to comment.