@@ -194,7 +194,7 @@ export function RoomTimeline({
194194 atBottomRef . current = val ;
195195 } , [ ] ) ;
196196
197- const shift = ! atBottomState ;
197+ const [ shift , setShift ] = useState ( false ) ;
198198 const [ topSpacerHeight , setTopSpacerHeight ] = useState ( 0 ) ;
199199
200200 const topSpacerHeightRef = useRef ( 0 ) ;
@@ -212,24 +212,22 @@ export function RoomTimeline({
212212 }
213213
214214 const processedEventsRef = useRef < ProcessedEvent [ ] > ( [ ] ) ;
215-
216215 const timelineSyncRef = useRef < typeof timelineSync > ( null as unknown as typeof timelineSync ) ;
217216
218- const scrollToBottom = useCallback ( ( behavior ?: 'instant' | 'smooth' ) => {
219- if ( ! vListRef . current ) return ;
220- const lastIndex = processedEventsRef . current . length - 1 ;
221- if ( lastIndex < 0 ) return ;
222-
223- vListRef . current . scrollTo ( vListRef . current . scrollSize ) ;
217+ const scrollToBottom = useCallback (
218+ ( behavior ?: 'instant' | 'smooth' ) => {
219+ if ( ! vListRef . current ) return ;
220+ const lastIndex = processedEventsRef . current . length - 1 ;
221+ if ( lastIndex < 0 ) return ;
224222
225- if ( behavior === 'instant' ) {
226- setTimeout ( ( ) => {
227- vListRef . current ?. scrollToIndex ( processedEventsRef . current . length - 1 , {
228- align : 'end' ,
229- } ) ;
230- } , 80 ) ;
231- }
232- } , [ ] ) ;
223+ if ( behavior === 'smooth' && ! reducedMotion ) {
224+ vListRef . current . scrollToIndex ( lastIndex , { align : 'end' , smooth : true } ) ;
225+ } else {
226+ vListRef . current . scrollTo ( vListRef . current . scrollSize ) ;
227+ }
228+ } ,
229+ [ reducedMotion ]
230+ ) ;
233231
234232 const timelineSync = useTimelineSync ( {
235233 room,
@@ -295,7 +293,7 @@ export function RoomTimeline({
295293 if ( Math . abs ( prev - newH ) > 2 ) {
296294 topSpacerHeightRef . current = newH ;
297295 setTopSpacerHeight ( newH ) ;
298- if ( prev > 0 && newH === 0 && eventsLengthRef . current > 0 ) {
296+ if ( prev > 0 && newH === 0 && processedEventsRef . current . length > 0 ) {
299297 requestAnimationFrame ( ( ) => {
300298 vListRef . current ?. scrollToIndex ( processedEventsRef . current . length - 1 , { align : 'end' } ) ;
301299 } ) ;
@@ -316,12 +314,14 @@ export function RoomTimeline({
316314 prevBackwardStatusRef . current = timelineSync . backwardStatus ;
317315 if ( timelineSync . backwardStatus === 'loading' ) {
318316 wasAtBottomBeforePaginationRef . current = atBottomRef . current ;
317+ if ( ! atBottomRef . current ) setShift ( true ) ;
319318 } else if ( prev === 'loading' && timelineSync . backwardStatus === 'idle' ) {
319+ setShift ( false ) ;
320320 if ( wasAtBottomBeforePaginationRef . current ) {
321- vListRef . current ?. scrollToIndex ( eventsLengthRef . current - 1 , { align : 'end' } ) ;
321+ vListRef . current ?. scrollToIndex ( processedEventsRef . current . length - 1 , { align : 'end' } ) ;
322322 }
323323 }
324- } , [ timelineSync . backwardStatus , shift ] ) ;
324+ } , [ timelineSync . backwardStatus ] ) ;
325325
326326 useEffect ( ( ) => {
327327 let timeoutId : ReturnType < typeof setTimeout > | undefined ;
@@ -382,7 +382,7 @@ export function RoomTimeline({
382382 const shrank = newHeight < prev ;
383383
384384 if ( shrank && atBottom ) {
385- vListRef . current ?. scrollToIndex ( processedEventsRef . current . length - 1 , { align : 'end' } ) ;
385+ vListRef . current ?. scrollTo ( vListRef . current . scrollSize ) ;
386386 }
387387 prevViewportHeightRef . current = newHeight ;
388388 } ) ;
0 commit comments