23
web/src/components/IdeConsole/IdeConsole.js
Normal file
23
web/src/components/IdeConsole/IdeConsole.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
|
import { IdeContext } from 'src/components/IdeToolbarNew'
|
||||||
|
|
||||||
|
const IdeConsole = () => {
|
||||||
|
const { state } = useContext(IdeContext)
|
||||||
|
return (
|
||||||
|
<div className="p-8 border-2 m-2">
|
||||||
|
<div className="pb-4">hi I'm console</div>
|
||||||
|
<div>
|
||||||
|
{state.consoleMessages?.map(({ type, message }, index) => (
|
||||||
|
<div
|
||||||
|
className={'font-mono ' + (type === 'error' ? 'text-red-500' : '')}
|
||||||
|
key={message + index}
|
||||||
|
>
|
||||||
|
-> {message}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IdeConsole
|
||||||
18
web/src/components/IdeContainer/IdeContainer.js
Normal file
18
web/src/components/IdeContainer/IdeContainer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import IdeEditor from 'src/components/IdeEditor'
|
||||||
|
import IdeViewer from 'src/components/IdeViewer'
|
||||||
|
import IdeConsole from 'src/components/IdeConsole'
|
||||||
|
|
||||||
|
const IdeContainer = () => {
|
||||||
|
return (
|
||||||
|
<div className="p-8 border-2">
|
||||||
|
<h2>hi I'm IDE container</h2>
|
||||||
|
<div className="flex">
|
||||||
|
<IdeEditor />
|
||||||
|
<IdeViewer />
|
||||||
|
<IdeConsole />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IdeContainer
|
||||||
29
web/src/components/IdeEditor/IdeEditor.js
Normal file
29
web/src/components/IdeEditor/IdeEditor.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
|
import { IdeContext } from 'src/components/IdeToolbarNew'
|
||||||
|
|
||||||
|
const IdeEditor = () => {
|
||||||
|
const { state, dispatch } = useContext(IdeContext)
|
||||||
|
return (
|
||||||
|
<div className="p-8 border-2 m-2">
|
||||||
|
<div>hi I'm editor</div>
|
||||||
|
<div className="pb-2">code:</div>
|
||||||
|
<input
|
||||||
|
value={state.code}
|
||||||
|
className="font-mono"
|
||||||
|
onChange={({ target }) =>
|
||||||
|
dispatch({ type: 'updateCode', payload: target.value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
dispatch({ type: 'render', payload: { code: state.code } })
|
||||||
|
}
|
||||||
|
className="m-2 border-2 shadow-md p-2 rounded"
|
||||||
|
>
|
||||||
|
Render plz
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IdeEditor
|
||||||
19
web/src/components/IdeToolbarNew/IdeToolbarNew.js
Normal file
19
web/src/components/IdeToolbarNew/IdeToolbarNew.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import IdeContainer from 'src/components/IdeContainer'
|
||||||
|
import { createContext } from 'react'
|
||||||
|
import { useIdeState } from 'src/helpers/hooks/useIdeState'
|
||||||
|
|
||||||
|
export const IdeContext = createContext()
|
||||||
|
|
||||||
|
const IdeToolbarNew = () => {
|
||||||
|
const [state, dispatch] = useIdeState()
|
||||||
|
return (
|
||||||
|
<IdeContext.Provider value={{ state, dispatch }}>
|
||||||
|
<div className="p-8 border-2">
|
||||||
|
<div>hi I'm the toolbar</div>
|
||||||
|
<IdeContainer />
|
||||||
|
</div>
|
||||||
|
</IdeContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IdeToolbarNew
|
||||||
18
web/src/components/IdeViewer/IdeViewer.js
Normal file
18
web/src/components/IdeViewer/IdeViewer.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
|
import { IdeContext } from 'src/components/IdeToolbarNew'
|
||||||
|
|
||||||
|
const IdeViewer = () => {
|
||||||
|
const { state } = useContext(IdeContext)
|
||||||
|
return (
|
||||||
|
<div className="p-8 border-2 m-2">
|
||||||
|
<div className="pb-4">hi I'm viewer</div>
|
||||||
|
<div>
|
||||||
|
I should be showing an{' '}
|
||||||
|
<span className="font-mono uppercase">{state.objectData?.type}</span>{' '}
|
||||||
|
right now
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IdeViewer
|
||||||
69
web/src/helpers/hooks/useIdeState.js
Normal file
69
web/src/helpers/hooks/useIdeState.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { useReducer } from 'react'
|
||||||
|
import { renderOpenScad } from 'src/helpers/openScadController'
|
||||||
|
|
||||||
|
export const useIdeState = () => {
|
||||||
|
const initialState = {
|
||||||
|
ideType: 'openscad',
|
||||||
|
consoleMessages: [
|
||||||
|
{ type: 'error', message: 'line 15 is being very naughty' },
|
||||||
|
{ type: 'message', message: '5 bodies produced' },
|
||||||
|
],
|
||||||
|
code: 'cubie(60);',
|
||||||
|
objectData: {
|
||||||
|
type: 'stl',
|
||||||
|
data: 'some binary',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const reducer = (state, { type, payload }) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'updateCode':
|
||||||
|
return { ...state, code: payload }
|
||||||
|
case 'healthyRender':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
objectData: {
|
||||||
|
type: payload.objectData?.type,
|
||||||
|
data: payload.objectData?.data,
|
||||||
|
},
|
||||||
|
consoleMessages: payload.message
|
||||||
|
? [...state.consoleMessages, payload.message]
|
||||||
|
: payload.message,
|
||||||
|
}
|
||||||
|
case 'errorRender':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
consoleMessages: payload.message
|
||||||
|
? [...state.consoleMessages, payload.message]
|
||||||
|
: payload.message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatchMiddleware(dispatch) {
|
||||||
|
return ({ type, payload }) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'render':
|
||||||
|
renderOpenScad({ code: payload.code })
|
||||||
|
.then(({ objectData, message }) =>
|
||||||
|
dispatch({
|
||||||
|
type: 'healthyRender',
|
||||||
|
payload: { objectData, message },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch(({ message }) =>
|
||||||
|
dispatch({
|
||||||
|
type: 'errorRender',
|
||||||
|
payload: { message },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
return dispatch({ type, payload })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [state, dispatch] = useReducer(reducer, initialState)
|
||||||
|
return [state, dispatchMiddleware(dispatch)]
|
||||||
|
}
|
||||||
26
web/src/helpers/openScadController.js
Normal file
26
web/src/helpers/openScadController.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export const renderOpenScad = async ({ code, settings }) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const shouldReject = Math.random() < 0.7
|
||||||
|
if (shouldReject) {
|
||||||
|
resolve({
|
||||||
|
objectData: {
|
||||||
|
type: Math.random() > 0.6 ? 'stl' : 'jpg',
|
||||||
|
data: 'some binary',
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: 'message',
|
||||||
|
message: `bodies rendered by: ${code}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject({
|
||||||
|
message: {
|
||||||
|
type: 'error',
|
||||||
|
message: 'unable to parse line: x',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 700)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -2,11 +2,13 @@ import MainLayout from 'src/layouts/MainLayout'
|
|||||||
import PartsCell from 'src/components/PartsCell'
|
import PartsCell from 'src/components/PartsCell'
|
||||||
import LandingSection from 'src/components/LandingSection'
|
import LandingSection from 'src/components/LandingSection'
|
||||||
import Seo from 'src/components/Seo/Seo'
|
import Seo from 'src/components/Seo/Seo'
|
||||||
|
import IdeToolbar from 'src/components/IdeToolbarNew'
|
||||||
|
|
||||||
const PartsPage = () => {
|
const PartsPage = () => {
|
||||||
return (
|
return (
|
||||||
<MainLayout>
|
<MainLayout>
|
||||||
<Seo title="Parts page" description="Cadhub parts page" lang="en-US" />
|
<Seo title="Parts page" description="Cadhub parts page" lang="en-US" />
|
||||||
|
<IdeToolbar />
|
||||||
<LandingSection />
|
<LandingSection />
|
||||||
<PartsCell shouldFilterPartsWithoutImage />
|
<PartsCell shouldFilterPartsWithoutImage />
|
||||||
</MainLayout>
|
</MainLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user