wip(app): file tree mode
This commit is contained in:
@@ -2,7 +2,16 @@ import { useFile } from "@/context/file"
|
||||
import { Collapsible } from "@opencode-ai/ui/collapsible"
|
||||
import { FileIcon } from "@opencode-ai/ui/file-icon"
|
||||
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
||||
import { createEffect, For, Match, splitProps, Switch, type ComponentProps, type ParentProps } from "solid-js"
|
||||
import {
|
||||
createEffect,
|
||||
createMemo,
|
||||
For,
|
||||
Match,
|
||||
splitProps,
|
||||
Switch,
|
||||
type ComponentProps,
|
||||
type ParentProps,
|
||||
} from "solid-js"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
import type { FileNode } from "@opencode-ai/sdk/v2"
|
||||
|
||||
@@ -11,15 +20,45 @@ export default function FileTree(props: {
|
||||
class?: string
|
||||
nodeClass?: string
|
||||
level?: number
|
||||
allowed?: readonly string[]
|
||||
onFileClick?: (file: FileNode) => void
|
||||
}) {
|
||||
const file = useFile()
|
||||
const level = props.level ?? 0
|
||||
|
||||
const filter = createMemo(() => {
|
||||
const allowed = props.allowed
|
||||
if (!allowed) return
|
||||
|
||||
const files = new Set(allowed)
|
||||
const dirs = new Set<string>()
|
||||
|
||||
for (const item of allowed) {
|
||||
const parts = item.split("/")
|
||||
const parents = parts.slice(0, -1)
|
||||
for (const [idx] of parents.entries()) {
|
||||
const dir = parents.slice(0, idx + 1).join("/")
|
||||
if (dir) dirs.add(dir)
|
||||
}
|
||||
}
|
||||
|
||||
return { files, dirs }
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
void file.tree.list(props.path)
|
||||
})
|
||||
|
||||
const nodes = createMemo(() => {
|
||||
const nodes = file.tree.children(props.path)
|
||||
const current = filter()
|
||||
if (!current) return nodes
|
||||
return nodes.filter((node) => {
|
||||
if (node.type === "file") return current.files.has(node.path)
|
||||
return current.dirs.has(node.path)
|
||||
})
|
||||
})
|
||||
|
||||
const Node = (
|
||||
p: ParentProps &
|
||||
ComponentProps<"div"> &
|
||||
@@ -81,7 +120,7 @@ export default function FileTree(props: {
|
||||
|
||||
return (
|
||||
<div class={`flex flex-col ${props.class ?? ""}`}>
|
||||
<For each={file.tree.children(props.path)}>
|
||||
<For each={nodes()}>
|
||||
{(node) => {
|
||||
const expanded = () => file.tree.state(node.path)?.expanded ?? false
|
||||
return (
|
||||
@@ -102,7 +141,12 @@ export default function FileTree(props: {
|
||||
</Node>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Content>
|
||||
<FileTree path={node.path} level={level + 1} onFileClick={props.onFileClick} />
|
||||
<FileTree
|
||||
path={node.path}
|
||||
level={level + 1}
|
||||
allowed={props.allowed}
|
||||
onFileClick={props.onFileClick}
|
||||
/>
|
||||
</Collapsible.Content>
|
||||
</Collapsible>
|
||||
</Match>
|
||||
|
||||
Reference in New Issue
Block a user