fix(webui): preserve user scroll ownership near tail (#5193)

This commit is contained in:
chengyongru
2026-07-31 23:37:26 +08:00
committed by GitHub
parent dda9b61b1e
commit 172fe4f991
4 changed files with 191 additions and 11 deletions
@@ -542,7 +542,7 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
const near = distance < NEAR_BOTTOM_PX;
const owner = threadMotionRef.current?.observeScroll(near) ?? "automatic";
const logicallyAtBottom = owner === "automatic" || near;
const logicallyAtBottom = owner === "automatic" || (owner === "navigation" && near);
setAtBottom((current) =>
current === logicallyAtBottom ? current : logicallyAtBottom,
);
@@ -557,6 +557,7 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
if (!direction) return;
threadMotionRef.current?.handleUserScrollIntent(
canScrollInDirection(el, direction),
direction === "forward",
);
};
const handleWheel = (event: WheelEvent) => {
@@ -572,20 +573,21 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
const handlePointerDown = (event: PointerEvent) => {
if (event.button === 0 && event.target === el) yieldCameraToUser();
};
let touchStartY: number | null = null;
let lastTouchY: number | null = null;
const handleTouchStart = (event: TouchEvent) => {
touchStartY = event.touches[0]?.clientY ?? null;
lastTouchY = event.touches[0]?.clientY ?? null;
};
const handleTouchMove = (event: TouchEvent) => {
const currentY = event.touches[0]?.clientY;
const scrollDeltaY =
touchStartY !== null && currentY !== undefined
? touchStartY - currentY
lastTouchY !== null && currentY !== undefined
? lastTouchY - currentY
: 0;
lastTouchY = currentY ?? null;
handleDirectionalInput(directionFromDelta(scrollDeltaY));
};
const handleTouchEnd = () => {
touchStartY = null;
lastTouchY = null;
};
const handleKeyDown = (event: KeyboardEvent) => {
if (