diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index adbb2e9a0..1336b45f4 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -705,6 +705,34 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli })); return; } + // [Gitea #212] Your OWN new message always comes into view — that is + // what pressing Send means — even if the at-bottom flag went stale + // (in-place growth like a poll gaining a row briefly pushes the anchor + // out of the viewport) or you had scrolled up to read. + const ownNewMessage = + mEvt.getSender() === mx.getUserId() && + !mEvt.isRelation() && + !mEvt.isRedaction() && + !mEvt.isState() && + mEvt.getType() !== MessageEvent.Reaction; + if (ownNewMessage) { + if (atLiveEndRef.current) { + setAtBottom(true); + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = true; + setTimeline((ct) => ({ + ...ct, + range: { start: ct.range.start + 1, end: ct.range.end + 1 }, + })); + } else { + // Paginated back into history: jump to the live end like the + // "Jump to Latest" button does. + setTimeline(getInitialTimeline(room)); + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = false; + } + return; + } setTimeline((ct) => ({ ...ct })); if (!unreadInfo) { setUnreadInfo(getRoomUnreadInfo(room));