summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/file-tree.tsx59
1 files changed, 44 insertions, 15 deletions
diff --git a/packages/app/src/components/file-tree.tsx b/packages/app/src/components/file-tree.tsx
index b7f8316d0..64988af53 100644
--- a/packages/app/src/components/file-tree.tsx
+++ b/packages/app/src/components/file-tree.tsx
@@ -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>