switch over to deep diffing for mutations
This commit is contained in:
parent
2e3a3e90de
commit
6064fd3b45
7 changed files with 228 additions and 88 deletions
|
@ -2,22 +2,27 @@ import { Accessor, Component, createContext, createSignal, For, JSX, Show, useCo
|
|||
import { AiFillFile, AiFillFolder, AiFillFolderOpen } from "solid-icons/ai";
|
||||
import { SelectionProvider, selectable } from "~/features/selectable";
|
||||
import css from "./filetree.module.css";
|
||||
import { debounce } from "~/utilities";
|
||||
|
||||
selectable;
|
||||
|
||||
export interface FileEntry {
|
||||
name: string;
|
||||
id: string;
|
||||
kind: 'file';
|
||||
meta: File;
|
||||
}
|
||||
|
||||
export interface FolderEntry {
|
||||
name: string;
|
||||
id: string;
|
||||
kind: 'folder';
|
||||
entries: Entry[];
|
||||
}
|
||||
|
||||
export type Entry = FileEntry | FolderEntry;
|
||||
|
||||
export const emptyFolder: FolderEntry = { name: '', kind: 'folder', entries: [] } as const;
|
||||
export const emptyFolder: FolderEntry = { name: '', id: '', kind: 'folder', entries: [] } as const;
|
||||
|
||||
export async function* walk(directory: FileSystemDirectoryHandle, filters: RegExp[] = [], depth = 0): AsyncGenerator<Entry, void, never> {
|
||||
if (depth === 10) {
|
||||
|
@ -25,16 +30,17 @@ export async function* walk(directory: FileSystemDirectoryHandle, filters: RegEx
|
|||
}
|
||||
|
||||
for await (const handle of directory.values()) {
|
||||
|
||||
if (filters.some(f => f.test(handle.name))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const id = await handle.getUniqueId();
|
||||
|
||||
if (handle.kind === 'file') {
|
||||
yield { name: handle.name, kind: 'file', meta: await handle.getFile() };
|
||||
yield { name: handle.name, id, kind: 'file', meta: await handle.getFile() };
|
||||
}
|
||||
else {
|
||||
yield { name: handle.name, kind: 'folder', entries: await Array.fromAsync(walk(handle, filters, depth + 1)) };
|
||||
yield { name: handle.name, id, kind: 'folder', entries: await Array.fromAsync(walk(handle, filters, depth + 1)) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,15 +54,8 @@ const TreeContext = createContext<TreeContextType>();
|
|||
export const Tree: Component<{ entries: Entry[], children: (file: Accessor<FileEntry>) => JSX.Element, open?: TreeContextType['open'] }> = (props) => {
|
||||
const [selection, setSelection] = createSignal<object[]>([]);
|
||||
|
||||
// createEffect(() => {
|
||||
// console.log(selection());
|
||||
// });
|
||||
|
||||
const context = {
|
||||
open: props.open ?? (() => { }),
|
||||
// open(file: File) {
|
||||
// console.log(`open ${file.name}`)
|
||||
// },
|
||||
};
|
||||
|
||||
return <SelectionProvider selection={setSelection}>
|
||||
|
@ -76,16 +75,16 @@ const _Tree: Component<{ entries: Entry[], children: (file: Accessor<FileEntry>)
|
|||
}</Show>
|
||||
|
||||
<Show when={entry.kind === 'file' ? entry : undefined}>{
|
||||
file => <span use:selectable={file()} ondblclick={() => context?.open(file().meta)}><AiFillFile /> {props.children(file)}</span>
|
||||
file => <span use:selectable={{ value: file() }} ondblclick={() => context?.open(file().meta)}><AiFillFile /> {props.children(file)}</span>
|
||||
}</Show>
|
||||
</>
|
||||
}</For>
|
||||
}
|
||||
|
||||
const Folder: Component<{ folder: FolderEntry, children: (file: Accessor<FileEntry>) => JSX.Element }> = (props) => {
|
||||
const [open, setOpen] = createSignal(false);
|
||||
const [open, setOpen] = createSignal(true);
|
||||
|
||||
return <details open={open()} ontoggle={() => setOpen(o => !o)}>
|
||||
return <details open={open()} ontoggle={() => debounce(() => setOpen(o => !o), 1)}>
|
||||
<summary><Show when={open()} fallback={<AiFillFolder />}><AiFillFolderOpen /></Show> {props.folder.name}</summary>
|
||||
<_Tree entries={props.folder.entries} children={props.children} />
|
||||
</details>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue