@@ -75,6 +78,8 @@ defineProps<{
formatSearchTopic: (filters: Record) => string;
formatSearchTime: (filters: Record) => string;
streamingMessage: boolean;
+ registerCollapseContent?: (key: string, el: Element | null) => void;
+ collapseKey?: string;
}>();
defineEmits<{ (event: 'toggle'): void }>();
diff --git a/static/src/composables/useScrollControl.ts b/static/src/composables/useScrollControl.ts
index 8820d5e..2791c1d 100644
--- a/static/src/composables/useScrollControl.ts
+++ b/static/src/composables/useScrollControl.ts
@@ -10,6 +10,8 @@ type ScrollContext = {
autoScrollEnabled?: boolean;
userScrolling?: boolean;
isOutputActive?: () => boolean;
+ streamingMessage?: boolean;
+ hasPendingToolActions?: () => boolean;
};
type ScrollOptions = {
@@ -106,6 +108,21 @@ export function toggleScrollLock(ctx: ScrollContext) {
return nextState;
}
+/**
+ * 在页面初始化/刷新后同步滚动锁定的默认状态:
+ * 仅当存在输出(流式中或有未完成工具)时才保持锁定,否则自动解锁。
+ */
+export function normalizeScrollLock(ctx: ScrollContext) {
+ const active =
+ (typeof ctx.isOutputActive === 'function' ? ctx.isOutputActive() : false) ||
+ !!ctx.streamingMessage ||
+ (typeof ctx.hasPendingToolActions === 'function' ? ctx.hasPendingToolActions() : false);
+
+ if (!active && ctx.autoScrollEnabled) {
+ ctx.chatSetScrollState?.({ autoScrollEnabled: false, userScrolling: false });
+ }
+}
+
export function scrollThinkingToBottom(ctx: ScrollContext, blockId: string) {
if (!blockId) {
return;
diff --git a/static/src/styles/components/chat/_chat-area.scss b/static/src/styles/components/chat/_chat-area.scss
index b5ae702..4d1ed23 100644
--- a/static/src/styles/components/chat/_chat-area.scss
+++ b/static/src/styles/components/chat/_chat-area.scss
@@ -266,11 +266,12 @@
overflow: hidden;
opacity: 0;
transition:
- max-height 0.26s cubic-bezier(0.4, 0, 0.2, 1),
- opacity 0.26s cubic-bezier(0.4, 0, 0.2, 1);
+ max-height 260ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 220ms cubic-bezier(0.4, 0, 0.2, 1);
/* 始终隐藏滚动条,避免堆叠模式展开时闪现 */
scrollbar-width: none;
-ms-overflow-style: none;
+ will-change: max-height, opacity;
}
.collapsible-content::-webkit-scrollbar {
@@ -278,7 +279,7 @@
}
.collapsible-block.expanded .collapsible-content {
- max-height: 600px;
+ max-height: var(--collapse-max, 600px);
overflow-y: auto;
opacity: 1;
}
@@ -439,8 +440,8 @@
.stacked-block .collapsible-content {
transition:
- max-height 280ms cubic-bezier(0.25, 0.9, 0.3, 1),
- opacity 220ms ease;
+ max-height 260ms cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 220ms cubic-bezier(0.4, 0, 0.2, 1);
}
.progress-indicator {