summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authorOpeOginni <[email protected]>2026-01-05 20:32:16 +0100
committerGitHub <[email protected]>2026-01-05 13:32:16 -0600
commit8996185f3bf5da3a3dd54303015f5d6a6378d0f7 (patch)
tree4bf1b904a9ab33333a186d2c06da9a7b48d6ef60 /packages/app/src
parent4f4996751853dbc77f91730329503ea86292aae4 (diff)
downloadopencode-8996185f3bf5da3a3dd54303015f5d6a6378d0f7.tar.gz
opencode-8996185f3bf5da3a3dd54303015f5d6a6378d0f7.zip
Feat/clickable subtask (#6846)
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/session/session-header.tsx69
-rw-r--r--packages/app/src/pages/directory-layout.tsx14
2 files changed, 69 insertions, 14 deletions
diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx
index 6c102e4bd..ded5d9d0f 100644
--- a/packages/app/src/components/session/session-header.tsx
+++ b/packages/app/src/components/session/session-header.tsx
@@ -35,7 +35,12 @@ export function SessionHeader() {
const projectDirectory = createMemo(() => base64Decode(params.dir ?? ""))
const sessions = createMemo(() => (sync.data.session ?? []).filter((s) => !s.parentID))
- const currentSession = createMemo(() => sessions().find((s) => s.id === params.id))
+ const currentSession = createMemo(() => sync.data.session.find((s) => s.id === params.id))
+ const parentSession = createMemo(() => {
+ const current = currentSession()
+ if (!current?.parentID) return undefined
+ return sync.data.session.find((s) => s.id === current.parentID)
+ })
const shareEnabled = createMemo(() => sync.data.config.share !== "disabled")
const worktrees = createMemo(() => layout.projects.list().map((p) => p.worktree), [], { equals: same })
@@ -45,6 +50,8 @@ export function SessionHeader() {
function navigateToSession(session: Session | undefined) {
if (!session) return
+ // Only navigate if we're actually changing to a different session
+ if (session.id === params.id) return
navigate(`/${params.dir}/session/${session.id}`)
}
@@ -79,18 +86,56 @@ export function SessionHeader() {
</Select>
<div class="text-text-weaker">/</div>
</div>
- <Select
- options={sessions()}
- current={currentSession()}
- placeholder="New session"
- label={(x) => x.title}
- value={(x) => x.id}
- onSelect={navigateToSession}
- class="text-14-regular text-text-base max-w-[calc(100vw-180px)] md:max-w-md"
- variant="ghost"
- />
+ <Show
+ when={parentSession()}
+ fallback={
+ <>
+ <Select
+ options={sessions()}
+ current={currentSession()}
+ placeholder="New session"
+ label={(x) => x.title}
+ value={(x) => x.id}
+ onSelect={navigateToSession}
+ class="text-14-regular text-text-base max-w-[calc(100vw-180px)] md:max-w-md"
+ variant="ghost"
+ />
+ </>
+ }
+ >
+ <div class="flex items-center gap-2 min-w-0">
+ <Select
+ options={sessions()}
+ current={parentSession()}
+ placeholder="Back to parent session"
+ label={(x) => x.title}
+ value={(x) => x.id}
+ onSelect={(session) => {
+ // Only navigate if selecting a different session than current parent
+ const currentParent = parentSession()
+ if (session && currentParent && session.id !== currentParent.id) {
+ navigateToSession(session)
+ }
+ }}
+ class="text-14-regular text-text-base max-w-[calc(100vw-180px)] md:max-w-md"
+ variant="ghost"
+ />
+ <div class="text-text-weaker">/</div>
+ <div class="flex items-center gap-1.5 min-w-0">
+ <Tooltip value="Back to parent session">
+ <button
+ type="button"
+ class="flex items-center justify-center gap-1 p-1 rounded hover:bg-surface-raised-base-hover active:bg-surface-raised-base-active transition-colors flex-shrink-0"
+ onClick={() => navigateToSession(parentSession())}
+ >
+ <Icon name="arrow-left" size="small" class="text-icon-base" />
+ </button>
+ </Tooltip>
+ </div>
+ </div>
+ </Show>
</div>
- <Show when={currentSession()}>
+ <Show when={currentSession() && !parentSession()}>
<TooltipKeybind class="hidden xl:block" title="New session" keybind={command.keybind("session.new")}>
<IconButton as={A} href={`/${params.dir}/session`} icon="edit-small-2" variant="ghost" />
</TooltipKeybind>
diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx
index 6aac3c384..39124637c 100644
--- a/packages/app/src/pages/directory-layout.tsx
+++ b/packages/app/src/pages/directory-layout.tsx
@@ -1,5 +1,5 @@
import { createMemo, Show, type ParentProps } from "solid-js"
-import { useParams } from "@solidjs/router"
+import { useNavigate, useParams } from "@solidjs/router"
import { SDKProvider, useSDK } from "@/context/sdk"
import { SyncProvider, useSync } from "@/context/sync"
import { LocalProvider } from "@/context/local"
@@ -10,6 +10,7 @@ import { iife } from "@opencode-ai/util/iife"
export default function Layout(props: ParentProps) {
const params = useParams()
+ const navigate = useNavigate()
const directory = createMemo(() => {
return base64Decode(params.dir!)
})
@@ -26,8 +27,17 @@ export default function Layout(props: ParentProps) {
response: "once" | "always" | "reject"
}) => sdk.client.permission.respond(input)
+ const navigateToSession = (sessionID: string) => {
+ navigate(`/${params.dir}/session/${sessionID}`)
+ }
+
return (
- <DataProvider data={sync.data} directory={directory()} onPermissionRespond={respond}>
+ <DataProvider
+ data={sync.data}
+ directory={directory()}
+ onPermissionRespond={respond}
+ onNavigateToSession={navigateToSession}
+ >
<LocalProvider>{props.children}</LocalProvider>
</DataProvider>
)