Naive persistence of state in URL fragment
This commit is contained in:
parent
e69c5c04d6
commit
a890b4ce45
6 changed files with 114 additions and 43 deletions
30
src/App.tsx
30
src/App.tsx
|
|
@ -1,10 +1,23 @@
|
||||||
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import SCADEditor from './Editor';
|
import {State} from './app-state'
|
||||||
|
import Editor from '@monaco-editor/react';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
import openscadEditorOptions from './language/openscad-editor-options';
|
||||||
|
import { writeStateInFragment } from './state';
|
||||||
|
|
||||||
|
export function App({initialState}: {initialState: State}) {
|
||||||
|
const [state, rawSetState] = useState(initialState);
|
||||||
|
|
||||||
|
const setState = (state: State) => {
|
||||||
|
rawSetState(state);
|
||||||
|
writeStateInFragment(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
const value = state.source.content;
|
||||||
|
const setValue = (content?: string) => setState({...state, source: {...state.source, content: content ?? ''}});
|
||||||
|
|
||||||
export function App() {
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header className="App-header">
|
<header className="App-header">
|
||||||
|
|
@ -20,9 +33,14 @@ export function App() {
|
||||||
>
|
>
|
||||||
Learn OpenSCAD
|
Learn OpenSCAD
|
||||||
</a>
|
</a>
|
||||||
<SCADEditor height="50vh" value="if (true) sphere(10); else cube();"/>
|
<Editor
|
||||||
|
className="openscad-editor"
|
||||||
</header>
|
defaultLanguage="openscad"
|
||||||
|
value={value}
|
||||||
|
onChange={setValue}
|
||||||
|
options={openscadEditorOptions}
|
||||||
|
height="50vh"/>
|
||||||
|
</header>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Editor from '@monaco-editor/react';
|
|
||||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
||||||
const options: monaco.editor.IStandaloneEditorConstructionOptions = {
|
|
||||||
lineNumbers: 'on',
|
|
||||||
automaticLayout: true,
|
|
||||||
scrollBeyondLastLine: false,
|
|
||||||
fontSize: 12,
|
|
||||||
language: 'openscad',
|
|
||||||
wordWrap: 'on',
|
|
||||||
wrappingStrategy: 'advanced',
|
|
||||||
suggest: {
|
|
||||||
// snippetsPreventQuickSuggestions: false,
|
|
||||||
showStatusBar: true,
|
|
||||||
preview: true,
|
|
||||||
},
|
|
||||||
codeLens: true,
|
|
||||||
function SCADEditor({value, ...props}: {value: string, height: string}) {
|
|
||||||
|
|
||||||
// let editor: monaco.editor.IStandaloneCodeEditor;
|
|
||||||
|
|
||||||
// function editorDidMount(e) {
|
|
||||||
// editor = e;
|
|
||||||
// console.log('editorDidMount', monaco.languages.getLanguages(), editor);
|
|
||||||
<Editor {...props} className="openscad-editor" defaultLanguage="openscad" value={value} options={options} />
|
|
||||||
// onMount={editorDidMount} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// export function createEditor() {
|
|
||||||
// monaco.editor.create(document.getElementById('openscad-editor') as any, options);
|
|
||||||
// }
|
|
||||||
|
|
||||||
export default SCADEditor;
|
|
||||||
14
src/app-state.ts
Normal file
14
src/app-state.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
source: {
|
||||||
|
content: string
|
||||||
|
},
|
||||||
|
output?: {
|
||||||
|
path: string,
|
||||||
|
timestamp: number,
|
||||||
|
sizeBytes: number,
|
||||||
|
formattedSize: string,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -6,6 +6,8 @@ import reportWebVitals from './reportWebVitals';
|
||||||
import { createEditorFS } from './filesystem';
|
import { createEditorFS } from './filesystem';
|
||||||
import { registerOpenSCADLanguage } from './language/openscad-register-language';
|
import { registerOpenSCADLanguage } from './language/openscad-register-language';
|
||||||
import { zipArchives } from './zip-archives';
|
import { zipArchives } from './zip-archives';
|
||||||
|
import {readStateFromFragment} from './state'
|
||||||
|
import { State } from './app-state';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
|
|
@ -13,12 +15,18 @@ import { zipArchives } from './zip-archives';
|
||||||
const fs = await createEditorFS(workingDir);
|
const fs = await createEditorFS(workingDir);
|
||||||
await registerOpenSCADLanguage(fs, workingDir, zipArchives);
|
await registerOpenSCADLanguage(fs, workingDir, zipArchives);
|
||||||
|
|
||||||
|
const initialState = readStateFromFragment() ?? {
|
||||||
|
source: {
|
||||||
|
content: 'cube(1);\ntranslate([0.5, 0.5, 0.5])\n\tcube(1);',
|
||||||
|
}
|
||||||
|
} as State;
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
);
|
);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App initialState={initialState} />
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
50
src/language/openscad-editor-options.ts
Normal file
50
src/language/openscad-editor-options.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Editor from '@monaco-editor/react';
|
||||||
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
lineNumbers: 'on',
|
||||||
|
automaticLayout: true,
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
fontSize: 12,
|
||||||
|
language: 'openscad',
|
||||||
|
tabSize: 2,
|
||||||
|
wordWrap: 'on',
|
||||||
|
wrappingStrategy: 'advanced',
|
||||||
|
suggest: {
|
||||||
|
// snippetsPreventQuickSuggestions: false,
|
||||||
|
localityBonus: true,
|
||||||
|
showStatusBar: true,
|
||||||
|
preview: true,
|
||||||
|
},
|
||||||
|
codeLens: true,
|
||||||
|
// language: 'javascript',
|
||||||
|
wordBasedSuggestions: false,
|
||||||
|
} as monaco.editor.IStandaloneEditorConstructionOptions;
|
||||||
|
|
||||||
|
// monaco.editor.IModelContentChangedEvent
|
||||||
|
|
||||||
|
// function SCADEditor({input, onInputChanged, ...props}: {input: string, onInputChanged: (value?: string) => void, height: string}) {
|
||||||
|
|
||||||
|
// // let editor: monaco.editor.IStandaloneCodeEditor;
|
||||||
|
|
||||||
|
// // function editorDidMount(e) {
|
||||||
|
// // editor = e;
|
||||||
|
// // console.log('editorDidMount', monaco.languages.getLanguages(), editor);
|
||||||
|
// // // editor.
|
||||||
|
// // editor.setModel(monaco.editor.createModel('sphere(123);', 'openscad'));
|
||||||
|
// // // editor.trigger('anything', 'editor.action.triggerSuggest', {});
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <Editor {...props}
|
||||||
|
// className="openscad-editor"
|
||||||
|
// defaultLanguage="openscad"
|
||||||
|
// value={n}
|
||||||
|
// onChange={setValue}
|
||||||
|
// options={options} />
|
||||||
|
// // onMount={editorDidMount} />
|
||||||
|
// );
|
||||||
|
// }
|
||||||
17
src/state.ts
Normal file
17
src/state.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Portions of this file are Copyright 2021 Google LLC, and licensed under GPL2+. See COPYING.
|
||||||
|
|
||||||
|
import { State } from "./app-state";
|
||||||
|
|
||||||
|
export function writeStateInFragment(state: State) {
|
||||||
|
window.location.hash = encodeURIComponent(JSON.stringify(state));
|
||||||
|
}
|
||||||
|
export function readStateFromFragment() {
|
||||||
|
if (window.location.hash.startsWith('#') && window.location.hash.length > 1) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(decodeURIComponent(window.location.hash.substring(1)));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue