mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-25 17:12:17 +00:00
fix(app): preserve session shell while loading (#44315)
This commit is contained in:
parent
b8fb894ec7
commit
d144c81d17
3 changed files with 44 additions and 24 deletions
|
|
@ -15,7 +15,7 @@ import { SessionUIProvider } from "@/shell/routes/session-ui-provider"
|
|||
import { useTabs } from "@/shell/tabs/tabs"
|
||||
import { requireServerKey } from "@/shell/routes/session"
|
||||
import { useSessionModel } from "./model"
|
||||
import { SessionPanelFrame, SessionRouteFrame } from "./session-frame"
|
||||
import { SessionPanelFrame } from "./session-frame"
|
||||
import { IncompatibleServerPanel } from "./incompatible-server-panel"
|
||||
import { SessionErrorFallback } from "./route-error"
|
||||
import { createSessionResolution } from "./session-resolution"
|
||||
|
|
@ -31,7 +31,7 @@ export function TargetSessionRouteContent() {
|
|||
<MarkSessionNotificationsViewed sessionID={() => params.id} />
|
||||
<ModelsProvider directory={directory}>
|
||||
<TargetSessionSettingsCommand />
|
||||
<SessionRouteErrorBoundary sessionID={params.id} serverKey={requireServerKey(params.serverKey)} padded>
|
||||
<SessionRouteErrorBoundary sessionID={params.id} serverKey={requireServerKey(params.serverKey)}>
|
||||
<ResolvedTargetSessionRoute />
|
||||
</SessionRouteErrorBoundary>
|
||||
</ModelsProvider>
|
||||
|
|
@ -45,16 +45,14 @@ function TargetSessionSettingsCommand() {
|
|||
}
|
||||
|
||||
function SessionRouteErrorBoundary(
|
||||
props: ParentProps<{ sessionID?: string; serverKey?: ServerConnection.Key; padded?: boolean }>,
|
||||
props: ParentProps<{ sessionID?: string; serverKey?: ServerConnection.Key }>,
|
||||
) {
|
||||
return (
|
||||
<ErrorBoundary
|
||||
fallback={(error) => (
|
||||
<SessionRouteFrame padded={props.padded}>
|
||||
<SessionPanelFrame raised={!!props.sessionID}>
|
||||
<SessionErrorFallback error={error} sessionID={props.sessionID} serverKey={props.serverKey} />
|
||||
</SessionPanelFrame>
|
||||
</SessionRouteFrame>
|
||||
<SessionStatePanel>
|
||||
<SessionErrorFallback error={error} sessionID={props.sessionID} serverKey={props.serverKey} />
|
||||
</SessionStatePanel>
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
|
|
@ -78,16 +76,14 @@ function ResolvedTargetSessionRoute() {
|
|||
<Show
|
||||
when={!server.health?.incompatible}
|
||||
fallback={
|
||||
<SessionRouteFrame padded>
|
||||
<SessionPanelFrame raised>
|
||||
<IncompatibleServerPanel
|
||||
onClose={() => tabs.removeSessionTab({ server: server.key, sessionId: params.id })}
|
||||
/>
|
||||
</SessionPanelFrame>
|
||||
</SessionRouteFrame>
|
||||
<SessionStatePanel>
|
||||
<IncompatibleServerPanel
|
||||
onClose={() => tabs.removeSessionTab({ server: server.key, sessionId: params.id })}
|
||||
/>
|
||||
</SessionStatePanel>
|
||||
}
|
||||
>
|
||||
<Show when={directory()}>
|
||||
<Show when={directory()} fallback={<SessionStatePanel />}>
|
||||
{(value) => (
|
||||
<LocationProvider directory={value()}>
|
||||
<SessionUIProvider directory={value()} server={server.key}>
|
||||
|
|
@ -100,6 +96,14 @@ function ResolvedTargetSessionRoute() {
|
|||
)
|
||||
}
|
||||
|
||||
function SessionStatePanel(props: ParentProps) {
|
||||
return (
|
||||
<div class="flex min-h-0 flex-1 p-2">
|
||||
<SessionPanelFrame raised>{props.children}</SessionPanelFrame>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function TargetSessionPage() {
|
||||
const location = useWorkspaceLocation()
|
||||
const server = useServerSDK()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { useSettings } from "@/settings/model"
|
|||
import { MessageTimeline } from "@/session/timeline/message-timeline"
|
||||
import type { SessionModel } from "@/session/model"
|
||||
import { SESSION_PANEL_WIDTH_MIN } from "@/session/session-panel-width"
|
||||
import { SessionPanelFrame, SessionRouteFrame } from "@/session/session-frame"
|
||||
import { SessionPanelFrame } from "@/session/session-frame"
|
||||
import { TerminalPanel } from "@/session/terminal/panel"
|
||||
import { useUsageExceededDialogs } from "./usage-exceeded-dialogs"
|
||||
import { SessionErrorFallback } from "./route-error"
|
||||
|
|
@ -58,10 +58,15 @@ export function SessionScreen(props: { session: SessionModel }) {
|
|||
|
||||
const sessionPanelContent = () => (
|
||||
<>
|
||||
{timeline.resource() ?? ""}
|
||||
<Show when={!isDesktop() && !!session.identity.params.id && !mobileTabsBottom()}>
|
||||
<SessionMobileTabs review={review} compact />
|
||||
</Show>
|
||||
{/* Surface query errors without suspending session metadata while messages load. */}
|
||||
<Show when={timeline.resource.error}>
|
||||
{(error) => {
|
||||
throw error()
|
||||
}}
|
||||
</Show>
|
||||
<div class="flex-1 min-h-0 overflow-hidden">
|
||||
<Switch>
|
||||
<Match when={session.identity.params.id && review.mobile.changes()}>
|
||||
|
|
@ -117,7 +122,7 @@ export function SessionScreen(props: { session: SessionModel }) {
|
|||
)
|
||||
|
||||
return (
|
||||
<SessionRouteFrame>
|
||||
<>
|
||||
<SessionHeader />
|
||||
<div class="flex-1 min-h-0 flex flex-col gap-2 p-2">
|
||||
<div ref={screen.panel.ref} class="flex-1 min-h-0 flex flex-col md:flex-row gap-2">
|
||||
|
|
@ -220,6 +225,6 @@ export function SessionScreen(props: { session: SessionModel }) {
|
|||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</SessionRouteFrame>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { Route, useParams } from "@solidjs/router"
|
||||
import { createMemo, lazy, Show, type ParentProps } from "solid-js"
|
||||
import { createMemo, lazy, Show, Suspense, type ParentProps } from "solid-js"
|
||||
import { Home } from "@/home/route"
|
||||
import { ServerProvider } from "@/runtime/server/current"
|
||||
import { useGlobal } from "@/runtime/server/runtime"
|
||||
import { ServerConnection } from "@/runtime/server/registry"
|
||||
import { SessionPanelFrame, SessionRouteFrame } from "@/session/session-frame"
|
||||
import { LayoutProvider } from "@/shell/state/layout"
|
||||
import Shell from "@/shell/shell"
|
||||
import { requireServerKey } from "./session"
|
||||
|
|
@ -31,9 +32,19 @@ export function AppRoutes() {
|
|||
<Route
|
||||
path="/server/:serverKey/session/:id"
|
||||
component={() => (
|
||||
<TargetServerRoute>
|
||||
<TargetSessionRouteContent />
|
||||
</TargetServerRoute>
|
||||
<SessionRouteFrame>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div class="flex min-h-0 flex-1 p-2">
|
||||
<SessionPanelFrame raised />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<TargetServerRoute>
|
||||
<TargetSessionRouteContent />
|
||||
</TargetServerRoute>
|
||||
</Suspense>
|
||||
</SessionRouteFrame>
|
||||
)}
|
||||
/>
|
||||
<Route path="/new-session" component={DraftRoute} />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue