diff --git a/src/App.vue b/src/App.vue index c39b2cd5b..e8463560b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2068,12 +2068,10 @@ const existingFolderFilteredEntries = computed(() => { }) const darkModeMediaQuery = typeof window !== 'undefined' ? window.matchMedia('(prefers-color-scheme: dark)') : null const chatWidthLabel = computed(() => t(CHAT_WIDTH_PRESETS[chatWidth.value].label)) -const terminalShortcutLabel = computed(() => { - if (typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform)) { - return '⌘J' - } - return 'Ctrl+J' -}) +function isMacPlatform(): boolean { + return typeof navigator !== 'undefined' && /mac|iphone|ipad|ipod/i.test(navigator.platform) +} +const terminalShortcutLabel = computed(() => (isMacPlatform() ? '⌘J' : 'Ctrl+J')) const terminalCommandPlaceholder = computed(() => ( isComposerTerminalOpen.value ? t('Terminal') : t('Open terminal') )) @@ -3100,6 +3098,10 @@ function onWindowKeyDown(event: KeyboardEvent): void { if (event.shiftKey || event.altKey) return const key = event.key.toLowerCase() if (key === 'b') { + const isSidebarShortcut = isMacPlatform() + ? event.metaKey && !event.ctrlKey + : event.ctrlKey && !event.metaKey + if (!isSidebarShortcut) return event.preventDefault() setSidebarCollapsed(!isSidebarCollapsed.value) return diff --git a/tests/projects-sidebar-new-chat/sidebar-scroll-position-survives-collapse.md b/tests/projects-sidebar-new-chat/sidebar-scroll-position-survives-collapse.md index 50d6a7230..5c7f032a7 100644 --- a/tests/projects-sidebar-new-chat/sidebar-scroll-position-survives-collapse.md +++ b/tests/projects-sidebar-new-chat/sidebar-scroll-position-survives-collapse.md @@ -10,15 +10,17 @@ Sidebar scroll position is restored after closing and reopening the sidebar. ## Steps 1. In light theme, open `http://127.0.0.1:4173/#/`. 2. Scroll the sidebar list downward until a lower project or thread row is near the top of the sidebar. -3. Collapse the sidebar with the sidebar toggle or `Command+B`. -4. Reopen the sidebar with the header/sidebar toggle or `Command+B`. -5. Confirm the same lower project or thread row is still near the top and the sidebar did not jump back to the top. -6. Repeat collapse/reopen twice quickly and confirm the restored position is not clobbered to the top while collapsed. -7. Repeat the collapse and reopen flow in dark theme. +3. Collapse the sidebar with the sidebar toggle, `Command+B` on macOS, or `Control+B` on non-macOS platforms. +4. Reopen the sidebar with the header/sidebar toggle, `Command+B` on macOS, or `Control+B` on non-macOS platforms. +5. On macOS, press `Control+B` and confirm it does not collapse or reopen the sidebar. +6. Confirm the same lower project or thread row is still near the top and the sidebar did not jump back to the top. +7. Repeat collapse/reopen twice quickly and confirm the restored position is not clobbered to the top while collapsed. +8. Repeat the collapse and reopen flow in dark theme. ## Expected Results - Closing and reopening the sidebar restores the previous vertical scroll offset. - The remembered scroll position remains stable while the sidebar content is remounted. +- `Command+B` toggles the sidebar on macOS, `Control+B` toggles it on non-macOS platforms, and `Control+B` does not toggle it on macOS. - Mobile drawer restore retries after reopen until the full list height is available, so transition/teleport timing does not leave the sidebar at the top or a partial intermediate offset. - Scroll events emitted after collapse do not overwrite the saved offset. - Light and dark theme sidebar rows remain readable after restore.