From 854a929c925671c00104c6ab5cb4ba57f3309134 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 25 Oct 2024 03:29:32 +0300 Subject: [PATCH] web/timeline: fix scroll to bottom firing incorrectly in some cases --- web/src/ui/roomcontext.ts | 5 ++++- web/src/ui/timeline/TimelineView.tsx | 11 +++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/web/src/ui/roomcontext.ts b/web/src/ui/roomcontext.ts index 8090655..0fa7557 100644 --- a/web/src/ui/roomcontext.ts +++ b/web/src/ui/roomcontext.ts @@ -28,11 +28,14 @@ export class RoomContextData { public setEditing: (evt: MemDBEvent | null) => void = noop("setEditing") public isEditing = new NonNullCachedEventDispatcher(false) public ownMessages: EventRowID[] = [] + public scrolledToBottom = true constructor(public store: RoomStateStore) {} scrollToBottom() { - this.timelineBottomRef.current?.scrollIntoView() + if (this.scrolledToBottom) { + this.timelineBottomRef.current?.scrollIntoView() + } } } diff --git a/web/src/ui/timeline/TimelineView.tsx b/web/src/ui/timeline/TimelineView.tsx index 8e1a3e6..3a18de0 100644 --- a/web/src/ui/timeline/TimelineView.tsx +++ b/web/src/ui/timeline/TimelineView.tsx @@ -36,7 +36,6 @@ const TimelineView = () => { const timelineViewRef = useRef(null) const prevOldestTimelineRow = useRef(0) const oldScrollHeight = useRef(0) - const scrolledToBottom = useRef(true) const focused = useFocus() // When the user scrolls the timeline manually, remember if they were at the bottom, @@ -46,15 +45,15 @@ const TimelineView = () => { return } const timelineView = timelineViewRef.current - scrolledToBottom.current = timelineView.scrollTop + timelineView.clientHeight + 1 >= timelineView.scrollHeight - }, []) + roomCtx.scrolledToBottom = timelineView.scrollTop + timelineView.clientHeight + 1 >= timelineView.scrollHeight + }, [roomCtx]) // Save the scroll height prior to updating the timeline, so that we can adjust the scroll position if needed. if (timelineViewRef.current) { oldScrollHeight.current = timelineViewRef.current.scrollHeight } useLayoutEffect(() => { const bottomRef = roomCtx.timelineBottomRef - if (bottomRef.current && scrolledToBottom.current) { + if (bottomRef.current && roomCtx.scrolledToBottom) { // For any timeline changes, if we were at the bottom, scroll to the new bottom bottomRef.current.scrollIntoView() } else if (timelineViewRef.current && prevOldestTimelineRow.current > (timeline[0]?.timeline_rowid ?? 0)) { @@ -72,7 +71,7 @@ const TimelineView = () => { useEffect(() => { const newestEvent = timeline[timeline.length - 1] if ( - scrolledToBottom.current + roomCtx.scrolledToBottom && focused && newestEvent && newestEvent.timeline_rowid > 0 @@ -85,7 +84,7 @@ const TimelineView = () => { err => console.error(`Failed to send read receipt for ${newestEvent.event_id}:`, err), ) } - }, [focused, client, room, timeline]) + }, [focused, client, roomCtx, room, timeline]) useEffect(() => { const topElem = topRef.current if (!topElem) {