Skip to content

Commit 10e4b87

Browse files
authored
fix(app): persist home project selection (anomalyco#33935)
1 parent e7c59b1 commit 10e4b87

3 files changed

Lines changed: 31 additions & 22 deletions

File tree

packages/app/src/context/layout.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createStore, produce } from "solid-js/store"
1+
import { createStore, produce, reconcile } from "solid-js/store"
22
import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
33
import { useLocation } from "@solidjs/router"
44
import { createSimpleContext } from "@opencode-ai/ui/context"
@@ -73,6 +73,7 @@ type TabHandoff = {
7373
}
7474

7575
export type LocalProject = Partial<Project> & { worktree: string; expanded: boolean }
76+
export type HomeProjectSelection = { server: ServerConnection.Key; directory?: string }
7677

7778
export type ReviewDiffStyle = "unified" | "split"
7879

@@ -290,6 +291,9 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
290291
handoff: {
291292
tabs: undefined as TabHandoff | undefined,
292293
},
294+
home: {
295+
selection: { server: server.key } as HomeProjectSelection,
296+
},
293297
}),
294298
)
295299

@@ -579,6 +583,12 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
579583
return {
580584
route,
581585
ready,
586+
home: {
587+
selection: createMemo(() => store.home.selection),
588+
setSelection(selection: HomeProjectSelection) {
589+
setStore("home", "selection", reconcile(selection))
590+
},
591+
},
582592
handoff: {
583593
tabs: createMemo(() => store.handoff?.tabs),
584594
setTabs(dir: string, id: string) {

packages/app/src/pages/home.tsx

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { Session } from "@opencode-ai/sdk/v2/client"
22
import {
3-
batch,
43
createEffect,
54
createMemo,
65
createRoot,
@@ -26,7 +25,12 @@ import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon"
2625
import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
2726
import { MenuV2 } from "@opencode-ai/ui/v2/menu-v2"
2827
import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
29-
import { getProjectAvatarVariant, useLayout, type LocalProject } from "@/context/layout"
28+
import {
29+
getProjectAvatarVariant,
30+
useLayout,
31+
type HomeProjectSelection,
32+
type LocalProject,
33+
} from "@/context/layout"
3034
import { useNavigate } from "@solidjs/router"
3135
import { base64Encode } from "@opencode-ai/core/util/encode"
3236
import { Icon } from "@opencode-ai/ui/icon"
@@ -47,7 +51,6 @@ import {
4751
errorMessage,
4852
getProjectAvatarSource,
4953
homeProjectDirectories,
50-
type HomeProjectSelection,
5154
projectForSession,
5255
sortedRootSessions,
5356
toggleHomeProjectSelection,
@@ -149,12 +152,12 @@ export function NewHome() {
149152
let focusSessionSearch: (() => void) | undefined
150153
const [state, setState] = createStore({
151154
search: "",
152-
selection: { server: server.key } as HomeProjectSelection,
153155
searchFocused: false,
154156
})
157+
const selection = layout.home.selection
155158

156159
const focusedServer = createMemo(
157-
() => global.servers.list().find((conn) => ServerConnection.key(conn) === state.selection.server) ?? server.current,
160+
() => global.servers.list().find((conn) => ServerConnection.key(conn) === selection().server) ?? server.current,
158161
)
159162
const focusedServerCtx = createMemo(() => {
160163
const conn = focusedServer()
@@ -163,7 +166,7 @@ export function NewHome() {
163166
})
164167
const focusedSync = () => focusedServerCtx()?.sync ?? sync()
165168
const projects = createMemo(() => focusedServerCtx()?.projects.list() ?? layout.projects.list())
166-
const selectedProject = createMemo(() => projects().find((project) => project.worktree === state.selection.directory))
169+
const selectedProject = createMemo(() => projects().find((project) => project.worktree === selection().directory))
167170
const newSessionProject = createMemo(
168171
() =>
169172
selectedProject() ??
@@ -191,7 +194,7 @@ export function NewHome() {
191194
return language.t("home.sessions.search.placeholder")
192195
})
193196
const sessionLoad = useQuery(() => ({
194-
queryKey: ["home", "sessions", state.selection.server, ...projectDirectories()] as const,
197+
queryKey: ["home", "sessions", selection().server, ...projectDirectories()] as const,
195198
queryFn: async () => {
196199
await Promise.all(
197200
projectDirectories().map((directory) =>
@@ -257,10 +260,7 @@ export function NewHome() {
257260
})
258261

259262
function setSelection(next: HomeProjectSelection) {
260-
batch(() => {
261-
if (state.selection.server !== next.server) setState("selection", "server", next.server)
262-
if (state.selection.directory !== next.directory) setState("selection", "directory", next.directory)
263-
})
263+
layout.home.setSelection(next)
264264
}
265265

266266
function closeSearch() {
@@ -285,7 +285,7 @@ export function NewHome() {
285285

286286
createEffect(() => {
287287
const list = global.servers.list()
288-
if (list.some((conn) => ServerConnection.key(conn) === state.selection.server)) return
288+
if (list.some((conn) => ServerConnection.key(conn) === selection().server)) return
289289
const conn = list.find((conn) => ServerConnection.key(conn) === server.key) ?? list[0]
290290
if (conn) setSelection({ server: ServerConnection.key(conn) })
291291
})
@@ -310,7 +310,7 @@ export function NewHome() {
310310
.some((project) => project.worktree === directory)
311311
)
312312
return
313-
setSelection(toggleHomeProjectSelection(state.selection, key, directory))
313+
setSelection(toggleHomeProjectSelection(selection(), key, directory))
314314
}
315315

316316
function addProjects(conn: ServerConnection.Any, directories: string[]) {
@@ -418,15 +418,15 @@ export function NewHome() {
418418
<div class="mx-auto grid h-full w-full max-w-[1080px] grid-rows-[auto_minmax(0,1fr)_auto] gap-4 px-3 pb-3 lg:grid-cols-[280px_minmax(0,720px)] lg:grid-rows-1 lg:gap-8 lg:px-6 lg:pb-16">
419419
<HomeProjectColumn
420420
projects={projects()}
421-
selected={state.selection}
421+
selected={selection()}
422422
focusServer={focusServer}
423423
selectProject={selectProject}
424424
openNewSession={openProjectNewSession}
425425
chooseProject={(conn) => void chooseProject(conn)}
426426
editProject={editProject}
427427
closeProject={(conn, directory) => {
428428
const next = closeHomeProject(
429-
state.selection,
429+
selection(),
430430
ServerConnection.key(conn),
431431
global.ensureServerCtx(conn).projects,
432432
directory,
@@ -451,8 +451,8 @@ export function NewHome() {
451451
loading={sessionLoad.isLoading}
452452
results={searchResults()}
453453
showProjectName={!selectedProject()}
454-
server={state.selection.server}
455-
activeServer={state.selection.server === server.key}
454+
server={selection().server}
455+
activeServer={selection().server === server.key}
456456
noResultsLabel={language.t("home.sessions.search.noResults", { query: search() })}
457457
bindFocus={(focus) => {
458458
focusSessionSearch = focus
@@ -489,8 +489,8 @@ export function NewHome() {
489489
<HomeSessionRow
490490
record={record}
491491
showProjectName={!selectedProject()}
492-
server={state.selection.server}
493-
activeServer={state.selection.server === server.key}
492+
server={selection().server}
493+
activeServer={selection().server === server.key}
494494
openSession={openSession}
495495
archiveSession={archiveSession}
496496
/>

packages/app/src/pages/layout/helpers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getFilename } from "@opencode-ai/core/util/path"
22
import { type Session } from "@opencode-ai/sdk/v2/client"
33
import { pathKey } from "@/utils/path-key"
44
import type { ServerConnection } from "@/context/server"
5+
import type { HomeProjectSelection } from "@/context/layout"
56

67
type SessionStore = {
78
session?: Session[]
@@ -56,8 +57,6 @@ export const childSessionOnPath = (sessions: Session[] | undefined, rootID: stri
5657
export const displayName = (project: { name?: string; worktree: string }) =>
5758
project.name || getFilename(project.worktree) || project.worktree
5859

59-
export type HomeProjectSelection = { server: ServerConnection.Key; directory?: string }
60-
6160
export function toggleHomeProjectSelection(
6261
current: HomeProjectSelection | undefined,
6362
server: ServerConnection.Key,

0 commit comments

Comments
 (0)