feat: add thread functionality to room features

- Enhance RoomInput to support sending messages as replies in threads by adding `threadRootId` prop.
- Update RoomTimeline to manage active thread state and handle opening threads.
- Implement ThreadView component to display thread messages and input.
- Create HomeThreadsCategory to list threads user has participated in.
- Introduce activeThreadIdAtomFamily to manage active thread state across rooms.
This commit is contained in:
2026-03-13 00:44:33 +11:00
parent 37f4297972
commit ced29a6571
9 changed files with 1039 additions and 44 deletions

View File

@@ -126,9 +126,11 @@ interface RoomInputProps {
fileDropContainerRef: RefObject<HTMLElement>;
roomId: string;
room: Room;
/** When provided, all messages are sent as replies in this thread. */
threadRootId?: string;
}
export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
({ editor, fileDropContainerRef, roomId, room }, ref) => {
({ editor, fileDropContainerRef, roomId, room, threadRootId }, ref) => {
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline');
@@ -388,13 +390,20 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
content['m.relates_to'].rel_type = RelationType.Thread;
content['m.relates_to'].is_falling_back = false;
}
} else if (threadRootId) {
content['m.relates_to'] = {
rel_type: RelationType.Thread,
event_id: threadRootId,
is_falling_back: true,
'm.in_reply_to': { event_id: threadRootId },
};
}
mx.sendMessage(roomId, content as any);
resetEditor(editor);
resetEditorHistory(editor);
setReplyDraft(undefined);
sendTypingStatus(false);
}, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft, isMarkdown, commands, autoConvertEmoticons]);
}, [mx, roomId, threadRootId, editor, replyDraft, sendTypingStatus, setReplyDraft, isMarkdown, commands, autoConvertEmoticons]);
const handleKeyDown: KeyboardEventHandler = useCallback(
(evt) => {