feat(chat-main-list): add collapsible sticky chat header on scroll
Add smooth transition animations for header height and content opacity. Handle scroll events to collapse the header when scrolling past the initial height, restore it when scrolled to top, and auto-collapse when sending a new chat message. Replace the static background image with a dynamic background div to support these transitions.
This commit is contained in:
@@ -9,10 +9,12 @@
|
|||||||
class="min-h-0 flex-1 overflow-y-auto overscroll-contain scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
|
class="min-h-0 flex-1 overflow-y-auto overscroll-contain scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
|
||||||
@scroll="handleScroll" @touchstart.capture="handleScrollAreaTouchStart" @touchstart="handleScrollAreaTouchStart"
|
@scroll="handleScroll" @touchstart.capture="handleScrollAreaTouchStart" @touchstart="handleScrollAreaTouchStart"
|
||||||
@touchmove="handleScrollAreaTouchMove">
|
@touchmove="handleScrollAreaTouchMove">
|
||||||
<div class="relative">
|
<div class="relative transition-all duration-300 ease-in-out bg-cover bg-center bg-no-repeat"
|
||||||
<img class="w-full block" :src="mainPageDataModel?.initPageImages?.backgroundImageUrl" style="height: 252px" />
|
:class="{ 'sticky top-0 z-10': isHeaderCollapsed }"
|
||||||
|
:style="{ height: isHeaderCollapsed ? '50px' : '252px', backgroundImage: mainPageDataModel?.initPageImages?.backgroundImageUrl ? `url(${mainPageDataModel.initPageImages.backgroundImageUrl})` : 'none' }">
|
||||||
<div class="absolute bottom-0 left-0 right-0 flex-1">
|
<div class="absolute bottom-0 left-0 right-0 flex-1">
|
||||||
<div class="px-[12px] pt-[12px]">
|
<div class="px-[12px] pt-[12px] transition-all duration-300"
|
||||||
|
:class="{ 'opacity-0 max-h-0 overflow-hidden pt-0': isHeaderCollapsed }">
|
||||||
<Welcome :mainPageDataModel="mainPageDataModel" />
|
<Welcome :mainPageDataModel="mainPageDataModel" />
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: -1px">
|
<div style="margin-bottom: -1px">
|
||||||
@@ -348,7 +350,8 @@ const handleScrollAreaTouchMove = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理用户滚动事件
|
// 处理用户滚动事件
|
||||||
const welcomeHeight = ref(0);
|
const welcomeHeight = ref(252);
|
||||||
|
const isHeaderCollapsed = ref(false);
|
||||||
let lastScrollTop = 0;
|
let lastScrollTop = 0;
|
||||||
const handleScroll = (e) => {
|
const handleScroll = (e) => {
|
||||||
if (Date.now() - lastScrollTouchAt < 1000) {
|
if (Date.now() - lastScrollTouchAt < 1000) {
|
||||||
@@ -359,6 +362,17 @@ const handleScroll = (e) => {
|
|||||||
e?.detail?.scrollTop ?? e?.target?.scrollTop ?? 0,
|
e?.detail?.scrollTop ?? e?.target?.scrollTop ?? 0,
|
||||||
);
|
);
|
||||||
const scrollEl = e?.target;
|
const scrollEl = e?.target;
|
||||||
|
|
||||||
|
// 滚动回顶部时还原头部布局
|
||||||
|
if (currentScrollTop <= 0 && isHeaderCollapsed.value) {
|
||||||
|
isHeaderCollapsed.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向上滚动超过头部高度时收敛
|
||||||
|
if (currentScrollTop > welcomeHeight.value && !isHeaderCollapsed.value) {
|
||||||
|
isHeaderCollapsed.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (topNavBarRef.value) {
|
if (topNavBarRef.value) {
|
||||||
topNavBarRef.value.show = currentScrollTop > welcomeHeight.value;
|
topNavBarRef.value.show = currentScrollTop > welcomeHeight.value;
|
||||||
}
|
}
|
||||||
@@ -906,6 +920,9 @@ const sendMessage = async (message, isInstruct = false) => {
|
|||||||
tabIndex.value = 1;
|
tabIndex.value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发起对话时收敛头部
|
||||||
|
isHeaderCollapsed.value = true;
|
||||||
|
|
||||||
// 检查WebSocket连接状态,如果未连接,尝试重新连接
|
// 检查WebSocket连接状态,如果未连接,尝试重新连接
|
||||||
if (!isWsConnected()) {
|
if (!isWsConnected()) {
|
||||||
console.log("WebSocket未连接,尝试重新连接...");
|
console.log("WebSocket未连接,尝试重新连接...");
|
||||||
|
|||||||
Reference in New Issue
Block a user