fix(chat): do not snap back to the end after a width resize
A slow edge drag settles the resize detector repeatedly, and every settle replayed the instant return to the live edge — reading as exactly the jumping the resize suspension removes. Stay where the reader is; geometry changed, and the next explicit action or stream correction re-engages the edge as usual.
This commit is contained in:
@@ -510,9 +510,11 @@ export const useChatTimelineScroll = ({
|
|||||||
|
|
||||||
// While the list width is resizing, every pinning write fights the
|
// While the list width is resizing, every pinning write fights the
|
||||||
// per-frame row re-measure and the pinned viewport shakes. Corrections
|
// per-frame row re-measure and the pinned viewport shakes. Corrections
|
||||||
// stand down for the whole resize (visible content is held by the list's
|
// stand down for the whole resize and the visible content is held by the
|
||||||
// size compensation instead), and the live edge is re-asserted once with
|
// list's size compensation instead. Deliberately NO snap back to the end
|
||||||
// a single instant write after the resize settles.
|
// afterwards: a slow drag settles repeatedly, and each snap reads as the
|
||||||
|
// very jump this suspension removes — geometry changed, staying where the
|
||||||
|
// reader is beats re-asserting the edge.
|
||||||
const widthResizingRef = React.useRef(false);
|
const widthResizingRef = React.useRef(false);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!scrollNode || typeof ResizeObserver === 'undefined') return;
|
if (!scrollNode || typeof ResizeObserver === 'undefined') return;
|
||||||
@@ -532,10 +534,6 @@ export const useChatTimelineScroll = ({
|
|||||||
quietTimer = setTimeout(() => {
|
quietTimer = setTimeout(() => {
|
||||||
quietTimer = null;
|
quietTimer = null;
|
||||||
widthResizingRef.current = false;
|
widthResizingRef.current = false;
|
||||||
if (modeRef.current !== 'following-end' || !isLiveFollowActive()) return;
|
|
||||||
const node = listRef.current?.getScrollableNode();
|
|
||||||
if (!node) return;
|
|
||||||
node.scrollTop = node.scrollHeight + 4096;
|
|
||||||
}, 350);
|
}, 350);
|
||||||
});
|
});
|
||||||
observer.observe(scrollNode);
|
observer.observe(scrollNode);
|
||||||
@@ -543,7 +541,7 @@ export const useChatTimelineScroll = ({
|
|||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
if (quietTimer !== null) clearTimeout(quietTimer);
|
if (quietTimer !== null) clearTimeout(quietTimer);
|
||||||
};
|
};
|
||||||
}, [isLiveFollowActive, scrollNode]);
|
}, [scrollNode]);
|
||||||
|
|
||||||
const onTimelineDataChange = React.useCallback(() => {
|
const onTimelineDataChange = React.useCallback(() => {
|
||||||
if (widthResizingRef.current) return;
|
if (widthResizingRef.current) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user