11import { createStore , produce } from "solid-js/store"
22import { batch , createEffect , createMemo , onCleanup , onMount , type Accessor } from "solid-js"
3+ import { useLocation } from "@solidjs/router"
34import { createSimpleContext } from "@opencode-ai/ui/context"
45import { makeEventListener } from "@solid-primitives/event-listener"
56import { useServerSync } from "./server-sync"
67import { useServerSDK } from "./server-sdk"
7- import { useServer } from "./server"
8+ import { ServerConnection , useServer } from "./server"
89import { usePlatform } from "./platform"
910import { Project } from "@opencode-ai/sdk/v2"
1011import { Persist , persisted , removePersisted } from "@/utils/persist"
@@ -13,6 +14,9 @@ import { same } from "@/utils/same"
1314import { createScrollPersistence , type SessionScroll } from "./layout-scroll"
1415import { createPathHelpers } from "./file/path"
1516import type { ProjectAvatarVariant } from "@opencode-ai/ui/v2/project-avatar-v2"
17+ import { createSessionKeyReader , ensureSessionKey , pruneSessionKeys } from "./layout-helpers"
18+
19+ export { createSessionKeyReader , ensureSessionKey , pruneSessionKeys }
1620
1721export type { ProjectAvatarVariant }
1822
@@ -69,42 +73,10 @@ export type LocalProject = Partial<Project> & { worktree: string; expanded: bool
6973
7074export type ReviewDiffStyle = "unified" | "split"
7175
72- export function ensureSessionKey ( key : string , touch : ( key : string ) => void , seed : ( key : string ) => void ) {
73- touch ( key )
74- seed ( key )
75- return key
76- }
77-
78- export function createSessionKeyReader ( sessionKey : string | Accessor < string > , ensure : ( key : string ) => void ) {
79- const key = typeof sessionKey === "function" ? sessionKey : ( ) => sessionKey
80- return ( ) => {
81- const value = key ( )
82- ensure ( value )
83- return value
84- }
85- }
86-
87- export function pruneSessionKeys ( input : {
88- keep ?: string
89- max : number
90- used : Map < string , number >
91- view : string [ ]
92- tabs : string [ ]
93- } ) {
94- if ( ! input . keep ) return [ ]
95-
96- const keys = new Set < string > ( [ ...input . view , ...input . tabs ] )
97- if ( keys . size <= input . max ) return [ ]
98-
99- const score = ( key : string ) => {
100- if ( key === input . keep ) return Number . MAX_SAFE_INTEGER
101- return input . used . get ( key ) ?? 0
102- }
103-
104- return Array . from ( keys )
105- . sort ( ( a , b ) => score ( b ) - score ( a ) )
106- . slice ( input . max )
107- }
76+ export type LayoutRoute =
77+ | { type : "home" }
78+ | { type : "dir-new-sesssion" ; dir : string ; dirBase64 : string ; server ?: ServerConnection . Key }
79+ | { type : "session" ; dir : string ; dirBase64 : string ; sessionId : string ; server ?: ServerConnection . Key }
10880
10981function nextSessionTabsForOpen ( current : SessionTabs | undefined , tab : string ) : SessionTabs {
11082 const all = current ?. all ?? [ ]
@@ -146,13 +118,30 @@ const normalizeStoredSessionTabs = (key: string, tabs: SessionTabs) => {
146118 }
147119}
148120
121+ const currentRoute = ( pathname : string ) : LayoutRoute => {
122+ const parts = pathname . split ( "/" ) . filter ( Boolean )
123+ if ( parts . length === 0 ) return { type : "home" }
124+
125+ const dirBase64 = parts [ 0 ]
126+ const dir = decode64 ( dirBase64 )
127+ if ( ! dir ) return { type : "home" }
128+
129+ if ( parts [ 1 ] !== "session" ) return { type : "home" }
130+
131+ const id = parts [ 2 ]
132+ if ( id ) return { type : "session" , dir, dirBase64, sessionId : id }
133+ return { type : "dir-new-sesssion" , dir, dirBase64 }
134+ }
135+
149136export const { use : useLayout , provider : LayoutProvider } = createSimpleContext ( {
150137 name : "Layout" ,
151138 init : ( ) => {
152139 const globalSdk = useServerSDK ( )
153140 const serverSync = useServerSync ( )
154141 const server = useServer ( )
155142 const platform = usePlatform ( )
143+ const location = useLocation ( )
144+ const route = createMemo ( ( ) => currentRoute ( location . pathname ) )
156145
157146 const isRecord = ( value : unknown ) : value is Record < string , unknown > =>
158147 typeof value === "object" && value !== null && ! Array . isArray ( value )
@@ -557,6 +546,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
557546 } )
558547
559548 return {
549+ route,
560550 ready,
561551 handoff : {
562552 tabs : createMemo ( ( ) => store . handoff ?. tabs ) ,
0 commit comments