app: fix workspace flicker when switching directories (#18207)

Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
This commit is contained in:
Brendan Allan
2026-03-19 19:29:14 +05:30
committed by GitHub
co-authored by Shoubhit Dash
parent cbf4b68fee
commit 84f60d97a0
11 changed files with 215 additions and 167 deletions
+50 -27
View File
@@ -543,13 +543,14 @@ export default function Layout(props: ParentProps) {
const currentProject = createMemo(() => {
const directory = currentDir()
if (!directory) return
const key = workspaceKey(directory)
const projects = layout.projects.list()
const sandbox = projects.find((p) => p.sandboxes?.includes(directory))
const sandbox = projects.find((p) => p.sandboxes?.some((item) => workspaceKey(item) === key))
if (sandbox) return sandbox
const direct = projects.find((p) => p.worktree === directory)
const direct = projects.find((p) => workspaceKey(p.worktree) === key)
if (direct) return direct
const [child] = globalSync.child(directory, { bootstrap: false })
@@ -630,7 +631,10 @@ export default function Layout(props: ParentProps) {
const projects = layout.projects.list()
for (const [directory, expanded] of Object.entries(store.workspaceExpanded)) {
if (!expanded) continue
const project = projects.find((item) => item.worktree === directory || item.sandboxes?.includes(directory))
const key = workspaceKey(directory)
const project = projects.find(
(item) => workspaceKey(item.worktree) === key || item.sandboxes?.some((sandbox) => workspaceKey(sandbox) === key),
)
if (!project) continue
if (project.vcs === "git" && layout.sidebar.workspaces(project.worktree)()) continue
setStore("workspaceExpanded", directory, false)
@@ -1155,13 +1159,16 @@ export default function Layout(props: ParentProps) {
}
function projectRoot(directory: string) {
const key = workspaceKey(directory)
const project = layout.projects
.list()
.find((item) => item.worktree === directory || item.sandboxes?.includes(directory))
.find(
(item) => workspaceKey(item.worktree) === key || item.sandboxes?.some((sandbox) => workspaceKey(sandbox) === key),
)
if (project) return project.worktree
const known = Object.entries(store.workspaceOrder).find(
([root, dirs]) => root === directory || dirs.includes(directory),
([root, dirs]) => workspaceKey(root) === key || dirs.some((item) => workspaceKey(item) === key),
)
if (known) return known[0]
@@ -1177,13 +1184,6 @@ export default function Layout(props: ParentProps) {
return currentProject()?.worktree ?? projectRoot(directory)
}
function touchProjectRoute() {
const root = currentProject()?.worktree
if (!root) return
if (server.projects.last() !== root) server.projects.touch(root)
return root
}
function rememberSessionRoute(directory: string, id: string, root = activeProjectRoot(directory)) {
setStore("lastProjectSession", root, { directory, id, at: Date.now() })
return root
@@ -1347,8 +1347,9 @@ export default function Layout(props: ParentProps) {
function closeProject(directory: string) {
const list = layout.projects.list()
const index = list.findIndex((x) => x.worktree === directory)
const active = currentProject()?.worktree === directory
const key = workspaceKey(directory)
const index = list.findIndex((x) => workspaceKey(x.worktree) === key)
const active = workspaceKey(currentProject()?.worktree ?? "") === key
if (index === -1) return
const next = list[index + 1]
@@ -1683,38 +1684,55 @@ export default function Layout(props: ParentProps) {
const activeRoute = {
session: "",
sessionProject: "",
directory: "",
}
createEffect(
on(
() => [pageReady(), params.dir, params.id, currentProject()?.worktree] as const,
([ready, dir, id]) => {
if (!ready || !dir) {
() => {
const dir = params.dir
const directory = dir ? decode64(dir) : undefined
const resolved = directory ? globalSync.child(directory, { bootstrap: false })[0].path.directory : ""
return [pageReady(), dir, params.id, currentProject()?.worktree, directory, resolved] as const
},
([ready, dir, id, root, directory, resolved]) => {
if (!ready || !dir || !directory) {
activeRoute.session = ""
activeRoute.sessionProject = ""
activeRoute.directory = ""
return
}
const directory = decode64(dir)
if (!directory) return
const root = touchProjectRoute() ?? activeProjectRoot(directory)
if (!id) {
activeRoute.session = ""
activeRoute.sessionProject = ""
activeRoute.directory = ""
return
}
const next = resolved || directory
const session = `${dir}/${id}`
if (session !== activeRoute.session) {
if (!root) {
activeRoute.session = session
activeRoute.sessionProject = syncSessionRoute(directory, id, root)
activeRoute.directory = next
activeRoute.sessionProject = ""
return
}
if (server.projects.last() !== root) server.projects.touch(root)
const changed = session !== activeRoute.session || next !== activeRoute.directory
if (changed) {
activeRoute.session = session
activeRoute.directory = next
activeRoute.sessionProject = syncSessionRoute(next, id, root)
return
}
if (root === activeRoute.sessionProject) return
activeRoute.sessionProject = rememberSessionRoute(directory, id, root)
activeRoute.directory = next
activeRoute.sessionProject = rememberSessionRoute(next, id, root)
},
),
)
@@ -1778,8 +1796,13 @@ export default function Layout(props: ParentProps) {
const local = project.worktree
const dirs = [local, ...(project.sandboxes ?? [])]
const active = currentProject()
const directory = active?.worktree === project.worktree ? currentDir() : undefined
const extra = directory && directory !== local && !dirs.includes(directory) ? directory : undefined
const directory = workspaceKey(active?.worktree ?? "") === workspaceKey(project.worktree) ? currentDir() : undefined
const extra =
directory &&
workspaceKey(directory) !== workspaceKey(local) &&
!dirs.some((item) => workspaceKey(item) === workspaceKey(directory))
? directory
: undefined
const pending = extra ? WorktreeState.get(extra)?.status === "pending" : false
const ordered = effectiveWorkspaceOrder(local, dirs, store.workspaceOrder[project.worktree])