From bf2f89062d399da54b35d816e00a5c64fdb96333 Mon Sep 17 00:00:00 2001 From: Lambda Date: Wed, 22 Apr 2026 19:05:15 +0800 Subject: [PATCH] fix(desktop): preserve last-opened workspace on app start (MUL-1269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The workspace query defaults `data` to `[]` before the first fetch, so the bootstrap effect ran with an empty valid-slug set, wiped the persisted `activeWorkspaceSlug`, then fell back to `workspaces[0]` once the real list arrived — dropping the user on the default workspace on every launch. Gate the effect on `workspaceListFetched` so validation runs only against the real list, and re-read the store after `validateWorkspaceSlugs` to avoid acting on a stale snapshot. --- apps/desktop/src/renderer/src/App.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index 7e43ee21a..5dfbf2782 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -123,15 +123,21 @@ function AppContent() { // warning because `switchWorkspace` is a Zustand setState that the // TabBar is subscribed to. useLayoutEffect flushes both renders before // the user sees anything, so there's no visible flicker. + // + // Gate on `workspaceListFetched`: useQuery defaults `data` to `[]` before + // the first fetch, so without this guard we'd run validation against an + // empty slug set, wipe the persisted `activeWorkspaceSlug`, then fall + // back to `workspaces[0]` once the real list arrives — losing the user's + // last-opened workspace on every app start. useLayoutEffect(() => { - if (!workspaces) return; + if (!workspaceListFetched) return; const validSlugs = new Set(workspaces.map((w) => w.slug)); - const tabStore = useTabStore.getState(); - tabStore.validateWorkspaceSlugs(validSlugs); - if (!tabStore.activeWorkspaceSlug && workspaces.length > 0) { - tabStore.switchWorkspace(workspaces[0].slug); + useTabStore.getState().validateWorkspaceSlugs(validSlugs); + const { activeWorkspaceSlug, switchWorkspace } = useTabStore.getState(); + if (!activeWorkspaceSlug && workspaces.length > 0) { + switchWorkspace(workspaces[0].slug); } - }, [workspaces]); + }, [workspaces, workspaceListFetched]); // null = undecided (pre-login or list hasn't settled yet) // true = session started with zero workspaces; next transition to >=1 triggers restart