agent-Specialization/static/src/composables/useScrollControl.ts

57 lines
1.5 KiB
TypeScript

// 负责聊天区域滚动控制的通用方法,解耦 App.vue 中的 DOM 操作
type ScrollContext = {
getMessagesAreaElement?: () => HTMLElement | null;
getThinkingContentElement?: (blockId: string) => HTMLElement | null;
chatToggleScrollLockState?: () => boolean;
thinkingScrollLocks?: Map<string, boolean>;
_setScrollingFlag?: (value: boolean) => void;
autoScrollEnabled?: boolean;
userScrolling?: boolean;
};
export function scrollToBottom(ctx: ScrollContext) {
setTimeout(() => {
const messagesArea = ctx.getMessagesAreaElement?.();
if (!messagesArea) {
return;
}
if (typeof ctx._setScrollingFlag === 'function') {
ctx._setScrollingFlag(true);
}
messagesArea.scrollTop = messagesArea.scrollHeight;
setTimeout(() => {
if (typeof ctx._setScrollingFlag === 'function') {
ctx._setScrollingFlag(false);
}
}, 100);
}, 50);
}
export function conditionalScrollToBottom(ctx: ScrollContext) {
if (ctx.autoScrollEnabled === true && ctx.userScrolling === false) {
scrollToBottom(ctx);
}
}
export function toggleScrollLock(ctx: ScrollContext) {
const nextState = ctx.chatToggleScrollLockState?.() ?? false;
if (nextState) {
scrollToBottom(ctx);
}
return nextState;
}
export function scrollThinkingToBottom(ctx: ScrollContext, blockId: string) {
if (!blockId) {
return;
}
if (!ctx.thinkingScrollLocks?.get(blockId)) {
return;
}
const el = ctx.getThinkingContentElement?.(blockId);
if (el) {
el.scrollTop = el.scrollHeight;
}
}