From 5e2e4a1da7c08f2c423c36452df20c742ffc3cf4 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Tue, 28 Jul 2026 14:41:23 +0800 Subject: [PATCH] refactor(app): simplify new session view --- packages/app/src/components/session/index.ts | 1 - .../session/session-new-design-view.tsx | 16 -- packages/app/src/pages/new-session.tsx | 31 +++- .../pages/new-session/new-session-view.tsx | 153 +++++++++--------- .../app/src/pages/new-session/new-session.tsx | 47 ------ 5 files changed, 102 insertions(+), 146 deletions(-) delete mode 100644 packages/app/src/components/session/session-new-design-view.tsx delete mode 100644 packages/app/src/pages/new-session/new-session.tsx diff --git a/packages/app/src/components/session/index.ts b/packages/app/src/components/session/index.ts index 9e44cea17b..c4fdb2ff38 100644 --- a/packages/app/src/components/session/index.ts +++ b/packages/app/src/components/session/index.ts @@ -4,4 +4,3 @@ export { SortableTab, FileVisual } from "./session-sortable-tab" export { SortableTabV2 } from "./session-sortable-tab-v2" export { SortableTerminalTab } from "./session-sortable-terminal-tab" export { NewSessionView } from "./session-new-view" -export { NewSessionDesignView } from "./session-new-design-view" diff --git a/packages/app/src/components/session/session-new-design-view.tsx b/packages/app/src/components/session/session-new-design-view.tsx deleted file mode 100644 index a324c64fa6..0000000000 --- a/packages/app/src/components/session/session-new-design-view.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { JSX } from "solid-js" -import { WordmarkV2 } from "@opencode-ai/ui/v2/wordmark-v2" -import { NEW_SESSION_CONTENT_WIDTH } from "@/pages/session/new-session-layout" - -export function NewSessionDesignView(props: { children: JSX.Element }) { - return ( -
-
-
- -
{props.children}
-
-
-
- ) -} diff --git a/packages/app/src/pages/new-session.tsx b/packages/app/src/pages/new-session.tsx index e96f58ae76..9fca3d77dd 100644 --- a/packages/app/src/pages/new-session.tsx +++ b/packages/app/src/pages/new-session.tsx @@ -1,11 +1,16 @@ import { createPromptProjectController } from "@/components/prompt-project-selector" +import { useTitlebarRightMount } from "@/components/titlebar" +import { useSettings } from "@/context/settings" +import { createEffect, createResource } from "solid-js" import { createNewSessionCommandController } from "./new-session/new-session-command-controller" import { createNewSessionDraftController } from "./new-session/new-session-draft-controller" -import { NewSession } from "./new-session/new-session" +import { NewSessionStatus, NewSessionView } from "./new-session/new-session-view" import { createNewSessionWorkspaceController } from "./new-session/new-session-workspace-controller" /** The draft-only V2 session page. Submitting promotes the draft into a real session. */ export default function NewSessionPage() { + const settings = useSettings() + const rightMount = useTitlebarRightMount() const workspace = createNewSessionWorkspaceController() const draft = createNewSessionDraftController({ worktree: workspace.selection.value, @@ -22,6 +27,28 @@ export default function NewSessionPage() { open: () => project.setOpen(true), }, }) + createEffect(() => { + if (!draft.prompt.ready()) return + draft.input.restoreFocus() + }) + const ready = Promise.resolve() + const [suspendUntilPromptReady] = createResource( + () => draft.prompt.readyPromise() ?? ready, + (promise) => promise.then(() => true), + ) - return + return ( +
+ {suspendUntilPromptReady()} + +
+ +
+
+ ) } diff --git a/packages/app/src/pages/new-session/new-session-view.tsx b/packages/app/src/pages/new-session/new-session-view.tsx index aba05e6acd..688c2edf0f 100644 --- a/packages/app/src/pages/new-session/new-session-view.tsx +++ b/packages/app/src/pages/new-session/new-session-view.tsx @@ -1,109 +1,102 @@ import { Tooltip } from "@opencode-ai/ui/tooltip" import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" -import { Show, createEffect, createMemo, createResource, createSignal, type Accessor, type JSX } from "solid-js" +import { WordmarkV2 } from "@opencode-ai/ui/v2/wordmark-v2" +import { Show, createMemo, createSignal, type Accessor } from "solid-js" import { createStore } from "solid-js/store" import { Portal } from "solid-js/web" import createPresence from "solid-presence" -import { NewSessionDesignView } from "@/components/session" +import { PromptInputV2Composer } from "@/components/prompt-input-v2" import { PromptGitStatus, PromptWorkspaceSelector } from "@/components/prompt-workspace-selector" -import type { PromptProject } from "@/components/prompt-project-selector" +import { + PromptProjectAddButton, + PromptProjectSelector, + type PromptProjectController, +} from "@/components/prompt-project-selector" import { StatusPopoverV2 } from "@/components/status-popover" import { useLanguage } from "@/context/language" import { NEW_SESSION_CONTENT_WIDTH } from "@/pages/session/new-session-layout" import { Persist, persisted } from "@/utils/persist" +import type { NewSessionCommandController } from "./new-session-command-controller" +import type { NewSessionDraftController } from "./new-session-draft-controller" +import type { NewSessionWorkspaceController } from "./new-session-workspace-controller" const providerTipDismissalDuration = 30 * 24 * 60 * 60 * 1000 export function NewSessionView(props: { - rightMount: Accessor - statusVisible: Accessor - statusLabel: Accessor - promptReady: Accessor - promptReadyPromise: Accessor | undefined> - restoreFocus: () => void - composer: () => JSX.Element - projectEmpty: Accessor - projectSelected: Accessor - projectAdd: () => JSX.Element - projectSelector: () => JSX.Element - workspaceVisible: Accessor - workspaceValue: Accessor - workspaceRoot: Accessor - workspaces: Accessor - branch: Accessor - noGit: Accessor - onWorkspaceChange: (value: string) => void - providerReady: Accessor - providerConnected: Accessor - onOpenProviders: () => void + input: NewSessionDraftController["input"] + project: PromptProjectController + workspace: NewSessionWorkspaceController + provider: NewSessionCommandController["provider"] }) { - createEffect(() => { - if (!props.promptReady()) return - props.restoreFocus() - }) - - const ready = Promise.resolve() - const [suspendUntilPromptReady] = createResource( - () => props.promptReadyPromise() ?? ready, - (promise) => promise.then(() => true), - ) - return ( -
- {suspendUntilPromptReady()} - - {(mount) => ( - - - - - - - - )} - -
-
-
- -
-
- {props.composer()} - {props.projectAdd()} - -
- {props.projectSelector()} - } - > - - -
+
+
+
+
+ +
+ + + + + +
+ + + } + > +
-
- - + +
+
) } +export function NewSessionStatus(props: { mount: Accessor; visible: Accessor }) { + const language = useLanguage() + + return ( + + {(mount) => ( + + + + + + + + )} + + ) +} + function ProviderTip(props: { ready: Accessor; connected: Accessor; openProviders: () => void }) { const language = useLanguage() const [persistedState, setPersistedState, , persistedReady] = persisted( diff --git a/packages/app/src/pages/new-session/new-session.tsx b/packages/app/src/pages/new-session/new-session.tsx deleted file mode 100644 index e14e9189be..0000000000 --- a/packages/app/src/pages/new-session/new-session.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import type { PromptProjectController } from "@/components/prompt-project-selector" -import { PromptProjectAddButton, PromptProjectSelector } from "@/components/prompt-project-selector" -import { PromptInputV2Composer } from "@/components/prompt-input-v2" -import { useLanguage } from "@/context/language" -import { useSettings } from "@/context/settings" -import { useTitlebarRightMount } from "@/components/titlebar" -import type { NewSessionCommandController } from "./new-session-command-controller" -import type { NewSessionDraftController } from "./new-session-draft-controller" -import { NewSessionView } from "./new-session-view" -import type { NewSessionWorkspaceController } from "./new-session-workspace-controller" - -export function NewSession(props: { - draft: NewSessionDraftController - commands: NewSessionCommandController - workspace: NewSessionWorkspaceController - project: PromptProjectController -}) { - const language = useLanguage() - const settings = useSettings() - const rightMount = useTitlebarRightMount() - - return ( - language.t("status.popover.trigger")} - promptReady={props.draft.prompt.ready} - promptReadyPromise={props.draft.prompt.readyPromise} - restoreFocus={props.draft.input.restoreFocus} - composer={() => } - projectEmpty={props.project.empty} - projectSelected={props.project.selected} - projectAdd={() => } - projectSelector={() => } - workspaceVisible={props.workspace.bar.visible} - workspaceValue={props.workspace.selection.value} - workspaceRoot={props.workspace.project.root} - workspaces={props.workspace.project.workspaces} - branch={props.workspace.bar.branch} - noGit={() => !props.workspace.project.git()} - onWorkspaceChange={props.workspace.selection.set} - providerReady={props.commands.provider.ready} - providerConnected={props.commands.provider.connected} - onOpenProviders={props.commands.provider.open} - /> - ) -}