summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/layout.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-22 21:01:09 -0600
committerAdam <[email protected]>2026-01-23 05:18:57 -0600
commit4afb46f571e85d0fb4352705c5cc1105985ef745 (patch)
tree55822295687f8868131ed3850208beb256fa9b1a /packages/app/src/context/layout.tsx
parentc4d223eb99c4f677ff9f540cbef1f71e8a502ac8 (diff)
downloadopencode-4afb46f571e85d0fb4352705c5cc1105985ef745.tar.gz
opencode-4afb46f571e85d0fb4352705c5cc1105985ef745.zip
perf(app): don't remount directory layout
Diffstat (limited to 'packages/app/src/context/layout.tsx')
-rw-r--r--packages/app/src/context/layout.tsx111
1 files changed, 72 insertions, 39 deletions
diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx
index 444a36d65..ddd66aa2f 100644
--- a/packages/app/src/context/layout.tsx
+++ b/packages/app/src/context/layout.tsx
@@ -1,5 +1,5 @@
import { createStore, produce } from "solid-js/store"
-import { batch, createEffect, createMemo, onCleanup, onMount } from "solid-js"
+import { batch, createEffect, createMemo, on, onCleanup, onMount, type Accessor } from "solid-js"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { useGlobalSync } from "./global-sync"
import { useGlobalSDK } from "./global-sdk"
@@ -432,10 +432,24 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
setStore("mobileSidebar", "opened", (x) => !x)
},
},
- view(sessionKey: string) {
- touch(sessionKey)
- scroll.seed(sessionKey)
- const s = createMemo(() => store.sessionView[sessionKey] ?? { scroll: {} })
+ view(sessionKey: string | Accessor<string>) {
+ const key = typeof sessionKey === "function" ? sessionKey : () => sessionKey
+
+ touch(key())
+ scroll.seed(key())
+
+ createEffect(
+ on(
+ key,
+ (value) => {
+ touch(value)
+ scroll.seed(value)
+ },
+ { defer: true },
+ ),
+ )
+
+ const s = createMemo(() => store.sessionView[key()] ?? { scroll: {} })
const terminalOpened = createMemo(() => store.terminal?.opened ?? false)
const reviewPanelOpened = createMemo(() => store.review?.panelOpened ?? true)
@@ -465,10 +479,10 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
return {
scroll(tab: string) {
- return scroll.scroll(sessionKey, tab)
+ return scroll.scroll(key(), tab)
},
setScroll(tab: string, pos: SessionScroll) {
- scroll.setScroll(sessionKey, tab, pos)
+ scroll.setScroll(key(), tab, pos)
},
terminal: {
opened: terminalOpened,
@@ -497,9 +511,10 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
review: {
open: createMemo(() => s().reviewOpen),
setOpen(open: string[]) {
- const current = store.sessionView[sessionKey]
+ const session = key()
+ const current = store.sessionView[session]
if (!current) {
- setStore("sessionView", sessionKey, {
+ setStore("sessionView", session, {
scroll: {},
reviewOpen: open,
})
@@ -507,93 +522,111 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
}
if (same(current.reviewOpen, open)) return
- setStore("sessionView", sessionKey, "reviewOpen", open)
+ setStore("sessionView", session, "reviewOpen", open)
},
},
}
},
- tabs(sessionKey: string) {
- touch(sessionKey)
- const tabs = createMemo(() => store.sessionTabs[sessionKey] ?? { all: [] })
+ tabs(sessionKey: string | Accessor<string>) {
+ const key = typeof sessionKey === "function" ? sessionKey : () => sessionKey
+
+ touch(key())
+
+ createEffect(
+ on(
+ key,
+ (value) => {
+ touch(value)
+ },
+ { defer: true },
+ ),
+ )
+
+ const tabs = createMemo(() => store.sessionTabs[key()] ?? { all: [] })
return {
tabs,
active: createMemo(() => tabs().active),
all: createMemo(() => tabs().all),
setActive(tab: string | undefined) {
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all: [], active: tab })
+ const session = key()
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all: [], active: tab })
} else {
- setStore("sessionTabs", sessionKey, "active", tab)
+ setStore("sessionTabs", session, "active", tab)
}
},
setAll(all: string[]) {
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all, active: undefined })
+ const session = key()
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all, active: undefined })
} else {
- setStore("sessionTabs", sessionKey, "all", all)
+ setStore("sessionTabs", session, "all", all)
}
},
async open(tab: string) {
- const current = store.sessionTabs[sessionKey] ?? { all: [] }
+ const session = key()
+ const current = store.sessionTabs[session] ?? { all: [] }
if (tab === "review") {
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all: [], active: tab })
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all: [], active: tab })
return
}
- setStore("sessionTabs", sessionKey, "active", tab)
+ setStore("sessionTabs", session, "active", tab)
return
}
if (tab === "context") {
const all = [tab, ...current.all.filter((x) => x !== tab)]
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all, active: tab })
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all, active: tab })
return
}
- setStore("sessionTabs", sessionKey, "all", all)
- setStore("sessionTabs", sessionKey, "active", tab)
+ setStore("sessionTabs", session, "all", all)
+ setStore("sessionTabs", session, "active", tab)
return
}
if (!current.all.includes(tab)) {
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all: [tab], active: tab })
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all: [tab], active: tab })
return
}
- setStore("sessionTabs", sessionKey, "all", [...current.all, tab])
- setStore("sessionTabs", sessionKey, "active", tab)
+ setStore("sessionTabs", session, "all", [...current.all, tab])
+ setStore("sessionTabs", session, "active", tab)
return
}
- if (!store.sessionTabs[sessionKey]) {
- setStore("sessionTabs", sessionKey, { all: current.all, active: tab })
+ if (!store.sessionTabs[session]) {
+ setStore("sessionTabs", session, { all: current.all, active: tab })
return
}
- setStore("sessionTabs", sessionKey, "active", tab)
+ setStore("sessionTabs", session, "active", tab)
},
close(tab: string) {
- const current = store.sessionTabs[sessionKey]
+ const session = key()
+ const current = store.sessionTabs[session]
if (!current) return
const all = current.all.filter((x) => x !== tab)
batch(() => {
- setStore("sessionTabs", sessionKey, "all", all)
+ setStore("sessionTabs", session, "all", all)
if (current.active !== tab) return
const index = current.all.findIndex((f) => f === tab)
const next = all[index - 1] ?? all[0]
- setStore("sessionTabs", sessionKey, "active", next)
+ setStore("sessionTabs", session, "active", next)
})
},
move(tab: string, to: number) {
- const current = store.sessionTabs[sessionKey]
+ const session = key()
+ const current = store.sessionTabs[session]
if (!current) return
const index = current.all.findIndex((f) => f === tab)
if (index === -1) return
setStore(
"sessionTabs",
- sessionKey,
+ session,
"all",
produce((opened) => {
opened.splice(to, 0, opened.splice(index, 1)[0])