Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove fallback replies & implement intentional mentions #2138

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
65 changes: 43 additions & 22 deletions src/app/features/room/RoomInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import React, {
} from 'react';
import { useAtom, useAtomValue } from 'jotai';
import { isKeyHotkey } from 'is-hotkey';
import { EventType, IContent, MsgType, RelationType, Room } from 'matrix-js-sdk';
import { EventType, IContent, MsgType, RelationType, Room, IMentions } from 'matrix-js-sdk';
import { ReactEditor } from 'slate-react';
import { Transforms, Editor } from 'slate';
import {Transforms, Editor, Descendant} from 'slate';
import {
Box,
Dialog,
Expand Down Expand Up @@ -53,10 +53,19 @@ import {
isEmptyEditor,
getBeginCommand,
trimCommand,
BlockType,
} from '../../components/editor';
import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board';
import { UseStateProvider } from '../../components/UseStateProvider';
import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import {
TUploadContent,
encryptFile,
getImageInfo,
getMxIdLocalPart,
mxcUrlToHttp,
isUserId,
getCanonicalAliasOrRoomId
} from '../../utils/matrix';
import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater';
import { useFilePicker } from '../../hooks/useFilePicker';
import { useFilePasteHandler } from '../../hooks/useFilePasteHandler';
Expand Down Expand Up @@ -96,19 +105,16 @@ import colorMXID from '../../../util/colorMXID';
import {
getAllParents,
getMemberDisplayName,
parseReplyBody,
parseReplyFormattedBody,
trimReplyFromBody,
trimReplyFromFormattedBody,
} from '../../utils/room';
import { sanitizeText } from '../../utils/sanitize';
import { CommandAutocomplete } from './CommandAutocomplete';
import { Command, SHRUG, TABLEFLIP, UNFLIP, useCommands } from '../../hooks/useCommands';
import { mobileOrTablet } from '../../utils/user-agent';
import { useElementSizeObserver } from '../../hooks/useElementSizeObserver';
import { ReplyLayout, ThreadIndicator } from '../../components/message';
import { roomToParentsAtom } from '../../state/room/roomToParents';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { InlineElement } from '../../components/editor/slate';

interface RoomInputProps {
editor: Editor;
Expand Down Expand Up @@ -248,7 +254,6 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
uploadBoardHandlers.current?.handleSend();

const commandName = getBeginCommand(editor);

let plainText = toPlainText(editor.children).trim();
let customHtml = trimCustomHtml(
toMatrixCustomHTML(editor.children, {
Expand Down Expand Up @@ -289,25 +294,41 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(

if (plainText === '') return;

let body = plainText;
let formattedBody = customHtml;
if (replyDraft) {
body = parseReplyBody(replyDraft.userId, trimReplyFromBody(replyDraft.body)) + body;
formattedBody =
parseReplyFormattedBody(
roomId,
replyDraft.userId,
replyDraft.eventId,
replyDraft.formattedBody
? trimReplyFromFormattedBody(replyDraft.formattedBody)
: sanitizeText(replyDraft.body)
) + formattedBody;
}
const body = plainText;
const formattedBody = customHtml;

const content: IContent = {
msgtype: msgType,
body,
};
const userIdMentions = new Set<string>();
if (replyDraft && replyDraft.userId !== mx.getUserId()) {
userIdMentions.add(replyDraft.userId);
nexy7574 marked this conversation as resolved.
Show resolved Hide resolved
}
let mentionsRoom = false;
editor.children.forEach((node: Descendant): void => {
if ("type" in node && node.type === BlockType.Paragraph) {
node.children?.forEach((child: InlineElement): void => {
if ("type" in child && child.type === BlockType.Mention) {
const mention = child;
if (mention.id === getCanonicalAliasOrRoomId(mx, roomId)) {
mentionsRoom = true
} else if (isUserId(mention.id) && mention.id !== mx.getUserId()) {
userIdMentions.add(mention.id)
}
}
})
}
})
const mMentions: IMentions = {}
if (userIdMentions.size > 0) {
mMentions.user_ids = Array.from(userIdMentions)
}
if(mentionsRoom) {
mMentions.room = true
}

content["m.mentions"] = mMentions
if (replyDraft || !customHtmlEqualsPlainText(formattedBody, body)) {
content.format = 'org.matrix.custom.html';
content.formatted_body = formattedBody;
Expand Down
40 changes: 37 additions & 3 deletions src/app/features/room/message/MessageEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import {
as,
config,
} from 'folds';
import { Editor, Transforms } from 'slate';
import {Descendant, Editor, Transforms} from 'slate';
import { ReactEditor } from 'slate-react';
import { IContent, MatrixEvent, RelationType, Room } from 'matrix-js-sdk';
import {IContent, IMentions, MatrixEvent, RelationType, Room} from 'matrix-js-sdk';
import { isKeyHotkey } from 'is-hotkey';
import {
AUTOCOMPLETE_PREFIXES,
Expand All @@ -42,7 +42,7 @@ import {
toMatrixCustomHTML,
toPlainText,
trimCustomHtml,
useEditor,
useEditor, BlockType,
} from '../../../components/editor';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
Expand All @@ -52,6 +52,10 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { getEditedEvent, trimReplyFromFormattedBody } from '../../../utils/room';
import { mobileOrTablet } from '../../../utils/user-agent';
import {InlineElement} from "../../../components/editor/slate";
import {getCanonicalAliasOrRoomId, isUserId} from "../../../utils/matrix";
import {useAtom} from "jotai/index";
import {roomIdToReplyDraftAtomFamily} from "../../../state/room/roomInputDrafts";

type MessageEditorProps = {
roomId: string;
Expand Down Expand Up @@ -122,6 +126,36 @@ export const MessageEditor = as<'div', MessageEditorProps>(
body: plainText,
};

const userIdMentions = new Set<string>();
// if (replyDraft && replyDraft.userId !== mx.getUserId()) {
// userIdMentions.add(replyDraft.userId);
// }
// TODO: Get the original message's reply to pick up the mention
let mentionsRoom = false;
editor.children.forEach((node: Descendant): void => {
if ("type" in node && node.type === BlockType.Paragraph) {
node.children?.forEach((child: InlineElement): void => {
if ("type" in child && child.type === BlockType.Mention) {
const mention = child;
if (mention.id === getCanonicalAliasOrRoomId(mx, roomId)) {
mentionsRoom = true
} else if (isUserId(mention.id) && mention.id !== mx.getUserId()) {
userIdMentions.add(mention.id)
}
}
})
}
})
const mMentions: IMentions = {}
if (userIdMentions.size > 0) {
mMentions.user_ids = Array.from(userIdMentions)
}
if(mentionsRoom) {
mMentions.room = true
}

newContent["m.mentions"] = mMentions

if (!customHtmlEqualsPlainText(customHtml, plainText)) {
newContent.format = 'org.matrix.custom.html';
newContent.formatted_body = customHtml;
Expand Down
Loading