fix(app): file tree performance
This commit is contained in:
@@ -17,6 +17,11 @@ import {
|
||||
import { Dynamic } from "solid-js/web"
|
||||
import type { FileNode } from "@opencode-ai/sdk/v2"
|
||||
|
||||
type Filter = {
|
||||
files: Set<string>
|
||||
dirs: Set<string>
|
||||
}
|
||||
|
||||
export default function FileTree(props: {
|
||||
path: string
|
||||
class?: string
|
||||
@@ -27,26 +32,19 @@ export default function FileTree(props: {
|
||||
draggable?: boolean
|
||||
tooltip?: boolean
|
||||
onFileClick?: (file: FileNode) => void
|
||||
|
||||
_filter?: Filter
|
||||
_marks?: Set<string>
|
||||
_deeps?: Map<string, number>
|
||||
}) {
|
||||
const file = useFile()
|
||||
const level = props.level ?? 0
|
||||
const draggable = () => props.draggable ?? true
|
||||
const tooltip = () => props.tooltip ?? true
|
||||
|
||||
const maxOpen = (dir: string, lvl: number): number => {
|
||||
const expanded = file.tree.state(dir)?.expanded ?? false
|
||||
if (!expanded) return -1
|
||||
|
||||
const nodes = file.tree.children(dir)
|
||||
const child = nodes.reduce((max, node) => {
|
||||
if (node.type !== "directory") return max
|
||||
return Math.max(max, maxOpen(node.path, lvl + 1))
|
||||
}, -1)
|
||||
|
||||
return Math.max(lvl, child)
|
||||
}
|
||||
|
||||
const filter = createMemo(() => {
|
||||
if (props._filter) return props._filter
|
||||
|
||||
const allowed = props.allowed
|
||||
if (!allowed) return
|
||||
|
||||
@@ -66,11 +64,38 @@ export default function FileTree(props: {
|
||||
})
|
||||
|
||||
const marks = createMemo(() => {
|
||||
if (props._marks) return props._marks
|
||||
|
||||
const modified = props.modified
|
||||
if (!modified || modified.length === 0) return
|
||||
return new Set(modified)
|
||||
})
|
||||
|
||||
const deeps = createMemo(() => {
|
||||
if (props._deeps) return props._deeps
|
||||
|
||||
const out = new Map<string, number>()
|
||||
|
||||
const visit = (dir: string, lvl: number): number => {
|
||||
const expanded = file.tree.state(dir)?.expanded ?? false
|
||||
if (!expanded) return -1
|
||||
|
||||
const nodes = file.tree.children(dir)
|
||||
const max = nodes.reduce((max, node) => {
|
||||
if (node.type !== "directory") return max
|
||||
const open = file.tree.state(node.path)?.expanded ?? false
|
||||
if (!open) return max
|
||||
return Math.max(max, visit(node.path, lvl + 1))
|
||||
}, lvl)
|
||||
|
||||
out.set(dir, max)
|
||||
return max
|
||||
}
|
||||
|
||||
visit(props.path, level - 1)
|
||||
return out
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
const current = filter()
|
||||
if (!current) return
|
||||
@@ -84,7 +109,8 @@ export default function FileTree(props: {
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
void file.tree.list(props.path)
|
||||
const path = props.path
|
||||
untrack(() => void file.tree.list(path))
|
||||
})
|
||||
|
||||
const nodes = createMemo(() => {
|
||||
@@ -165,7 +191,7 @@ export default function FileTree(props: {
|
||||
<For each={nodes()}>
|
||||
{(node) => {
|
||||
const expanded = () => file.tree.state(node.path)?.expanded ?? false
|
||||
const deep = createMemo(() => (node.type === "directory" ? maxOpen(node.path, level) : -1))
|
||||
const deep = () => deeps().get(node.path) ?? -1
|
||||
const Wrapper = (p: ParentProps) => {
|
||||
if (!tooltip()) return p.children
|
||||
return (
|
||||
@@ -212,6 +238,9 @@ export default function FileTree(props: {
|
||||
draggable={props.draggable}
|
||||
tooltip={props.tooltip}
|
||||
onFileClick={props.onFileClick}
|
||||
_filter={filter()}
|
||||
_marks={marks()}
|
||||
_deeps={deeps()}
|
||||
/>
|
||||
</Collapsible.Content>
|
||||
</Collapsible>
|
||||
|
||||
Reference in New Issue
Block a user