fix(chat): 运行中逐帧贴底锁,修复块外框与内容移动不同步

This commit is contained in:
JOJO 2026-08-03 23:18:49 +08:00
parent a7a40a8a2f
commit 677604b538

View File

@ -1215,6 +1215,52 @@ const { anchorBlockElement, stopAll: stopBlockExpansionAnchors } = useBlockExpan
scrollRef,
{ stopScroll }
);
//
// stick resize ResizeObserver rAF scrollTop
// .messages-flow virtua
// 1~2 //
//
// rAF scrollHeight
// escapedFromLock/isAtBottom false
// useBlockExpansionAnchor
let liveStickLockRaf: number | null = null;
function liveStickLockTick() {
liveStickLockRaf = null;
if (!props.streamingMessage) return;
const el = scrollRef.value;
if (el && isAtBottom.value && !escapedFromLock.value) {
const maxTop = el.scrollHeight - el.clientHeight;
if (maxTop - el.scrollTop > 1) {
markProgrammaticHint('ChatArea.liveStickLock');
el.scrollTop = maxTop;
}
}
liveStickLockRaf = requestAnimationFrame(liveStickLockTick);
}
function stopLiveStickLock() {
if (liveStickLockRaf !== null) {
cancelAnimationFrame(liveStickLockRaf);
liveStickLockRaf = null;
}
}
watch(
() => props.streamingMessage,
(streaming) => {
if (streaming) {
if (liveStickLockRaf === null) {
liveStickLockRaf = requestAnimationFrame(liveStickLockTick);
}
} else {
stopLiveStickLock();
}
},
{ immediate: true }
);
const thinkingRefs = new Map<string, HTMLElement | null>();
let scrollbarResizeObserver: ResizeObserver | null = null;
let bounceTraceCount = 0;
@ -2082,6 +2128,7 @@ watch(scrollRef, () => {
onBeforeUnmount(() => {
detachBounceListener();
stopBlockExpansionAnchors();
stopLiveStickLock();
if (scrollbarResizeObserver) {
scrollbarResizeObserver.disconnect();
scrollbarResizeObserver = null;