Ver Fonte

fix(app): startup homepage flash

Adam há 1 mês atrás
pai
commit
2d65db95af
1 ficheiros alterados com 56 adições e 23 exclusões
  1. 56 23
      packages/app/src/pages/layout.tsx

+ 56 - 23
packages/app/src/pages/layout.tsx

@@ -128,6 +128,7 @@ export default function Layout(props: ParentProps) {
 
 
   const [state, setState] = createStore({
   const [state, setState] = createStore({
     autoselect: !initialDirectory,
     autoselect: !initialDirectory,
+    routing: false,
     busyWorkspaces: {} as Record<string, boolean>,
     busyWorkspaces: {} as Record<string, boolean>,
     hoverSession: undefined as string | undefined,
     hoverSession: undefined as string | undefined,
     hoverProject: undefined as string | undefined,
     hoverProject: undefined as string | undefined,
@@ -140,6 +141,7 @@ export default function Layout(props: ParentProps) {
   })
   })
 
 
   const editor = createInlineEditorController()
   const editor = createInlineEditorController()
+  let token = 0
   const setBusy = (directory: string, value: boolean) => {
   const setBusy = (directory: string, value: boolean) => {
     const key = workspaceKey(directory)
     const key = workspaceKey(directory)
     if (value) {
     if (value) {
@@ -261,6 +263,7 @@ export default function Layout(props: ParentProps) {
 
 
   const autoselecting = createMemo(() => {
   const autoselecting = createMemo(() => {
     if (params.dir) return false
     if (params.dir) return false
+    if (state.routing) return true
     if (!state.autoselect) return false
     if (!state.autoselect) return false
     if (!pageReady()) return true
     if (!pageReady()) return true
     if (!layoutReady()) return true
     if (!layoutReady()) return true
@@ -270,12 +273,16 @@ export default function Layout(props: ParentProps) {
   })
   })
 
 
   createEffect(() => {
   createEffect(() => {
-    if (!state.autoselect) return
+    if (!state.autoselect && !state.routing) return
     const dir = params.dir
     const dir = params.dir
     if (!dir) return
     if (!dir) return
     const directory = decode64(dir)
     const directory = decode64(dir)
     if (!directory) return
     if (!directory) return
-    setState("autoselect", false)
+    token += 1
+    batch(() => {
+      setState("autoselect", false)
+      setState("routing", false)
+    })
   })
   })
 
 
   const editorOpen = editor.editorOpen
   const editorOpen = editor.editorOpen
@@ -561,23 +568,32 @@ export default function Layout(props: ParentProps) {
         if (!value.ready) return
         if (!value.ready) return
         if (!value.layoutReady) return
         if (!value.layoutReady) return
         if (!state.autoselect) return
         if (!state.autoselect) return
+        if (state.routing) return
         if (value.dir) return
         if (value.dir) return
 
 
         const last = server.projects.last()
         const last = server.projects.last()
+        const next =
+          value.list.length === 0
+            ? last
+            : (value.list.find((project) => project.worktree === last)?.worktree ?? value.list[0]?.worktree)
+        if (!next) return
 
 
-        if (value.list.length === 0) {
-          if (!last) return
+        const id = ++token
+        batch(() => {
           setState("autoselect", false)
           setState("autoselect", false)
-          openProject(last, false)
-          navigateToProject(last)
-          return
-        }
-
-        const next = value.list.find((project) => project.worktree === last) ?? value.list[0]
-        if (!next) return
-        setState("autoselect", false)
-        openProject(next.worktree, false)
-        navigateToProject(next.worktree)
+          setState("routing", true)
+        })
+        void navigateToProject(next, () => id === token && !params.dir).then(
+          (navigated) => {
+            if (id !== token) return
+            if (navigated) return
+            setState("routing", false)
+          },
+          () => {
+            if (id !== token) return
+            setState("routing", false)
+          },
+        )
       },
       },
     ),
     ),
   )
   )
@@ -1211,14 +1227,19 @@ export default function Layout(props: ParentProps) {
     return root
     return root
   }
   }
 
 
-  async function navigateToProject(directory: string | undefined) {
-    if (!directory) return
+  async function navigateToProject(directory: string | undefined, live = () => true) {
+    if (!directory || !live()) return false
     const root = projectRoot(directory)
     const root = projectRoot(directory)
-    server.projects.touch(root)
+    const touch = () => {
+      if (!live()) return false
+      layout.projects.open(root)
+      server.projects.touch(root)
+      return true
+    }
     const project = layout.projects.list().find((item) => item.worktree === root)
     const project = layout.projects.list().find((item) => item.worktree === root)
-    let dirs = project
-      ? effectiveWorkspaceOrder(root, [root, ...(project.sandboxes ?? [])], store.workspaceOrder[root])
-      : [root]
+    const sandboxes =
+      project?.sandboxes ?? globalSync.data.project.find((item) => item.worktree === root)?.sandboxes ?? []
+    let dirs = effectiveWorkspaceOrder(root, [root, ...sandboxes], store.workspaceOrder[root])
     const canOpen = (value: string | undefined) => {
     const canOpen = (value: string | undefined) => {
       if (!value) return false
       if (!value) return false
       return dirs.some((item) => workspaceKey(item) === workspaceKey(value))
       return dirs.some((item) => workspaceKey(item) === workspaceKey(value))
@@ -1229,13 +1250,16 @@ export default function Layout(props: ParentProps) {
         .list({ directory: root })
         .list({ directory: root })
         .then((x) => x.data ?? [])
         .then((x) => x.data ?? [])
         .catch(() => [] as string[])
         .catch(() => [] as string[])
+      if (!live()) return false
       dirs = effectiveWorkspaceOrder(root, [root, ...listed], store.workspaceOrder[root])
       dirs = effectiveWorkspaceOrder(root, [root, ...listed], store.workspaceOrder[root])
       return canOpen(target)
       return canOpen(target)
     }
     }
     const openSession = async (target: { directory: string; id: string }) => {
     const openSession = async (target: { directory: string; id: string }) => {
+      if (!live()) return false
       if (!canOpen(target.directory)) return false
       if (!canOpen(target.directory)) return false
       const [data] = globalSync.child(target.directory, { bootstrap: false })
       const [data] = globalSync.child(target.directory, { bootstrap: false })
       if (data.session.some((item) => item.id === target.id)) {
       if (data.session.some((item) => item.id === target.id)) {
+        if (!touch()) return false
         setStore("lastProjectSession", root, { directory: target.directory, id: target.id, at: Date.now() })
         setStore("lastProjectSession", root, { directory: target.directory, id: target.id, at: Date.now() })
         navigateWithSidebarReset(`/${base64Encode(target.directory)}/session/${target.id}`)
         navigateWithSidebarReset(`/${base64Encode(target.directory)}/session/${target.id}`)
         return true
         return true
@@ -1244,8 +1268,10 @@ export default function Layout(props: ParentProps) {
         .get({ sessionID: target.id })
         .get({ sessionID: target.id })
         .then((x) => x.data)
         .then((x) => x.data)
         .catch(() => undefined)
         .catch(() => undefined)
+      if (!live()) return false
       if (!resolved?.directory) return false
       if (!resolved?.directory) return false
       if (!canOpen(resolved.directory)) return false
       if (!canOpen(resolved.directory)) return false
+      if (!touch()) return false
       setStore("lastProjectSession", root, { directory: resolved.directory, id: resolved.id, at: Date.now() })
       setStore("lastProjectSession", root, { directory: resolved.directory, id: resolved.id, at: Date.now() })
       navigateWithSidebarReset(`/${base64Encode(resolved.directory)}/session/${resolved.id}`)
       navigateWithSidebarReset(`/${base64Encode(resolved.directory)}/session/${resolved.id}`)
       return true
       return true
@@ -1254,19 +1280,23 @@ export default function Layout(props: ParentProps) {
     const projectSession = store.lastProjectSession[root]
     const projectSession = store.lastProjectSession[root]
     if (projectSession?.id) {
     if (projectSession?.id) {
       await refreshDirs(projectSession.directory)
       await refreshDirs(projectSession.directory)
+      if (!live()) return false
       const opened = await openSession(projectSession)
       const opened = await openSession(projectSession)
-      if (opened) return
+      if (opened) return true
+      if (!live()) return false
       clearLastProjectSession(root)
       clearLastProjectSession(root)
     }
     }
 
 
+    if (!live()) return false
     const latest = latestRootSession(
     const latest = latestRootSession(
       dirs.map((item) => globalSync.child(item, { bootstrap: false })[0]),
       dirs.map((item) => globalSync.child(item, { bootstrap: false })[0]),
       Date.now(),
       Date.now(),
     )
     )
     if (latest && (await openSession(latest))) {
     if (latest && (await openSession(latest))) {
-      return
+      return true
     }
     }
 
 
+    if (!live()) return false
     const fetched = latestRootSession(
     const fetched = latestRootSession(
       await Promise.all(
       await Promise.all(
         dirs.map(async (item) => ({
         dirs.map(async (item) => ({
@@ -1279,11 +1309,14 @@ export default function Layout(props: ParentProps) {
       ),
       ),
       Date.now(),
       Date.now(),
     )
     )
+    if (!live()) return false
     if (fetched && (await openSession(fetched))) {
     if (fetched && (await openSession(fetched))) {
-      return
+      return true
     }
     }
 
 
+    if (!touch()) return false
     navigateWithSidebarReset(`/${base64Encode(root)}/session`)
     navigateWithSidebarReset(`/${base64Encode(root)}/session`)
+    return true
   }
   }
 
 
   function navigateToSession(session: Session | undefined) {
   function navigateToSession(session: Session | undefined) {