summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/layout.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/context/layout.tsx')
-rw-r--r--packages/app/src/context/layout.tsx94
1 files changed, 49 insertions, 45 deletions
diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx
index 95a2006ea..8d9c865f8 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, on, onCleanup, onMount, type Accessor } from "solid-js"
+import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { useGlobalSync } from "./global-sync"
import { useGlobalSDK } from "./global-sdk"
@@ -47,6 +47,43 @@ export type LocalProject = Partial<Project> & { worktree: string; expanded: bool
export type ReviewDiffStyle = "unified" | "split"
+export function ensureSessionKey(key: string, touch: (key: string) => void, seed: (key: string) => void) {
+ touch(key)
+ seed(key)
+ return key
+}
+
+export function createSessionKeyReader(sessionKey: string | Accessor<string>, ensure: (key: string) => void) {
+ const key = typeof sessionKey === "function" ? sessionKey : () => sessionKey
+ return () => {
+ const value = key()
+ ensure(value)
+ return value
+ }
+}
+
+export function pruneSessionKeys(input: {
+ keep?: string
+ max: number
+ used: Map<string, number>
+ view: string[]
+ tabs: string[]
+}) {
+ if (!input.keep) return []
+
+ const keys = new Set<string>([...input.view, ...input.tabs])
+ if (keys.size <= input.max) return []
+
+ const score = (key: string) => {
+ if (key === input.keep) return Number.MAX_SAFE_INTEGER
+ return input.used.get(key) ?? 0
+ }
+
+ return Array.from(keys)
+ .sort((a, b) => score(b) - score(a))
+ .slice(input.max)
+}
+
export const { use: useLayout, provider: LayoutProvider } = createSimpleContext({
name: "Layout",
init: () => {
@@ -172,20 +209,13 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
}
function prune(keep?: string) {
- if (!keep) return
-
- const keys = new Set<string>()
- for (const key of Object.keys(store.sessionView)) keys.add(key)
- for (const key of Object.keys(store.sessionTabs)) keys.add(key)
- if (keys.size <= MAX_SESSION_KEYS) return
-
- const score = (key: string) => {
- if (key === keep) return Number.MAX_SAFE_INTEGER
- return used.get(key) ?? 0
- }
-
- const ordered = Array.from(keys).sort((a, b) => score(b) - score(a))
- const drop = ordered.slice(MAX_SESSION_KEYS)
+ const drop = pruneSessionKeys({
+ keep,
+ max: MAX_SESSION_KEYS,
+ used,
+ view: Object.keys(store.sessionView),
+ tabs: Object.keys(store.sessionTabs),
+ })
if (drop.length === 0) return
setStore(
@@ -233,6 +263,8 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
},
})
+ const ensureKey = (key: string) => ensureSessionKey(key, touch, (sessionKey) => scroll.seed(sessionKey))
+
createEffect(() => {
if (!ready()) return
if (meta.pruned) return
@@ -616,22 +648,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
},
},
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 key = createSessionKeyReader(sessionKey, ensureKey)
const s = createMemo(() => store.sessionView[key()] ?? { scroll: {} })
const terminalOpened = createMemo(() => store.terminal?.opened ?? false)
const reviewPanelOpened = createMemo(() => store.review?.panelOpened ?? true)
@@ -711,20 +728,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
}
},
tabs(sessionKey: string | Accessor<string>) {
- const key = typeof sessionKey === "function" ? sessionKey : () => sessionKey
-
- touch(key())
-
- createEffect(
- on(
- key,
- (value) => {
- touch(value)
- },
- { defer: true },
- ),
- )
-
+ const key = createSessionKeyReader(sessionKey, ensureKey)
const tabs = createMemo(() => store.sessionTabs[key()] ?? { all: [] })
return {
tabs,