diff options
Diffstat (limited to 'packages/app/src/context/layout.tsx')
| -rw-r--r-- | packages/app/src/context/layout.tsx | 94 |
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, |
