Remove fallback replies & implement intentional mentions (#2138)

* Remove reply fallbacks & add m.mentions

(WIP) the typing on line 301 and 303 needs fixing but apart from that this is mint

* Less jank typing

* Mention the reply author in m.mentions

* Improve typing

* Fix typing in m.mentions finder

* Correctly iterate through editor children, properly handle @room, ...

..., don't mention the reply author when the reply author is ourself, don't add own user IDs when mentioning intentionally

* Formatting

* Add intentional mentions to edited messages

* refactor reusable code and fix todo

* parse mentions from all nodes

---------

Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com>
This commit is contained in:
nexy7574 2025-02-23 11:08:08 +00:00 committed by GitHub
parent dd4c1a94e6
commit 8d95758ed7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 83 additions and 28 deletions

View file

@ -35,7 +35,7 @@ import { useHover, useFocusWithin } from 'react-aria';
import { MatrixEvent, Room } from 'matrix-js-sdk';
import { Relations } from 'matrix-js-sdk/lib/models/relations';
import classNames from 'classnames';
import { EventType, RoomPinnedEventsEventContent } from 'matrix-js-sdk/lib/types';
import { RoomPinnedEventsEventContent } from 'matrix-js-sdk/lib/types';
import {
AvatarBase,
BubbleLayout,

View file

@ -21,7 +21,7 @@ import {
} from 'folds';
import { 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,
@ -43,6 +43,7 @@ import {
toPlainText,
trimCustomHtml,
useEditor,
getMentions,
} from '../../../components/editor';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
@ -50,7 +51,7 @@ import { UseStateProvider } from '../../../components/UseStateProvider';
import { EmojiBoard } from '../../../components/emoji-board';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { getEditedEvent, trimReplyFromFormattedBody } from '../../../utils/room';
import { getEditedEvent, getMentionContent, trimReplyFromFormattedBody } from '../../../utils/room';
import { mobileOrTablet } from '../../../utils/user-agent';
type MessageEditorProps = {
@ -74,19 +75,23 @@ export const MessageEditor = as<'div', MessageEditorProps>(
const getPrevBodyAndFormattedBody = useCallback((): [
string | undefined,
string | undefined
string | undefined,
IMentions | undefined
] => {
const evtId = mEvent.getId()!;
const evtTimeline = room.getTimelineForEvent(evtId);
const editedEvent =
evtTimeline && getEditedEvent(evtId, mEvent, evtTimeline.getTimelineSet());
const { body, formatted_body: customHtml }: Record<string, unknown> =
editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent();
const content: IContent = editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent();
const { body, formatted_body: customHtml }: Record<string, unknown> = content;
const mMentions: IMentions | undefined = content['m.mentions'];
return [
typeof body === 'string' ? body : undefined,
typeof customHtml === 'string' ? customHtml : undefined,
mMentions,
];
}, [room, mEvent]);
@ -101,7 +106,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
})
);
const [prevBody, prevCustomHtml] = getPrevBodyAndFormattedBody();
const [prevBody, prevCustomHtml, prevMentions] = getPrevBodyAndFormattedBody();
if (plainText === '') return undefined;
if (prevBody) {
@ -122,6 +127,15 @@ export const MessageEditor = as<'div', MessageEditorProps>(
body: plainText,
};
const mentionData = getMentions(mx, roomId, editor);
prevMentions?.user_ids?.forEach((prevMentionId) => {
mentionData.users.add(prevMentionId);
});
const mMentions = getMentionContent(Array.from(mentionData.users), mentionData.room);
newContent['m.mentions'] = mMentions;
if (!customHtmlEqualsPlainText(customHtml, plainText)) {
newContent.format = 'org.matrix.custom.html';
newContent.formatted_body = customHtml;