Browse Source

fix(app): file tree not always loading

adamelmore 3 weeks ago
parent
commit
605e533558
2 changed files with 50 additions and 2 deletions
  1. 23 1
      packages/app/src/components/file-tree.tsx
  2. 27 1
      packages/app/src/pages/session.tsx

+ 23 - 1
packages/app/src/components/file-tree.tsx

@@ -8,6 +8,7 @@ import {
   createMemo,
   For,
   Match,
+  onCleanup,
   Show,
   splitProps,
   Switch,
@@ -123,7 +124,28 @@ export default function FileTree(props: {
 
   createEffect(() => {
     const path = props.path
-    untrack(() => void file.tree.list(path))
+    const state = { cancelled: false, timer: undefined as number | undefined }
+
+    const load = (attempt: number) => {
+      if (state.cancelled) return
+      if (file.tree.state(path)?.loaded) return
+
+      void untrack(() => file.tree.list(path)).finally(() => {
+        if (state.cancelled) return
+        if (file.tree.state(path)?.loaded) return
+        if (attempt >= 2) return
+
+        const wait = Math.min(2000, 250 * 2 ** attempt)
+        state.timer = window.setTimeout(() => load(attempt + 1), wait)
+      })
+    }
+
+    load(0)
+
+    onCleanup(() => {
+      state.cancelled = true
+      if (state.timer !== undefined) clearTimeout(state.timer)
+    })
   })
 
   const nodes = createMemo(() => {

+ 27 - 1
packages/app/src/pages/session.tsx

@@ -1256,7 +1256,33 @@ export default function Page() {
     if (!wants) return
     if (sync.data.session_diff[id] !== undefined) return
 
-    sync.session.diff(id)
+    const state = {
+      cancelled: false,
+      attempt: 0,
+      timer: undefined as number | undefined,
+    }
+
+    const load = () => {
+      if (state.cancelled) return
+      const pending = sync.session.diff(id)
+      if (!pending) return
+      pending.catch(() => {
+        if (state.cancelled) return
+        const attempt = state.attempt + 1
+        state.attempt = attempt
+        if (attempt > 5) return
+        if (state.timer !== undefined) clearTimeout(state.timer)
+        const wait = Math.min(10000, 250 * 2 ** (attempt - 1))
+        state.timer = window.setTimeout(load, wait)
+      })
+    }
+
+    load()
+
+    onCleanup(() => {
+      state.cancelled = true
+      if (state.timer !== undefined) clearTimeout(state.timer)
+    })
   })
 
   const autoScroll = createAutoScroll({