feat: 移动端侧边栏体验 — 窄视口(<1024px)双工作台合并为单面板抽屉(可拖分隔条、高度与底部面板互通)、不提供底部面板按钮、文件/外链打开自动展开、新会话默认收起

This commit is contained in:
Menghuan1918
2026-08-12 18:20:34 +08:00
parent bab659f8bd
commit b391ebffed
12 changed files with 638 additions and 72 deletions
+20 -3
View File
@@ -22,9 +22,10 @@
import type { ReactNode } from 'react'
import type { Context } from '../context-types.ts'
import {
activateTab, allLeaves, closeTab as closeTabReducer, openTabInActivePane, patchTab,
activateTab, allLeaves, closeTab as closeTabReducer, openTabInActivePane, patchTab, togglePanel,
type SidebarState, type SidebarStore, type SidebarTab,
} from './state.ts'
import { isNarrowWidth } from './breakpoints.ts'
import type { SessionScope } from './api.ts'
/** One declarative boolean setting of a tab/viewer, rendered as a nested
@@ -335,13 +336,29 @@ export function createBetterSidebarService(store: SidebarStore): BetterSidebarSe
// A URL seed pre-fills the tab's path (the browser tab navigates to it
// on mount). An explicit seed.title also wins over a createTab-minted
// default title (e.g. the sidebar-browser's hostname title).
let landed: SidebarState
if (seed.url !== undefined) {
return patchTab(next, tab.id, {
landed = patchTab(next, tab.id, {
path: seed.url,
...(seed.title !== undefined ? { title: seed.title } : {}),
})
} else {
landed = next
}
return next
// Narrow-viewport drawer: a CONTENT open (file / browser) must be
// visible — expand the collapsed drawer so the open lands in sight.
// Type-only opens (+ menu, agent-terminal auto-tabs) never expand; on
// wide viewports nothing here changes (the panel behavior is the
// caller's business).
if (
typeof window !== 'undefined'
&& isNarrowWidth(window.innerWidth)
&& (seed.path !== undefined || seed.url !== undefined)
&& !landed.panelOpen
) {
return togglePanel(landed)
}
return landed
})
}