fix(timeline): your own new message always scrolls into view (#212)
CI / Build & Quality Checks (push) Successful in 1m34s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 7s
CI / Trigger Desktop Build (push) Successful in 9s
CI / Playwright smoke (e2e) (push) Successful in 3m1s
CI / Build & Quality Checks (push) Successful in 1m34s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 7s
CI / Trigger Desktop Build (push) Successful in 9s
CI / Playwright smoke (e2e) (push) Successful in 3m1s
Auto-scroll on a live event only ran while the at-bottom flag was true, so a stale flag (in-place growth like a poll gaining a row briefly pushes the anchor out of view; or simply having scrolled up) left your own just-sent message below the fold behind 'Jump to Latest'. An own non-relation, non-state, non-reaction event now always brings the live end into view: advance the range + smooth scroll when the window is at the live end, otherwise reset to the live timeline like the Jump to Latest button. Others' messages keep the current behaviour. Verified headless: scrolled up 600 px → Send → message visible, no Jump pill (before: Jump pill, message off-screen). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user