fix(chat): 运行期间恢复旧滚动逻辑,堆叠块更多按钮也接入锚定
This commit is contained in:
parent
edb557bdd3
commit
f43b5ea73b
@ -131,6 +131,7 @@
|
|||||||
:format-search-topic="formatSearchTopic"
|
:format-search-topic="formatSearchTopic"
|
||||||
:format-search-time="formatSearchTime"
|
:format-search-time="formatSearchTime"
|
||||||
:format-search-domains="formatSearchDomains"
|
:format-search-domains="formatSearchDomains"
|
||||||
|
@more-toggle="handleStackedMoreToggle"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else-if="isActionVisible(group.action)"
|
v-else-if="isActionVisible(group.action)"
|
||||||
@ -914,6 +915,7 @@ function attachBounceListener() {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
lastUserWheelUpTs = now;
|
lastUserWheelUpTs = now;
|
||||||
stopScroll();
|
stopScroll();
|
||||||
|
stopBlockExpansionAnchors();
|
||||||
emit('user-scroll-intent', {
|
emit('user-scroll-intent', {
|
||||||
ts: now,
|
ts: now,
|
||||||
delta: deltaY,
|
delta: deltaY,
|
||||||
@ -977,6 +979,7 @@ function attachBounceListener() {
|
|||||||
if (shouldTreatAsUserIntent) {
|
if (shouldTreatAsUserIntent) {
|
||||||
// 用户手动滚动时,立即中断 stick 引擎中可能仍在运行的动画滚动
|
// 用户手动滚动时,立即中断 stick 引擎中可能仍在运行的动画滚动
|
||||||
stopScroll();
|
stopScroll();
|
||||||
|
stopBlockExpansionAnchors();
|
||||||
lastUserDownScrollTs = now;
|
lastUserDownScrollTs = now;
|
||||||
emit('user-scroll-intent', {
|
emit('user-scroll-intent', {
|
||||||
ts: lastUserDownScrollTs,
|
ts: lastUserDownScrollTs,
|
||||||
@ -1078,14 +1081,6 @@ function escapeBlockSelector(value: string) {
|
|||||||
return value.replace(/["\\]/g, '\\$&');
|
return value.replace(/["\\]/g, '\\$&');
|
||||||
}
|
}
|
||||||
|
|
||||||
function elementLooksStreaming(el: HTMLElement) {
|
|
||||||
return (
|
|
||||||
el.classList.contains('processing') ||
|
|
||||||
el.classList.contains('running') ||
|
|
||||||
!!el.querySelector('.processing, .running, .thinking-animation')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const prevExpandedBlocks = ref(new Set<string>());
|
const prevExpandedBlocks = ref(new Set<string>());
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -1102,6 +1097,10 @@ watch(
|
|||||||
prevExpandedBlocks.value = new Set(newSet);
|
prevExpandedBlocks.value = new Set(newSet);
|
||||||
|
|
||||||
if (changed.size === 0) return;
|
if (changed.size === 0) return;
|
||||||
|
|
||||||
|
// 保守策略:运行期间保持旧逻辑,由 stick-to-bottom 固定向下展开并向上滚动
|
||||||
|
if (props.streamingMessage) return;
|
||||||
|
|
||||||
const container = scrollRef.value;
|
const container = scrollRef.value;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
@ -1110,13 +1109,10 @@ watch(
|
|||||||
`[data-block-id="${escapeBlockSelector(id)}"]`
|
`[data-block-id="${escapeBlockSelector(id)}"]`
|
||||||
) as HTMLElement | null;
|
) as HTMLElement | null;
|
||||||
if (el) {
|
if (el) {
|
||||||
const isExpanding = newSet.has(id);
|
|
||||||
const streaming = elementLooksStreaming(el);
|
|
||||||
anchorBlockElement(el, id, {
|
anchorBlockElement(el, id, {
|
||||||
direction: 'auto',
|
direction: 'auto',
|
||||||
duration: streaming ? 5000 : 260,
|
duration: 260,
|
||||||
extendOnGrowth: streaming,
|
phase: newSet.has(id) ? 'expand' : 'collapse'
|
||||||
phase: isExpanding ? 'expand' : 'collapse'
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,7 +1120,25 @@ watch(
|
|||||||
{ flush: 'post' }
|
{ 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 }) {
|
function handleMinimalGroupToggle(payload: { groupId: string; expanded: boolean }) {
|
||||||
|
// 保守策略:运行期间保持旧逻辑
|
||||||
|
if (props.streamingMessage) return;
|
||||||
|
|
||||||
const { groupId, expanded } = payload;
|
const { groupId, expanded } = payload;
|
||||||
const container = scrollRef.value;
|
const container = scrollRef.value;
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
@ -1132,11 +1146,9 @@ function handleMinimalGroupToggle(payload: { groupId: string; expanded: boolean
|
|||||||
`[data-group-id="${escapeBlockSelector(groupId)}"]`
|
`[data-group-id="${escapeBlockSelector(groupId)}"]`
|
||||||
) as HTMLElement | null;
|
) as HTMLElement | null;
|
||||||
if (el) {
|
if (el) {
|
||||||
const streaming = elementLooksStreaming(el);
|
|
||||||
anchorBlockElement(el, groupId, {
|
anchorBlockElement(el, groupId, {
|
||||||
direction: 'auto',
|
direction: 'auto',
|
||||||
duration: streaming ? 5000 : 300,
|
duration: 300,
|
||||||
extendOnGrowth: streaming,
|
|
||||||
phase: expanded ? 'expand' : 'collapse'
|
phase: expanded ? 'expand' : 'collapse'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -177,6 +177,16 @@ const props = defineProps<{
|
|||||||
formatSearchDomains: (filters: Record<string, any>) => string;
|
formatSearchDomains: (filters: Record<string, any>) => string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(
|
||||||
|
event: 'more-toggle',
|
||||||
|
payload: { element: HTMLElement; expanded: boolean; stackKey: string }
|
||||||
|
): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
let stackInstanceCounter = 0;
|
||||||
|
const stackKey = `stacked-${++stackInstanceCounter}`;
|
||||||
|
|
||||||
// 初始化 personalization store
|
// 初始化 personalization store
|
||||||
const personalizationStore = usePersonalizationStore();
|
const personalizationStore = usePersonalizationStore();
|
||||||
|
|
||||||
@ -253,6 +263,10 @@ const isToolCompleted = (action: any) => action?.tool?.status === 'completed';
|
|||||||
const toggleMore = () => {
|
const toggleMore = () => {
|
||||||
showAll.value = !showAll.value;
|
showAll.value = !showAll.value;
|
||||||
scheduleMeasure();
|
scheduleMeasure();
|
||||||
|
const el = moreBlock.value;
|
||||||
|
if (el instanceof HTMLElement) {
|
||||||
|
emit('more-toggle', { element: el, expanded: showAll.value, stackKey });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleBlock = (blockId: string) => {
|
const toggleBlock = (blockId: string) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user