57 lines
1.5 KiB
TypeScript
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;
|
|
}
|
|
}
|