diff --git a/static/src/components/chat/ChatArea.vue b/static/src/components/chat/ChatArea.vue
index ecb4077..d17a50d 100644
--- a/static/src/components/chat/ChatArea.vue
+++ b/static/src/components/chat/ChatArea.vue
@@ -131,6 +131,7 @@
:format-search-topic="formatSearchTopic"
:format-search-time="formatSearchTime"
:format-search-domains="formatSearchDomains"
+ @more-toggle="handleStackedMoreToggle"
/>
());
watch(
@@ -1102,6 +1097,10 @@ watch(
prevExpandedBlocks.value = new Set(newSet);
if (changed.size === 0) return;
+
+ // 保守策略:运行期间保持旧逻辑,由 stick-to-bottom 固定向下展开并向上滚动
+ if (props.streamingMessage) return;
+
const container = scrollRef.value;
if (!container) return;
@@ -1110,13 +1109,10 @@ watch(
`[data-block-id="${escapeBlockSelector(id)}"]`
) as HTMLElement | null;
if (el) {
- const isExpanding = newSet.has(id);
- const streaming = elementLooksStreaming(el);
anchorBlockElement(el, id, {
direction: 'auto',
- duration: streaming ? 5000 : 260,
- extendOnGrowth: streaming,
- phase: isExpanding ? 'expand' : 'collapse'
+ duration: 260,
+ phase: newSet.has(id) ? 'expand' : 'collapse'
});
}
}
@@ -1124,7 +1120,25 @@ watch(
{ flush: 'post' }
);
+function handleStackedMoreToggle(payload: {
+ element: HTMLElement;
+ expanded: boolean;
+ stackKey: string;
+}) {
+ // 保守策略:运行期间保持旧逻辑
+ if (props.streamingMessage) return;
+
+ anchorBlockElement(payload.element, `more-${payload.stackKey}`, {
+ direction: 'auto',
+ duration: 260,
+ phase: expanded ? 'expand' : 'collapse'
+ });
+}
+
function handleMinimalGroupToggle(payload: { groupId: string; expanded: boolean }) {
+ // 保守策略:运行期间保持旧逻辑
+ if (props.streamingMessage) return;
+
const { groupId, expanded } = payload;
const container = scrollRef.value;
if (!container) return;
@@ -1132,11 +1146,9 @@ function handleMinimalGroupToggle(payload: { groupId: string; expanded: boolean
`[data-group-id="${escapeBlockSelector(groupId)}"]`
) as HTMLElement | null;
if (el) {
- const streaming = elementLooksStreaming(el);
anchorBlockElement(el, groupId, {
direction: 'auto',
- duration: streaming ? 5000 : 300,
- extendOnGrowth: streaming,
+ duration: 300,
phase: expanded ? 'expand' : 'collapse'
});
}
diff --git a/static/src/components/chat/StackedBlocks.vue b/static/src/components/chat/StackedBlocks.vue
index 37bb04e..84d1cd2 100644
--- a/static/src/components/chat/StackedBlocks.vue
+++ b/static/src/components/chat/StackedBlocks.vue
@@ -177,6 +177,16 @@ const props = defineProps<{
formatSearchDomains: (filters: Record) => string;
}>();
+const emit = defineEmits<{
+ (
+ event: 'more-toggle',
+ payload: { element: HTMLElement; expanded: boolean; stackKey: string }
+ ): void;
+}>();
+
+let stackInstanceCounter = 0;
+const stackKey = `stacked-${++stackInstanceCounter}`;
+
// 初始化 personalization store
const personalizationStore = usePersonalizationStore();
@@ -253,6 +263,10 @@ const isToolCompleted = (action: any) => action?.tool?.status === 'completed';
const toggleMore = () => {
showAll.value = !showAll.value;
scheduleMeasure();
+ const el = moreBlock.value;
+ if (el instanceof HTMLElement) {
+ emit('more-toggle', { element: el, expanded: showAll.value, stackKey });
+ }
};
const toggleBlock = (blockId: string) => {