77 <AppSkeletonLoader />
88 </div >
99
10- <div v-else class =" app-container" :class =" appContainerClasses" >
10+ <!-- ✅ MODIFICATION START: Bind dynamic style for sidebar width and a class for collapsed state -->
11+ <div
12+ v-else
13+ class =" app-container"
14+ :class =" appContainerClasses"
15+ :style =" { '--sidebar-width': `${uiStore.sidebarWidth}px` }"
16+ >
17+ <!-- ✅ MODIFICATION END -->
1118 <aside class =" sidebar-container" >
1219 <ChatList />
1320 </aside >
1421
22+ <!-- ✅ MODIFICATION START: Add SidebarResizer component between sidebar and main content -->
23+ <SidebarResizer />
24+ <!-- ✅ MODIFICATION END -->
25+
1526 <div class =" main-content-wrapper" >
1627 <main class =" main-view-container" >
1728 <ChatView v-if =" chatStore .currentChatId " :key =" chatStore .currentChatId " />
4960 v-if =" uiStore .activeModal === ' locationPicker' "
5061 v-motion-pop
5162 />
52- <!-- -- - [移除] -- - -->
53- <!-- BindManualConnectionModal is no longer needed -->
5463 <ScreenshotGuideModal
5564 v-if =" uiStore .activeModal === ' screenshotGuide' "
5665 v-motion-pop
6372 v-if =" uiStore .activeModal === ' confirmation' "
6473 v-motion-pop
6574 />
66- <!-- -- - [移除] -- - -->
67- <!-- CommentModal is no longer a global modal -->
6875 </div >
6976 </Transition >
7077
@@ -120,12 +127,13 @@ import WelcomeHeader from '@/components/ChatView/WelcomeHeader.vue';
120127import FloatingCallWidget from ' @/components/Shared/FloatingCallWidget.vue' ;
121128import SettingsModalSkeleton from ' @/components/Shared/SettingsModalSkeleton.vue' ;
122129import MobileGlobalHeader from ' @/components/Shared/MobileGlobalHeader.vue' ;
130+ // ✅ MODIFICATION START: Import the new resizer component
131+ import SidebarResizer from ' @/components/Shared/SidebarResizer.vue' ;
132+ // ✅ MODIFICATION END
123133
124134const SettingsModal = defineAsyncComponent (() => import (' @/components/Modals/SettingsModal.vue' ));
125135const NewContactModal = defineAsyncComponent (() => import (' @/components/Modals/NewContactModal.vue' ));
126136const LocationPickerModal = defineAsyncComponent (() => import (' @/components/Modals/LocationPickerModal.vue' ));
127- // --- [移除] ---
128- // const BindManualConnectionModal = ...
129137const ScreenshotEditor = defineAsyncComponent (() => import (' @/components/Modals/ScreenshotEditor.vue' ));
130138const ScreenshotGuideModal = defineAsyncComponent (() => import (' @/components/Modals/ScreenshotGuideModal.vue' ));
131139const IncomingCallModal = defineAsyncComponent (() => import (' @/components/Modals/IncomingCallModal.vue' ));
@@ -134,8 +142,6 @@ const MediaViewerModal = defineAsyncComponent(() => import('@/components/Modals/
134142const LocationViewerModal = defineAsyncComponent (() => import (' @/components/Modals/LocationViewerModal.vue' ));
135143const WorldMapModal = defineAsyncComponent (() => import (' @/components/Modals/WorldMapModal.vue' ));
136144const ImageCropperModal = defineAsyncComponent (() => import (' @/components/Modals/ImageCropperModal.vue' ));
137- // --- [移除] ---
138- // const CommentModal = ... // No longer needed here
139145
140146const userStore = useUserStore ();
141147const chatStore = useChatStore ();
@@ -147,9 +153,17 @@ const memoryStore = useMemoryStore();
147153
148154const globalAudioSink = ref (null );
149155
156+ // ✅ MODIFICATION START: Define sidebar collapsed threshold and computed property
157+ const SIDEBAR_COLLAPSED_THRESHOLD = 80 ;
158+ const isSidebarCollapsed = computed (() => uiStore .sidebarWidth < SIDEBAR_COLLAPSED_THRESHOLD );
159+ // ✅ MODIFICATION END
160+
150161const appContainerClasses = computed (() => ({
151162 ' details-panel-open' : uiStore .isDetailsPanelOpen ,
152- ' chat-active' : uiStore .isChatViewActiveOnMobile
163+ ' chat-active' : uiStore .isChatViewActiveOnMobile ,
164+ // ✅ MODIFICATION START: Add collapsed class dynamically
165+ ' sidebar-collapsed' : isSidebarCollapsed .value ,
166+ // ✅ MODIFICATION END
153167}));
154168
155169const appRootClasses = computed (() => ({
@@ -178,8 +192,6 @@ onMounted(async () => {
178192 await memoryStore .init ();
179193 callStore .setGlobalAudioElement (globalAudioSink .value );
180194 webrtcService .init (userStore .userId );
181- // --- [移除] ---
182- // eventBus.on('webrtc:manual-connection-ready', ...)
183195 } catch (error) {
184196 console .error (" 应用初始化失败:" , error);
185197 } finally {
@@ -213,11 +225,9 @@ function handleBackButton() {
213225 } else if (uiStore .activeModal ) {
214226 uiStore .hideModal ();
215227 handled = true ;
216- // ✅ MODIFICATION START: Add check for EmojiPicker
217228 } else if (uiStore .isEmojiPickerVisible ) {
218229 uiStore .toggleEmojiPicker (false );
219230 handled = true ;
220- // ✅ MODIFICATION END
221231 } else if (uiStore .isDetailsPanelOpen ) {
222232 uiStore .toggleDetailsPanel (false );
223233 handled = true ;
@@ -307,7 +317,18 @@ body {
307317 width: var (-- sidebar- width);
308318 flex- shrink: 0 ;
309319 background- color: var (-- color- background- panel);
320+ /* ✅ MODIFICATION START: Add smooth transition for width changes */
321+ transition: width 0 .2s ease- out;
322+ will- change: width;
323+ /* ✅ MODIFICATION END */
310324}
325+
326+ /* ✅ MODIFICATION START: Disable transition during drag for "跟手" effect */
327+ body .is - resizing .sidebar - container {
328+ transition: none;
329+ }
330+ /* ✅ MODIFICATION END */
331+
311332.details - panel- container {
312333 background- color: var (-- color- background- panel);
313334 border- left: 1px solid var (-- color- border);
0 commit comments