Files
cadhub/web/src/helpers/hooks/useIdeState.js
2021-03-14 17:41:29 +11:00

122 lines
3.1 KiB
JavaScript

import { useReducer } from 'react'
import { cadPackages } from 'src/helpers/cadPackages'
const donutInitCode = `
color(c="DarkGoldenrod")rotate_extrude()translate([20,0])circle(d=30);
donut();
module donut() {
for(i=[1:360]){
rotate(i*13.751)stick(20,i*1.351);
}
}
module stick(basewid, angl){
translate([basewid,0,0])rotate([angl,angl,angl*2])color(c="hotpink")hull(){
sphere(7);
translate([0,0,10])sphere(9);
}
}`
export const useIdeState = () => {
const initialState = {
ideType: 'openScad',
consoleMessages: [{ type: 'message', message: 'Initialising OpenSCAD' }],
code: donutInitCode,
objectData: {
type: 'stl',
data: 'some binary',
},
layout: {
direction: 'row',
first: 'Editor',
second: {
direction: 'column',
first: 'Viewer',
second: 'Console',
splitPercentage: 70,
},
},
isLoading: false,
}
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,
isLoading: false,
}
case 'errorRender':
return {
...state,
consoleMessages: payload.message
? [...state.consoleMessages, payload.message]
: payload.message,
isLoading: false,
}
case 'setIdeType':
return {
...state,
ideType: payload.message,
}
case 'setLayout':
return {
...state,
layout: payload.message,
}
case 'setLoading':
return {
...state,
isLoading: true,
}
default:
return state
}
}
function dispatchMiddleware(dispatch, state) {
return ({ type, payload }) => {
switch (type) {
case 'render':
cadPackages[state.ideType]
.render({
code: payload.code,
settings: {
camera: payload.camera,
viewerSize: payload.viewerSize,
},
})
.then(({ objectData, message, status }) => {
if (status === 'insufficient-preview-info') return
if (status === 'error') {
dispatch({
type: 'errorRender',
payload: { message },
})
} else {
dispatch({
type: 'healthyRender',
payload: { objectData, message },
})
}
})
dispatch({ type: 'setLoading' })
break
default:
return dispatch({ type, payload })
}
}
}
const [state, dispatch] = useReducer(reducer, initialState)
return [state, dispatchMiddleware(dispatch, state)]
}