feat(web): 在窄屏幕宽度下自动折叠并浮动对话侧边栏

为 .chat-main 添加了 ResizeObserver,当消息区域宽度低于 600px 时自动折叠对话历史侧边栏,避免界面挤压。同时添加了浮动状态,使侧边栏在小屏幕上重新打开时以覆盖层形式显示。
This commit is contained in:
Wenjie Zhang 2026-03-21 16:41:32 +08:00
parent d06c7000ea
commit a8b96dbcf2
2 changed files with 51 additions and 2 deletions

View File

@ -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()
})

View File

@ -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;