summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context/layout.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-01 10:52:26 -0600
committerAdam <[email protected]>2026-01-01 21:03:03 -0600
commitb8872d9d20c76ef351a0ec356558b1484a74f20f (patch)
treedca28cfbb0f72e3d2507df06849b1647975daccd /packages/app/src/context/layout.tsx
parent78940d5b7ee2f3e5020f87b400db1785b37a7d71 (diff)
downloadopencode-b8872d9d20c76ef351a0ec356558b1484a74f20f.tar.gz
opencode-b8872d9d20c76ef351a0ec356558b1484a74f20f.zip
wip(desktop): progress
Diffstat (limited to 'packages/app/src/context/layout.tsx')
-rw-r--r--packages/app/src/context/layout.tsx78
1 files changed, 70 insertions, 8 deletions
diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx
index 613a0e0c1..6a9258b4c 100644
--- a/packages/app/src/context/layout.tsx
+++ b/packages/app/src/context/layout.tsx
@@ -23,11 +23,28 @@ export function getAvatarColors(key?: string) {
}
}
+function same<T>(a: readonly T[] | undefined, b: readonly T[] | undefined) {
+ if (a === b) return true
+ if (!a || !b) return false
+ if (a.length !== b.length) return false
+ return a.every((x, i) => x === b[i])
+}
+
type SessionTabs = {
active?: string
all: string[]
}
+type SessionScroll = {
+ x: number
+ y: number
+}
+
+type SessionView = {
+ scroll: Record<string, SessionScroll>
+ reviewOpen?: string[]
+}
+
export type LocalProject = Partial<Project> & { worktree: string; expanded: boolean }
export type ReviewDiffStyle = "unified" | "split"
@@ -39,7 +56,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
const globalSync = useGlobalSync()
const server = useServer()
const [store, setStore, _, ready] = persisted(
- "layout.v4",
+ "layout.v6",
createStore({
sidebar: {
opened: false,
@@ -56,7 +73,11 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
session: {
width: 600,
},
+ mobileSidebar: {
+ opened: false,
+ },
sessionTabs: {} as Record<string, SessionTabs>,
+ sessionView: {} as Record<string, SessionView>,
}),
)
@@ -182,11 +203,55 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
resize(width: number) {
if (!store.session) {
setStore("session", { width })
- } else {
- setStore("session", "width", width)
+ return
}
+ setStore("session", "width", width)
+ },
+ },
+ mobileSidebar: {
+ opened: createMemo(() => store.mobileSidebar?.opened ?? false),
+ show() {
+ setStore("mobileSidebar", "opened", true)
+ },
+ hide() {
+ setStore("mobileSidebar", "opened", false)
+ },
+ toggle() {
+ setStore("mobileSidebar", "opened", (x) => !x)
},
},
+ view(sessionKey: string) {
+ const s = createMemo(() => store.sessionView[sessionKey] ?? { scroll: {} })
+ return {
+ scroll(tab: string) {
+ return s().scroll?.[tab]
+ },
+ setScroll(tab: string, pos: SessionScroll) {
+ const current = store.sessionView[sessionKey]
+ if (!current) {
+ setStore("sessionView", sessionKey, { scroll: { [tab]: pos } })
+ return
+ }
+
+ const prev = current.scroll?.[tab]
+ if (prev?.x === pos.x && prev?.y === pos.y) return
+ setStore("sessionView", sessionKey, "scroll", tab, pos)
+ },
+ review: {
+ open: createMemo(() => s().reviewOpen),
+ setOpen(open: string[]) {
+ const current = store.sessionView[sessionKey]
+ if (!current) {
+ setStore("sessionView", sessionKey, { scroll: {}, reviewOpen: open })
+ return
+ }
+
+ if (same(current.reviewOpen, open)) return
+ setStore("sessionView", sessionKey, "reviewOpen", open)
+ },
+ },
+ }
+ },
tabs(sessionKey: string) {
const tabs = createMemo(() => store.sessionTabs[sessionKey] ?? { all: [] })
return {
@@ -256,11 +321,8 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
if (current.active !== tab) return
const index = current.all.findIndex((f) => f === tab)
- if (index <= 0) {
- setStore("sessionTabs", sessionKey, "active", undefined)
- return
- }
- setStore("sessionTabs", sessionKey, "active", current.all[index - 1])
+ const next = all[index - 1] ?? all[0]
+ setStore("sessionTabs", sessionKey, "active", next)
})
},
move(tab: string, to: number) {