Split into more components

This commit is contained in:
ochafik 2023-03-26 19:29:24 +01:00
commit 0e97a288e1
11 changed files with 276 additions and 160 deletions

View file

@ -0,0 +1,85 @@
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
import { CSSProperties, useContext } from 'react';
import { TreeSelect } from 'primereact/treeselect';
import TreeNode from 'primereact/treenode';
import { getParentDir, librariesFolder } from '../fs/filesystem';
import { ModelContext, FSContext } from './contexts';
export const isFileWritable = (path: string) => getParentDir(path) === '/home'
function listFilesAsNodes(fs: FS, path: string): TreeNode[] {
const files: [string, string][] = []
const dirs: [string, string][] = []
for (const name of fs.readdirSync(path)) {
if (name.startsWith('.')) {
continue;
}
const childPath = `${path}/${name}`;
const stat = fs.lstatSync(childPath);
const isDirectory = stat.isDirectory();
if (!isDirectory && !name.endsWith('.scad')) {
continue;
}
(isDirectory ? dirs : files).push([name, childPath]);
}
[files, dirs].forEach(arr => arr.sort(([a], [b]) => a.localeCompare(b)));
const nodes: TreeNode[] = []
for (const [arr, isDirectory] of [[files, false], [dirs, true]] as [[string, string][], boolean][]) {
for (const [name, path] of arr) {
const children = isDirectory ? listFilesAsNodes(fs, path) : undefined;
if (isDirectory && children!.length == 0) {
continue;
}
nodes.push({
// icon: path == '/home' ? 'pi-home' : ...
icon: isDirectory ? 'pi pi-folder' : isFileWritable(path) ? 'pi pi-file' : 'pi pi-lock',
label: name,
data: path,
key: path,
children,
selectable: !isDirectory // && (name == 'LICENSE' || name.endsWith('.scad') || name.endsWith('.scad')
});
}
}
return nodes;
}
export default function FilePicker({className, style}: {className?: string, style?: CSSProperties}) {
const model = useContext(ModelContext);
if (!model) throw new Error('No model');
const state = model.state;
const fs = useContext(FSContext);
const fsItems = fs && [
{
icon: 'pi pi-home',
label: 'User files',
key: '/home',
children: listFilesAsNodes(fs, '/home'),
selectable: false
},
{
icon: 'pi pi-database',
label: 'Builtin libraries',
key: librariesFolder,
children: listFilesAsNodes(fs, librariesFolder),
selectable: false
},
] || [];
return (
<TreeSelect
className={className}
title='OpenSCAD Playground Files'
value={state.params.sourcePath}
onChange={(e) => model.openFile(String(e.value))}
// dropdownIcon="pi pi-folder-open"
filter
style={style}
// style={{style}}
options={fsItems} />
)
}