feat(web): 在窄屏幕宽度下自动折叠并浮动对话侧边栏
为 .chat-main 添加了 ResizeObserver,当消息区域宽度低于 600px 时自动折叠对话历史侧边栏,避免界面挤压。同时添加了浮动状态,使侧边栏在小屏幕上重新打开时以覆盖层形式显示。
This commit is contained in:
parent
d06c7000ea
commit
a8b96dbcf2
@ -4,6 +4,7 @@
|
||||
:current-chat-id="currentChatId"
|
||||
:chats-list="chatsList"
|
||||
:is-sidebar-open="chatUIStore.isSidebarOpen"
|
||||
:is-floating="isSidebarFloating"
|
||||
:is-initial-render="localUIState.isInitialRender"
|
||||
:single-mode="props.singleMode"
|
||||
:agents="agents"
|
||||
@ -72,7 +73,7 @@
|
||||
|
||||
<div class="chat-content-container">
|
||||
<!-- Main Chat Area -->
|
||||
<div class="chat-main">
|
||||
<div class="chat-main" ref="chatMainRef">
|
||||
<div class="chat-box">
|
||||
<div class="conv-box" v-for="(conv, index) in conversations" :key="index">
|
||||
<AgentMessageComponent
|
||||
@ -491,6 +492,9 @@ const isProcessing = computed(() => isStreaming.value)
|
||||
|
||||
// ==================== SCROLL & RESIZE HANDLING ====================
|
||||
const scrollController = new ScrollController('.chat-main')
|
||||
const chatMainRef = ref(null)
|
||||
const isSidebarFloating = ref(false)
|
||||
let chatMainResizeObserver = null
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
@ -498,6 +502,30 @@ onMounted(() => {
|
||||
if (chatMainContainer) {
|
||||
chatMainContainer.addEventListener('scroll', scrollController.handleScroll, { passive: true })
|
||||
}
|
||||
|
||||
if (window.ResizeObserver && chatMainRef.value) {
|
||||
chatMainResizeObserver = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const width = entry.contentRect.width
|
||||
const isTakingSpace = chatUIStore.isSidebarOpen && !isSidebarFloating.value
|
||||
|
||||
if (isTakingSpace) {
|
||||
if (width < 600) {
|
||||
isSidebarFloating.value = true
|
||||
chatUIStore.isSidebarOpen = false
|
||||
localStorage.setItem('chat_sidebar_open', 'false')
|
||||
}
|
||||
} else {
|
||||
if (width >= 880) {
|
||||
isSidebarFloating.value = false
|
||||
} else {
|
||||
isSidebarFloating.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
chatMainResizeObserver.observe(chatMainRef.value)
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
localUIState.isInitialRender = false
|
||||
@ -506,6 +534,9 @@ onMounted(() => {
|
||||
|
||||
onUnmounted(() => {
|
||||
scrollController.cleanup()
|
||||
if (chatMainResizeObserver) {
|
||||
chatMainResizeObserver.disconnect()
|
||||
}
|
||||
// 清理所有线程状态
|
||||
resetOnGoingConv()
|
||||
})
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="chat-sidebar"
|
||||
:class="{ 'sidebar-open': chatUIStore.isSidebarOpen, 'no-transition': isInitialRender }"
|
||||
:class="{ 'sidebar-open': chatUIStore.isSidebarOpen, 'no-transition': isInitialRender, 'is-floating': isFloating }"
|
||||
>
|
||||
<div class="sidebar-content">
|
||||
<div class="sidebar-header">
|
||||
@ -146,6 +146,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isFloating: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
singleMode: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@ -295,6 +299,20 @@ const togglePin = (chatId) => {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
&.is-floating {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
|
||||
&.sidebar-open {
|
||||
box-shadow: 4px 0 16px rgba(0, 0, 0, 0.08);
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.sidebar-open {
|
||||
width: 280px;
|
||||
max-width: 300px;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user