feat(threads): up-arrow edits your last thread reply (+ fix cross-fire)

The thread composer reused RoomInput's hardcoded editableName="RoomInput", so
the main timeline's global up-arrow "edit last message" handler fired while
focused in a thread composer and targeted the MAIN timeline's last message
(wrong), and there was no up-arrow edit for the thread itself.

- Make editableName a RoomInput prop (default "RoomInput"); the thread composer
  passes "ThreadInput", so the two up-arrow handlers never cross-fire.
- Add an up-arrow-edit handler to ThreadTimeline (parity with RoomTimeline):
  empty thread composer + Up -> edit the latest editable reply in that thread,
  using thread.liveTimeline + canEditEvent + setEditId.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 20:28:26 -04:00
co-authored by Claude Opus 4.8
parent 61f1733f50
commit f155a4dc22
4 changed files with 41 additions and 4 deletions
+6 -2
View File
@@ -151,9 +151,13 @@ interface RoomInputProps {
roomId: string;
room: Room;
threadRootId?: string;
// Identifies this composer to global key handlers (e.g. the up-arrow "edit last
// message" handler). Threads pass a distinct name so the main timeline's handler
// doesn't fire for the thread composer, and vice-versa.
editableName?: string;
}
export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
({ editor, fileDropContainerRef, roomId, room, threadRootId }, ref) => {
({ editor, fileDropContainerRef, roomId, room, threadRootId, editableName = 'RoomInput' }, ref) => {
const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication();
const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline');
@@ -981,7 +985,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
)}
<ScheduledMessagesTray roomId={roomId} />
<CustomEditor
editableName="RoomInput"
editableName={editableName}
editor={editor}
placeholder="Send a message..."
onKeyDown={handleKeyDown}