Browse Source

情绪大模型新增滚动最底部功能。

dev
宋杰 10 hours ago
parent
commit
06acfb4369
  1. 146
      src/views/homePage.vue

146
src/views/homePage.vue

@ -365,6 +365,12 @@ const tabContentAIchat = ref(null);
const tabContentAiEmotion = ref(null); const tabContentAiEmotion = ref(null);
const isScrolling = ref(false); // const isScrolling = ref(false); //
// AiEmotion
const aiEmotionHeightObserver = ref(null);
const isAiEmotionAutoScrollEnabled = ref(false);
const isAiEmotionUserScrolling = ref(false); //
const aiEmotionScrollTimer = ref(null); //
// //
const getCurrentScrollContainer = () => { const getCurrentScrollContainer = () => {
if (activeTab.value === 'AIchat') { if (activeTab.value === 'AIchat') {
@ -398,6 +404,135 @@ const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 300, {
trailing: false, trailing: false,
}); });
// AiEmotion
const debouncedAiEmotionScrollToBottom = _.debounce(() => {
if (activeTab.value === 'AiEmotion' && isAiEmotionAutoScrollEnabled.value && !isAiEmotionUserScrolling.value) {
const container = tabContentAiEmotion.value;
if (container) {
container.scrollTop = container.scrollHeight - container.offsetHeight;
}
}
}, 150);
// AiEmotion
const startAiEmotionHeightObserver = () => {
//
stopAiEmotionHeightObserver();
isAiEmotionAutoScrollEnabled.value = true;
// ResizeObserver
aiEmotionHeightObserver.value = new ResizeObserver((entries) => {
if (isAiEmotionAutoScrollEnabled.value && activeTab.value === 'AiEmotion') {
debouncedAiEmotionScrollToBottom();
}
});
// document.body
if (document.body) {
aiEmotionHeightObserver.value.observe(document.body);
}
// MutationObserverDOM
const mutationObserver = new MutationObserver((mutations) => {
let shouldScroll = false;
mutations.forEach((mutation) => {
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
//
const hasContent = Array.from(mutation.addedNodes).some((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
return node.offsetHeight > 0 || node.scrollHeight > 0;
}
return (
node.nodeType === Node.TEXT_NODE &&
node.textContent.trim().length > 0
);
});
if (hasContent) {
shouldScroll = true;
}
}
});
if (shouldScroll && isAiEmotionAutoScrollEnabled.value && activeTab.value === 'AiEmotion') {
debouncedAiEmotionScrollToBottom();
}
});
// AiEmotionDOM
const aiEmotionContainer = tabContentAiEmotion.value;
if (aiEmotionContainer) {
mutationObserver.observe(aiEmotionContainer, {
childList: true,
subtree: true,
attributes: false,
characterData: true,
});
}
// mutationObserver便
aiEmotionHeightObserver.value.mutationObserver = mutationObserver;
// AiEmotion
if (aiEmotionContainer) {
aiEmotionContainer.addEventListener('scroll', handleAiEmotionUserScroll, { passive: true });
// 便
aiEmotionHeightObserver.value.scrollListener = handleAiEmotionUserScroll;
}
console.log("AiEmotion页面高度监听器已启动");
};
// AiEmotion
const handleAiEmotionUserScroll = () => {
//
isAiEmotionUserScrolling.value = true;
//
if (aiEmotionScrollTimer.value) {
clearTimeout(aiEmotionScrollTimer.value);
}
// 2
aiEmotionScrollTimer.value = setTimeout(() => {
isAiEmotionUserScrolling.value = false;
console.log("AiEmotion页面用户滚动检测:恢复自动滚动");
}, 2000);
};
// AiEmotion
const stopAiEmotionHeightObserver = () => {
isAiEmotionAutoScrollEnabled.value = false;
isAiEmotionUserScrolling.value = false;
//
if (aiEmotionScrollTimer.value) {
clearTimeout(aiEmotionScrollTimer.value);
aiEmotionScrollTimer.value = null;
}
if (aiEmotionHeightObserver.value) {
// ResizeObserver
aiEmotionHeightObserver.value.disconnect();
// MutationObserver
if (aiEmotionHeightObserver.value.mutationObserver) {
aiEmotionHeightObserver.value.mutationObserver.disconnect();
aiEmotionHeightObserver.value.mutationObserver = null;
}
//
if (aiEmotionHeightObserver.value.scrollListener && tabContentAiEmotion.value) {
tabContentAiEmotion.value.removeEventListener('scroll', aiEmotionHeightObserver.value.scrollListener);
aiEmotionHeightObserver.value.scrollListener = null;
}
aiEmotionHeightObserver.value = null;
}
console.log("AiEmotion页面高度监听器已停止");
};
watch( watch(
() => chatStore.messages.length, () => chatStore.messages.length,
() => { () => {
@ -437,9 +572,18 @@ watch(
if (activeTab.value === "AIchat") { if (activeTab.value === "AIchat") {
isScrolling.value = false; // isScrolling.value = false; //
// AiEmotion
stopAiEmotionHeightObserver();
setTimeout(() => { setTimeout(() => {
// throttledSmoothScrollToBottom(); // throttledSmoothScrollToBottom();
}, 100); }, 100);
} else if (activeTab.value === "AiEmotion") {
// AiEmotion
await nextTick(); // DOM
startAiEmotionHeightObserver();
} else {
// AiEmotion
stopAiEmotionHeightObserver();
} }
// AiEmotion // AiEmotion
// setTimeout(throttledSmoothScrollToBottom, 100); // setTimeout(throttledSmoothScrollToBottom, 100);
@ -761,6 +905,8 @@ onUnmounted(() => {
console.log("卸载touchmoveHandlerRef组件"); console.log("卸载touchmoveHandlerRef组件");
document.removeEventListener("touchmove", touchmoveHandlerRef); document.removeEventListener("touchmove", touchmoveHandlerRef);
} }
// AiEmotion
stopAiEmotionHeightObserver();
}); });
</script> </script>

Loading…
Cancel
Save