diff --git a/packages/app/src/context/server.tsx b/packages/app/src/context/server.tsx index 8945cd37e..107657092 100644 --- a/packages/app/src/context/server.tsx +++ b/packages/app/src/context/server.tsx @@ -36,6 +36,7 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext( createStore({ list: [] as string[], projects: {} as Record, + lastProject: {} as Record, }), ) @@ -197,6 +198,16 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext( result.splice(toIndex, 0, item) setStore("projects", key, result) }, + last() { + const key = origin() + if (!key) return + return store.lastProject[key] + }, + touch(directory: string) { + const key = origin() + if (!key) return + setStore("lastProject", key, directory) + }, }, } }, diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index 275113566..a9e89a7f5 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -1,4 +1,3 @@ -import { useGlobalSync } from "@/context/global-sync" import { createMemo, For, Match, Show, Switch } from "solid-js" import { Button } from "@opencode-ai/ui/button" import { Logo } from "@opencode-ai/ui/logo" @@ -12,6 +11,7 @@ import { useDialog } from "@opencode-ai/ui/context/dialog" import { DialogSelectDirectory } from "@/components/dialog-select-directory" import { DialogSelectServer } from "@/components/dialog-select-server" import { useServer } from "@/context/server" +import { useGlobalSync } from "@/context/global-sync" export default function Home() { const sync = useGlobalSync() @@ -24,6 +24,7 @@ export default function Home() { function openProject(directory: string) { layout.projects.open(directory) + server.projects.touch(directory) navigate(`/${base64Encode(directory)}`) } diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index c25512a15..5e291449f 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -88,6 +88,7 @@ export default function Layout(props: ParentProps) { onCleanup(() => xlQuery.removeEventListener("change", handleViewportChange)) const params = useParams() + const [autoselect, setAutoselect] = createSignal(!params.dir) const globalSDK = useGlobalSDK() const globalSync = useGlobalSync() const layout = useLayout() @@ -101,6 +102,7 @@ export default function Layout(props: ParentProps) { const dialog = useDialog() const command = useCommand() const theme = useTheme() + const initialDir = params.dir const availableThemeEntries = createMemo(() => Object.entries(theme.themes())) const colorSchemeOrder: ColorScheme[] = ["system", "light", "dark"] const colorSchemeLabel: Record = { @@ -400,6 +402,43 @@ export default function Layout(props: ParentProps) { return layout.projects.list().find((p) => p.worktree === directory || p.sandboxes?.includes(directory)) }) + createEffect( + on( + () => ({ ready: pageReady(), project: currentProject() }), + (value) => { + if (!value.ready) return + const project = value.project + if (!project) return + const last = server.projects.last() + if (last === project.worktree) return + server.projects.touch(project.worktree) + }, + { defer: true }, + ), + ) + + createEffect( + on( + () => ({ ready: pageReady(), layoutReady: layoutReady(), dir: params.dir, list: layout.projects.list() }), + (value) => { + if (!value.ready) return + if (!value.layoutReady) return + if (!autoselect()) return + if (initialDir) return + if (value.dir) return + if (value.list.length === 0) return + + const last = server.projects.last() + const next = value.list.find((project) => project.worktree === last) ?? value.list[0] + if (!next) return + setAutoselect(false) + openProject(next.worktree, false) + navigateToProject(next.worktree) + }, + { defer: true }, + ), + ) + const workspaceName = (directory: string) => store.workspaceName[directory] const workspaceLabel = (directory: string, branch?: string) => workspaceName(directory) ?? branch ?? getFilename(directory) @@ -791,6 +830,7 @@ export default function Layout(props: ParentProps) { function navigateToProject(directory: string | undefined) { if (!directory) return + server.projects.touch(directory) const lastSession = store.lastSession[directory] navigate(`/${base64Encode(directory)}${lastSession ? `/session/${lastSession}` : ""}`) layout.mobileSidebar.hide()