fix(desktop): handle moved projects and deleted paths
This commit is contained in:
parent
4b948c5d74
commit
c9e1aedd42
6 changed files with 176 additions and 9 deletions
|
|
@ -40,6 +40,7 @@ beforeAll(async () => {
|
|||
describe("file tree fetch discipline", () => {
|
||||
test("root lists on mount unless already loaded or loading", () => {
|
||||
expect(shouldListRoot({ level: 0 })).toBe(true)
|
||||
expect(shouldListRoot({ level: 0, filtered: true })).toBe(false)
|
||||
expect(shouldListRoot({ level: 0, dir: { loaded: true } })).toBe(false)
|
||||
expect(shouldListRoot({ level: 0, dir: { loading: true } })).toBe(false)
|
||||
expect(shouldListRoot({ level: 1 })).toBe(false)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,12 @@ type Filter = {
|
|||
dirs: Set<string>
|
||||
}
|
||||
|
||||
export function shouldListRoot(input: { level: number; dir?: { loaded?: boolean; loading?: boolean } }) {
|
||||
export function shouldListRoot(input: {
|
||||
level: number
|
||||
filtered?: boolean
|
||||
dir?: { loaded?: boolean; loading?: boolean }
|
||||
}) {
|
||||
if (input.filtered) return false
|
||||
if (input.level !== 0) return false
|
||||
if (input.dir?.loaded) return false
|
||||
if (input.dir?.loading) return false
|
||||
|
|
@ -309,7 +314,7 @@ export default function FileTree(props: {
|
|||
filter: current,
|
||||
expanded: (dir) => untrack(() => file.tree.state(dir)?.expanded) ?? false,
|
||||
})
|
||||
for (const dir of dirs) file.tree.expand(dir)
|
||||
for (const dir of dirs) file.tree.expand(dir, { load: false })
|
||||
})
|
||||
|
||||
createEffect(
|
||||
|
|
@ -317,7 +322,7 @@ export default function FileTree(props: {
|
|||
() => props.path,
|
||||
(path) => {
|
||||
const dir = untrack(() => file.tree.state(path))
|
||||
if (!shouldListRoot({ level, dir })) return
|
||||
if (!shouldListRoot({ level, filtered: !!filter(), dir })) return
|
||||
void file.tree.list(path)
|
||||
},
|
||||
{ defer: false },
|
||||
|
|
@ -401,7 +406,9 @@ export default function FileTree(props: {
|
|||
data-scope="filetree"
|
||||
forceMount={false}
|
||||
open={expanded()}
|
||||
onOpenChange={(open) => (open ? file.tree.expand(node.path) : file.tree.collapse(node.path))}
|
||||
onOpenChange={(open) =>
|
||||
open ? file.tree.expand(node.path, { load: !filter() }) : file.tree.collapse(node.path)
|
||||
}
|
||||
>
|
||||
<Collapsible.Trigger>
|
||||
<FileTreeNode
|
||||
|
|
|
|||
28
packages/app/src/context/file/tree-store.test.ts
Normal file
28
packages/app/src/context/file/tree-store.test.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { createRoot } from "solid-js"
|
||||
import { createFileTreeStore } from "./tree-store"
|
||||
|
||||
describe("file tree store", () => {
|
||||
test("expands synthetic directories without listing them", () => {
|
||||
const listed: string[] = []
|
||||
const value = createRoot((dispose) => ({
|
||||
dispose,
|
||||
tree: createFileTreeStore({
|
||||
scope: () => "/project",
|
||||
normalizeDir: (input) => input,
|
||||
list: (input) => {
|
||||
listed.push(input)
|
||||
return Promise.resolve([])
|
||||
},
|
||||
onError: () => undefined,
|
||||
}),
|
||||
}))
|
||||
|
||||
value.tree.expandDir("deleted/parent", { load: false })
|
||||
|
||||
expect(value.tree.dirState("deleted/parent")?.expanded).toBe(true)
|
||||
expect(listed).toEqual([])
|
||||
|
||||
value.dispose()
|
||||
})
|
||||
})
|
||||
|
|
@ -127,10 +127,11 @@ export function createFileTreeStore(options: TreeStoreOptions) {
|
|||
return promise
|
||||
}
|
||||
|
||||
const expandDir = (input: string) => {
|
||||
const expandDir = (input: string, opts?: { load?: boolean }) => {
|
||||
const dir = options.normalizeDir(input)
|
||||
ensureDir(dir)
|
||||
setTree("dir", dir, "expanded", true)
|
||||
if (opts?.load === false) return
|
||||
void listDir(dir)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue