Skip to content

Commit 23bbebb

Browse files
committed
fix conflicting shift state making messages overlap
1 parent 1f96a47 commit 23bbebb

2 files changed

Lines changed: 25 additions & 20 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: patch
3+
---
4+
5+
Fix messages overlapping in timeline.

src/app/features/room/RoomTimeline.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)