From e9cc98b7eec605a10762457ed8c9a40b1294cb56 Mon Sep 17 00:00:00 2001 From: therainisme Date: Sat, 31 Jan 2026 10:06:43 +0800 Subject: [PATCH] feat(web): Add session sidebar for desktop, keep mobile single-page layout (#112) * feat(web): Responsive session sidebar + split chat layout * Update sidebar width * Fixed dialog * Move the sidebar scrollbar to the left without flipping content --- web/src/components/SessionList.tsx | 10 +- web/src/components/ui/dialog.tsx | 2 +- web/src/index.css | 11 ++ web/src/router.tsx | 160 ++++++++++++++++++----------- 4 files changed, 120 insertions(+), 63 deletions(-) diff --git a/web/src/components/SessionList.tsx b/web/src/components/SessionList.tsx index 28d2882a..69c71c37 100644 --- a/web/src/components/SessionList.tsx +++ b/web/src/components/SessionList.tsx @@ -166,9 +166,10 @@ function SessionItem(props: { onSelect: (sessionId: string) => void showPath?: boolean api: ApiClient | null + selected?: boolean }) { const { t } = useTranslation() - const { session: s, onSelect, showPath = true, api } = props + const { session: s, onSelect, showPath = true, api, selected = false } = props const { haptic } = usePlatform() const [menuOpen, setMenuOpen] = useState(false) const [menuAnchorPoint, setMenuAnchorPoint] = useState<{ x: number; y: number }>({ x: 0, y: 0 }) @@ -205,8 +206,9 @@ function SessionItem(props: { - +
+
+
+
+
+ {t('sessions.count', { n: sessions.length, m: projectCount })} +
+
+ + +
+ +
+ {error ? ( +
+
{error}
+
+ ) : null} + navigate({ + to: '/sessions/$sessionId', + params: { sessionId }, + })} + onNewSession={() => navigate({ to: '/sessions/new' })} + onRefresh={handleRefresh} + isLoading={isLoading} + renderHeader={false} + api={api} + /> +
-
- {error ? ( -
-
{error}
-
- ) : null} - navigate({ - to: '/sessions/$sessionId', - params: { sessionId }, - })} - onNewSession={() => navigate({ to: '/sessions/new' })} - onRefresh={handleRefresh} - isLoading={isLoading} - renderHeader={false} - api={api} - /> + +
+
+ +
) } +function SessionsIndexPage() { + return null +} + function SessionPage() { const { api } = useAppContext() const goBack = useAppGoBack() @@ -281,6 +305,15 @@ function SessionPage() { ) } +function SessionDetailRoute() { + const pathname = useLocation({ select: location => location.pathname }) + const { sessionId } = useParams({ from: '/sessions/$sessionId' }) + const basePath = `/sessions/${sessionId}` + const isChat = pathname === basePath || pathname === `${basePath}/` + + return isChat ? : +} + function NewSessionPage() { const { api } = useAppContext() const navigate = useNavigate() @@ -353,21 +386,27 @@ const sessionsRoute = createRoute({ component: SessionsPage, }) -const sessionRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions/$sessionId', - component: SessionPage, +const sessionsIndexRoute = createRoute({ + getParentRoute: () => sessionsRoute, + path: '/', + component: SessionsIndexPage, +}) + +const sessionDetailRoute = createRoute({ + getParentRoute: () => sessionsRoute, + path: '$sessionId', + component: SessionDetailRoute, }) const sessionFilesRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions/$sessionId/files', + getParentRoute: () => sessionDetailRoute, + path: 'files', component: FilesPage, }) const sessionTerminalRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions/$sessionId/terminal', + getParentRoute: () => sessionDetailRoute, + path: 'terminal', component: TerminalPage, }) @@ -377,8 +416,8 @@ type SessionFileSearch = { } const sessionFileRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions/$sessionId/file', + getParentRoute: () => sessionDetailRoute, + path: 'file', validateSearch: (search: Record): SessionFileSearch => { const path = typeof search.path === 'string' ? search.path : '' const staged = search.staged === true || search.staged === 'true' @@ -393,8 +432,8 @@ const sessionFileRoute = createRoute({ }) const newSessionRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/sessions/new', + getParentRoute: () => sessionsRoute, + path: 'new', component: NewSessionPage, }) @@ -406,12 +445,15 @@ const settingsRoute = createRoute({ export const routeTree = rootRoute.addChildren([ indexRoute, - sessionsRoute, - sessionRoute, - sessionTerminalRoute, - sessionFilesRoute, - sessionFileRoute, - newSessionRoute, + sessionsRoute.addChildren([ + sessionsIndexRoute, + newSessionRoute, + sessionDetailRoute.addChildren([ + sessionTerminalRoute, + sessionFilesRoute, + sessionFileRoute, + ]), + ]), settingsRoute, ])