Split into more components
This commit is contained in:
parent
704c6ed074
commit
0e97a288e1
11 changed files with 276 additions and 160 deletions
|
|
@ -9,10 +9,11 @@ import { MenuItem } from 'primereact/menuitem';
|
|||
import { TreeSelect } from 'primereact/treeselect';
|
||||
import TreeNode from 'primereact/treenode';
|
||||
import { Menu } from 'primereact/menu';
|
||||
import { getParentDir } from '../fs/filesystem';
|
||||
import { getParentDir, librariesFolder } from '../fs/filesystem';
|
||||
import { buildUrlForStateParams } from '../state/fragment-state';
|
||||
import { blankProjectState } from '../state/initial-state';
|
||||
import { ModelContext, FSContext } from './contexts';
|
||||
import FilePicker, { isFileWritable } from './FilePicker';
|
||||
|
||||
// import "primereact/resources/themes/lara-light-indigo/theme.css";
|
||||
// import "primereact/resources/primereact.min.css";
|
||||
|
|
@ -21,42 +22,45 @@ import { ModelContext, FSContext } from './contexts';
|
|||
let monacoInstance: Monaco
|
||||
loader.init().then(mi => monacoInstance = mi);
|
||||
|
||||
const isFileWritable = (path: string) => getParentDir(path) === '/home'
|
||||
// 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)) {
|
||||
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)));
|
||||
// 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;
|
||||
}
|
||||
// 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 EditorPanel({className, style}: {className?: string, style?: CSSProperties}) {
|
||||
|
||||
|
|
@ -67,7 +71,7 @@ export default function EditorPanel({className, style}: {className?: string, sty
|
|||
|
||||
const state = model.state;
|
||||
|
||||
const fs = useContext(FSContext);
|
||||
// const fs = useContext(FSContext);
|
||||
const [editor, setEditor] = useState(null as monaco.editor.IStandaloneCodeEditor | null)
|
||||
// const [modelFile, setModelFile] = useState(state.params.sourcePath);
|
||||
|
||||
|
|
@ -100,8 +104,6 @@ export default function EditorPanel({className, style}: {className?: string, sty
|
|||
setEditor(editor)
|
||||
}
|
||||
|
||||
const fsItems = fs && listFilesAsNodes(fs, '/home') || [];
|
||||
|
||||
return (
|
||||
<div className={`editor-panel ${className ?? ''}`} style={{
|
||||
// maxWidth: '5 0vw',
|
||||
|
|
@ -111,7 +113,6 @@ export default function EditorPanel({className, style}: {className?: string, sty
|
|||
// width: '100%', height: '100%',
|
||||
...(style ?? {})
|
||||
}}>
|
||||
{/* <BreadCrumb model={breadCrumbsItems} home={breadCrumbsHome}/> */}
|
||||
<div className='flex flex-row gap-2' style={{
|
||||
margin: '5px',
|
||||
}}>
|
||||
|
|
@ -214,73 +215,39 @@ export default function EditorPanel({className, style}: {className?: string, sty
|
|||
] as MenuItem[]} popup ref={menu} />
|
||||
<Button title="Editor menu" rounded text icon="pi pi-ellipsis-h" onClick={(e) => menu.current && menu.current.toggle(e)} />
|
||||
|
||||
<TreeSelect
|
||||
title='OpenSCAD Playground Files'
|
||||
value={state.params.sourcePath}
|
||||
onChange={(e) => model.openFile(String(e.value))}
|
||||
// dropdownIcon="pi pi-folder-open"
|
||||
filter
|
||||
<FilePicker
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
options={fsItems} />
|
||||
|
||||
}}/>
|
||||
</div>
|
||||
|
||||
{/* <SplitPane type="vertical"> */}
|
||||
{/* <div className='flex flex-column'> */}
|
||||
{/* <Splitter style={{
|
||||
// height: '300px'
|
||||
}} layout="vertical"> */}
|
||||
{/* <SplitterPanel className="flex flex-column align-items-center justify-content-center"
|
||||
style={{
|
||||
// width: '100%', height: '100%'
|
||||
}}> */}
|
||||
<div style={{
|
||||
position: 'relative',
|
||||
flex: 1
|
||||
}}>
|
||||
<Editor
|
||||
className="openscad-editor absolute-fill"
|
||||
defaultLanguage="openscad"
|
||||
path={state.params.sourcePath}
|
||||
value={state.params.source}
|
||||
onChange={s => model.source = s ?? ''}
|
||||
onMount={onMount} // TODO: This looks a bit silly, does it trigger a re-render??
|
||||
options={{
|
||||
...openscadEditorOptions,
|
||||
readOnly: !isFileWritable(state.params.sourcePath)
|
||||
}}
|
||||
// height="100%"
|
||||
// width="100%"
|
||||
// height="80vh"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
position: 'relative',
|
||||
flex: 1
|
||||
}}>
|
||||
<Editor
|
||||
className="openscad-editor absolute-fill"
|
||||
defaultLanguage="openscad"
|
||||
path={state.params.sourcePath}
|
||||
value={state.params.source}
|
||||
onChange={s => model.source = s ?? ''}
|
||||
onMount={onMount} // TODO: This looks a bit silly, does it trigger a re-render??
|
||||
options={{
|
||||
...openscadEditorOptions,
|
||||
readOnly: !isFileWritable(state.params.sourcePath)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* </SplitterPanel>
|
||||
<SplitterPanel className="flex flex-column align-items-center justify-content-center" style={{position: 'relative'}}> */}
|
||||
{/* <ScrollPanel style={{
|
||||
// width: '100%', height: '200px'
|
||||
}} className="custombar2"> */}
|
||||
<div style={{
|
||||
display: state.view.logs ? undefined : 'none',
|
||||
overflowY: 'scroll',
|
||||
height: 'calc(min(200px, 30vh))',
|
||||
// position: 'relative',
|
||||
// maxWidth: '100%',
|
||||
// maxWidth: '50vw',
|
||||
}}>
|
||||
<pre><code id="logs" style={{
|
||||
// maxWidth: '200px'
|
||||
}}>{state.lastCheckerRun?.logText ?? 'No log yet!'}</code></pre>
|
||||
</div>
|
||||
{/* </ScrollPanel> */}
|
||||
{/* <div className="logs-container">
|
||||
</div> */}
|
||||
{/* </SplitterPanel>
|
||||
</Splitter> */}
|
||||
{/* </SplitPane> */}
|
||||
{/* </div> */}
|
||||
<div style={{
|
||||
display: state.view.logs ? undefined : 'none',
|
||||
overflowY: 'scroll',
|
||||
height: 'calc(min(200px, 30vh))',
|
||||
}}>
|
||||
<pre><code id="logs" style={{
|
||||
}}>{state.lastCheckerRun?.logText ?? 'No log yet!'}</code></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
85
src/components/FilePicker.tsx
Normal file
85
src/components/FilePicker.tsx
Normal 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} />
|
||||
)
|
||||
}
|
||||
|
|
@ -9,9 +9,10 @@ import { ProgressBar } from 'primereact/progressbar';
|
|||
import { MenuItem } from 'primereact/menuitem';
|
||||
import { Badge } from 'primereact/badge';
|
||||
import { Menu } from 'primereact/menu';
|
||||
import { ToggleButton } from 'primereact/togglebutton';
|
||||
import { ConfirmDialog, confirmDialog } from 'primereact/confirmdialog';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import SettingsMenu from './SettingsMenu';
|
||||
import HelpMenu from './HelpMenu';
|
||||
|
||||
function downloadOutput(state: State) {
|
||||
if (!state.output) return;
|
||||
|
|
@ -46,11 +47,11 @@ function downloadOutput(state: State) {
|
|||
export default function Footer({style}: {style?: CSSProperties}) {
|
||||
const model = useContext(ModelContext);
|
||||
if (!model) throw new Error('No model');
|
||||
const state = model.state;
|
||||
|
||||
const menu = useRef<Menu>(null);
|
||||
const helpMenu = useRef<Menu>(null);
|
||||
const toast = useRef<Toast>(null);
|
||||
|
||||
const state = model.state;
|
||||
|
||||
const severityByMarkerSeverity = new Map<monaco.MarkerSeverity, 'danger' | 'warning' | 'info'>([
|
||||
[monaco.MarkerSeverity.Error, 'danger'],
|
||||
|
|
@ -147,49 +148,9 @@ export default function Footer({style}: {style?: CSSProperties}) {
|
|||
// </a>
|
||||
)}
|
||||
|
||||
<ToggleButton
|
||||
style={{
|
||||
// flex: 1,
|
||||
}}
|
||||
onIcon='pi pi-table'
|
||||
offIcon='pi pi-table'
|
||||
onLabel=''
|
||||
offLabel=''
|
||||
// onLabel='Multi'
|
||||
// offLabel='Single'
|
||||
title='Change between single and multiple layout'
|
||||
checked={state.view.layout.mode === 'multi'}
|
||||
onChange={e => model.changeLayout(e.value ? 'multi' : 'single')} />
|
||||
<SettingsMenu />
|
||||
|
||||
<Menu model={[
|
||||
{
|
||||
label: "openscad-playground",
|
||||
icon: 'pi pi-github',
|
||||
command: () => window.open('https://github.com/openscad/openscad-playground/tree/rewrite1', '_blank'),
|
||||
},
|
||||
{
|
||||
label: 'LICENSES',
|
||||
icon: 'pi pi-info-circle',
|
||||
command: () => window.open('https://github.com/openscad/openscad-playground/blob/rewrite1/LICENSE.md', '_blank'),
|
||||
},
|
||||
{
|
||||
label: 'OpenSCAD Docs',
|
||||
icon: 'pi pi-book',
|
||||
command: () => window.open('http://openscad.org/documentation.html', '_blank'),
|
||||
},
|
||||
{
|
||||
label: 'OpenSCAD Cheatsheet',
|
||||
icon: 'pi pi-palette',
|
||||
command: () => window.open('http://openscad.org/cheatsheet/', '_blank'),
|
||||
},
|
||||
{
|
||||
label: 'BOSL2 Cheatsheet',
|
||||
icon: 'pi pi-palette',
|
||||
command: () => window.open('https://github.com/revarbat/BOSL2/wiki/CheatSheet', '_blank'),
|
||||
},
|
||||
] as MenuItem[]} popup ref={menu} />
|
||||
<Button title="Help & Licenses" rounded icon="pi pi-question-circle" onClick={(e) => menu.current && menu.current.toggle(e)} />
|
||||
|
||||
<HelpMenu />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
|
|
|||
48
src/components/HelpMenu.tsx
Normal file
48
src/components/HelpMenu.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||
|
||||
import { useContext, useRef } from 'react';
|
||||
import { Button } from 'primereact/button';
|
||||
import { MenuItem } from 'primereact/menuitem';
|
||||
import { Menu } from 'primereact/menu';
|
||||
import { ModelContext } from './contexts';
|
||||
|
||||
export default function HelpMenu() {
|
||||
const menuRef = useRef<Menu>(null);
|
||||
return (
|
||||
<>
|
||||
<Menu model={[
|
||||
{
|
||||
label: "openscad-playground",
|
||||
icon: 'pi pi-github',
|
||||
url: 'https://github.com/openscad/openscad-playground/tree/rewrite1',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'LICENSES',
|
||||
icon: 'pi pi-info-circle',
|
||||
url: 'https://github.com/openscad/openscad-playground/blob/rewrite1/LICENSE.md',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'OpenSCAD Docs',
|
||||
icon: 'pi pi-book',
|
||||
url: 'http://openscad.org/documentation.html',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'OpenSCAD Cheatsheet',
|
||||
icon: 'pi pi-palette',
|
||||
url: 'http://openscad.org/cheatsheet/',
|
||||
target: '_blank'
|
||||
},
|
||||
{
|
||||
label: 'BOSL2 Cheatsheet',
|
||||
icon: 'pi pi-palette',
|
||||
url: 'https://github.com/revarbat/BOSL2/wiki/CheatSheet',
|
||||
target: '_blank'
|
||||
},
|
||||
] as MenuItem[]} popup ref={menuRef} />
|
||||
<Button title="Help & Licenses" rounded icon="pi pi-question-circle" onClick={(e) => menuRef.current && menuRef.current.toggle(e)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
45
src/components/SettingsMenu.tsx
Normal file
45
src/components/SettingsMenu.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||
|
||||
import { useContext, useRef } from 'react';
|
||||
import { Button } from 'primereact/button';
|
||||
import { MenuItem } from 'primereact/menuitem';
|
||||
import { Menu } from 'primereact/menu';
|
||||
import { ModelContext } from './contexts';
|
||||
|
||||
export default function SettingsMenu() {
|
||||
const model = useContext(ModelContext);
|
||||
if (!model) throw new Error('No model');
|
||||
const state = model.state;
|
||||
|
||||
const settingsMenu = useRef<Menu>(null);
|
||||
return (
|
||||
<>
|
||||
<Menu model={[
|
||||
{
|
||||
label: state.view.layout.mode === 'multi'
|
||||
? 'Switch to single panel mode'
|
||||
: "Switch to side-by-side mode",
|
||||
icon: 'pi pi-table',
|
||||
// disabled: true,
|
||||
command: () => model.changeLayout(state.view.layout.mode === 'multi' ? 'single' : 'multi'),
|
||||
},
|
||||
{
|
||||
separator: true
|
||||
},
|
||||
{
|
||||
label: state.view.showAxes ? 'Hide axes' : 'Show axes',
|
||||
icon: 'pi pi-box',
|
||||
// disabled: true,
|
||||
command: () => model.mutate(s => s.view.showAxes = !s.view.showAxes)
|
||||
},
|
||||
{
|
||||
label: state.view.showShadows ? 'Hide shadows' : 'Add shadows',
|
||||
icon: 'pi pi-box',
|
||||
// disabled: true,
|
||||
command: () => model.mutate(s => s.view.showShadows = !s.view.showShadows)
|
||||
},
|
||||
] as MenuItem[]} popup ref={settingsMenu} />
|
||||
<Button title="Settings menu" rounded text icon="pi pi-cog" onClick={(e) => settingsMenu.current && settingsMenu.current.toggle(e)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -26,9 +26,9 @@ export default function ViewerPanel({className, style}: {className?: string, sty
|
|||
// width: '100%'
|
||||
}}
|
||||
// ref={stlModelRef}
|
||||
showAxes={true}
|
||||
showAxes={state.view.showAxes}
|
||||
orbitControls
|
||||
shadows
|
||||
shadows={state.view.showShadows}
|
||||
modelProps={{
|
||||
color: '#f9d72c',
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export type OpenSCADInvocationResults = {
|
|||
elapsedMillis: number,
|
||||
}
|
||||
|
||||
export function spawnOpenSCAD({inputs, args, outputPaths}: OpenSCADInvocation): AbortablePromise<OpenSCADInvocationResults> {
|
||||
export function spawnOpenSCAD(invocation: OpenSCADInvocation): AbortablePromise<OpenSCADInvocationResults> {
|
||||
var worker: Worker | null;
|
||||
var rejection: (err: any) => void;
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ export function spawnOpenSCAD({inputs, args, outputPaths}: OpenSCADInvocation):
|
|||
resolve(e.data);
|
||||
terminate();
|
||||
}
|
||||
worker.postMessage({inputs, args, outputPaths})
|
||||
worker.postMessage(invocation)
|
||||
|
||||
return () => {
|
||||
// rejection({error: 'Terminated'});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import OpenSCAD from "../wasm/openscad.js";
|
||||
|
||||
import { createEditorFS, getBrowserFSLibrariesMounts, symlinkLibraries } from "../fs/filesystem";
|
||||
import { createEditorFS, getBrowserFSLibrariesMounts, librariesFolder, symlinkLibraries } from "../fs/filesystem";
|
||||
import { OpenSCADInvocation, OpenSCADInvocationResults } from "./openscad-runner";
|
||||
import { zipArchives } from "../fs/zip-archives";
|
||||
declare var BrowserFS: BrowserFSInterface
|
||||
|
|
@ -33,12 +33,14 @@ addEventListener('message', async (e) => {
|
|||
console.debug('stderr: ' + text);
|
||||
mergedOutputs.push({ stderr: text })
|
||||
},
|
||||
ENV: {
|
||||
OPENSCADPATH: '/home'
|
||||
}
|
||||
// ENV: {
|
||||
// OPENSCADPATH: '/home'
|
||||
// }
|
||||
});
|
||||
|
||||
const fs = await createEditorFS('/home');
|
||||
// const librariesFolder = '/home/.local/share/OpenSCAD/libraries'
|
||||
const fs = await createEditorFS();
|
||||
await symlinkLibraries(allArchiveNames, fs, librariesFolder, '/home');//'/home', '/home');
|
||||
|
||||
// https://github.com/emscripten-core/emscripten/issues/10061
|
||||
const BFS = new BrowserFS.EmscriptenFS(
|
||||
|
|
@ -49,7 +51,7 @@ addEventListener('message', async (e) => {
|
|||
}, instance.ERRNO_CODES ?? {});
|
||||
instance.FS.mount(BFS, {root: '/home'}, '/home');
|
||||
|
||||
// await symlinkLibraries(allArchiveNames, instance.FS, '/home/libraries', '/home');
|
||||
//await symlinkLibraries(allArchiveNames, instance.FS, '/home/libraries', '/home');
|
||||
|
||||
instance.FS.chdir('/home');
|
||||
|
||||
|
|
@ -65,7 +67,7 @@ addEventListener('message', async (e) => {
|
|||
}
|
||||
}
|
||||
|
||||
console.log('Calling main ', args)
|
||||
console.log('Invoking OpenSCAD from ', workingDir, args)
|
||||
const start = performance.now();
|
||||
const exitCode = instance.callMain(args);
|
||||
const end = performance.now();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ export interface State {
|
|||
} | ({
|
||||
mode: 'multi',
|
||||
} & { [K in MultiLayoutComponentId]: boolean })
|
||||
|
||||
showAxes?: boolean,
|
||||
showShadows?: boolean,
|
||||
}
|
||||
|
||||
lastCheckerRun?: {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ export function readStateFromFragment(): State | null {
|
|||
editor: validateBoolean(view?.layout['editor']),
|
||||
viewer: validateBoolean(view?.layout['viewer']),
|
||||
customizer: validateBoolean(view?.layout['customizer']),
|
||||
}
|
||||
},
|
||||
showAxes: validateBoolean(view?.layout?.showAxis),
|
||||
showShadows: validateBoolean(view?.layout?.showShadow),
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ export function createInitialState(fs: any, state: State | null) {
|
|||
}
|
||||
}
|
||||
|
||||
initialState.view.showAxes ??= true
|
||||
initialState.view.showShadows ??= true
|
||||
|
||||
fs.writeFile(initialState.params.sourcePath, initialState.params.source);
|
||||
if (initialState.params.sourcePath !== defaultSourcePath) {
|
||||
fs.writeFile(defaultSourcePath, defaultScad);
|
||||
|
|
|
|||
Loading…
Reference in a new issue