Front end changes for cadquery

Basic changes to get the proof of concept working. Lots of attention
was given to the store/reducer to solve existing problems with async
code and stale closures, it seems even today how to handle this with
use reducer is not quiet settle, I guess because once an app reaches
a certain level of maturity everyone grabs an off the shelf solution
to state management. I ended up implementing thunks because they are
really rather simple. Interesting thread about it all here:
https://gist.github.com/astoilkov/013c513e33fe95fa8846348038d8fe42#gistcomment-3377800

I also move some of settings that were persisted in the openScad
controller into the data store as I ulimately thing what I was doing
in that file was very confusing, with the fact that it had to be
called multiple times with different information before it would be able
to render something properly.
This commit is contained in:
Kurt Hutten
2021-04-18 12:28:23 +10:00
parent 1a702ddae1
commit 2153e5b1bf
9 changed files with 295 additions and 162 deletions

View File

@@ -2,10 +2,15 @@ import { useContext, useEffect, Suspense, lazy } from 'react'
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
import { IdeContext } from 'src/components/IdeToolbarNew'
import { codeStorageKey } from 'src/helpers/hooks/useIdeState'
import { requestRender } from 'src/helpers/hooks/useIdeState'
const Editor = lazy(() => import('@monaco-editor/react'))
const IdeEditor = () => {
const { state, dispatch } = useContext(IdeContext)
const { state, thunkDispatch } = useContext(IdeContext)
const ideTypeToLanguageMap = {
cadQuery: 'python',
openScad: 'cpp',
}
const scriptKey = 'encoded_script'
useEffect(() => {
@@ -17,7 +22,7 @@ const IdeEditor = () => {
const [key, scriptBase64] = hash.slice(1).split('=')
if (key === scriptKey) {
const script = atob(scriptBase64)
dispatch({ type: 'updateCode', payload: script })
thunkDispatch({ type: 'updateCode', payload: script })
}
}, [])
useEffect(() => {
@@ -27,25 +32,38 @@ const IdeEditor = () => {
}, [state.code])
function handleCodeChange(value, _event) {
dispatch({ type: 'updateCode', payload: value })
thunkDispatch({ type: 'updateCode', payload: value })
}
function handleSaveHotkey(event) {
//ctrl|meta + s is very intuitive for most devs
const { key, ctrlKey, metaKey } = event
if (key === 's' && (ctrlKey || metaKey)) {
event.preventDefault()
dispatch({ type: 'render', payload: { code: state.code } })
thunkDispatch((dispatch, getState) => {
const state = getState()
dispatch({ type: 'setLoading' })
requestRender({
state,
dispatch,
code: state.code,
viewerSize: state.viewerSize,
camera: state.camera,
})
})
localStorage.setItem(codeStorageKey, state.code)
}
}
return (
<div className="h-full" onKeyDown={handleSaveHotkey}>
<div // eslint-disable-line jsx-a11y/no-static-element-interactions
className="h-full"
onKeyDown={handleSaveHotkey}
>
<Suspense fallback={<div>. . . loading</div>}>
<Editor
defaultValue={state.code}
// TODO #247 cpp seems better than js for the time being
defaultLanguage="cpp"
defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}
onChange={handleCodeChange}
/>
</Suspense>