Init multiple types of cadPackages
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const express = require('express')
|
||||
var cors = require('cors')
|
||||
const axios = require('axios')
|
||||
const { restart } = require('nodemon')
|
||||
const app = express()
|
||||
const port = 8080
|
||||
app.use(express.json())
|
||||
@@ -10,19 +11,29 @@ const invocationURL = (port) =>
|
||||
`http://localhost:${port}/2015-03-31/functions/function/invocations`
|
||||
|
||||
app.post('/openscad/preview', async (req, res) => {
|
||||
const { data } = await axios.post(invocationURL(5052), {
|
||||
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
|
||||
})
|
||||
res.status(data.statusCode)
|
||||
res.send(data.body)
|
||||
try {
|
||||
const { data } = await axios.post(invocationURL(5052), {
|
||||
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
|
||||
})
|
||||
res.status(data.statusCode)
|
||||
res.send(data.body)
|
||||
} catch (e) {
|
||||
res.status(500)
|
||||
res.send()
|
||||
}
|
||||
})
|
||||
app.post('/cadquery/stl', async (req, res) => {
|
||||
console.log('making post request to 5060')
|
||||
const { data } = await axios.post(invocationURL(5060), {
|
||||
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
|
||||
})
|
||||
res.status(data.statusCode)
|
||||
res.send(data.body)
|
||||
try {
|
||||
const { data } = await axios.post(invocationURL(5060), {
|
||||
body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
|
||||
})
|
||||
res.status(data.statusCode)
|
||||
res.send(data.body)
|
||||
} catch (e) {
|
||||
res.status(500)
|
||||
res.send()
|
||||
}
|
||||
})
|
||||
|
||||
app.listen(port, () => {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.0.0",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@monaco-editor/react": "^4.0.11",
|
||||
"@redwoodjs/auth": "^0.30.1",
|
||||
|
||||
@@ -35,7 +35,7 @@ const Routes = () => {
|
||||
)
|
||||
return (
|
||||
<Router>
|
||||
<Route path="/dev-ide" page={DevIdePage} name="devIde" />
|
||||
<Route path="/dev-ide/{cadPackage}" page={DevIdePage} name="devIde" />
|
||||
<Route path="/policies/privacy-policy" page={PrivacyPolicyPage} name="privacyPolicy" />
|
||||
<Route path="/policies/code-of-conduct" page={CodeOfConductPage} name="codeOfConduct" />
|
||||
<Route path="/account-recovery/update-password" page={UpdatePasswordPage} name="updatePassword" />
|
||||
|
||||
@@ -12,25 +12,6 @@ const IdeEditor = () => {
|
||||
openScad: 'cpp',
|
||||
}
|
||||
|
||||
const scriptKey = 'encoded_script'
|
||||
useEffect(() => {
|
||||
// load code from hash if it's there
|
||||
let hash
|
||||
if (isBrowser) {
|
||||
hash = window.location.hash
|
||||
}
|
||||
const [key, scriptBase64] = hash.slice(1).split('=')
|
||||
if (key === scriptKey) {
|
||||
const script = atob(scriptBase64)
|
||||
thunkDispatch({ type: 'updateCode', payload: script })
|
||||
}
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
if (isBrowser) {
|
||||
window.location.hash = ''
|
||||
}
|
||||
}, [state.code])
|
||||
|
||||
function handleCodeChange(value, _event) {
|
||||
thunkDispatch({ type: 'updateCode', payload: value })
|
||||
}
|
||||
@@ -61,6 +42,7 @@ const IdeEditor = () => {
|
||||
<Suspense fallback={<div>. . . loading</div>}>
|
||||
<Editor
|
||||
defaultValue={state.code}
|
||||
value={state.code}
|
||||
// TODO #247 cpp seems better than js for the time being
|
||||
defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
||||
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext } from 'react'
|
||||
import { createContext, useEffect } from 'react'
|
||||
import IdeContainer from 'src/components/IdeContainer'
|
||||
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
||||
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
|
||||
@@ -6,11 +6,27 @@ import { copyTextToClipboard } from 'src/helpers/clipboard'
|
||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||
|
||||
export const IdeContext = createContext()
|
||||
const IdeToolbarNew = () => {
|
||||
const IdeToolbarNew = ({ cadPackage }) => {
|
||||
const [state, thunkDispatch] = useIdeState()
|
||||
function setIdeType(ide) {
|
||||
thunkDispatch({ type: 'setIdeType', payload: { message: ide } })
|
||||
}
|
||||
const scriptKey = 'encoded_script'
|
||||
useEffect(() => {
|
||||
thunkDispatch({
|
||||
type: 'initIde',
|
||||
payload: { cadPackage },
|
||||
})
|
||||
// load code from hash if it's there
|
||||
let hash
|
||||
if (isBrowser) {
|
||||
hash = window.location.hash
|
||||
}
|
||||
const [key, scriptBase64] = hash.slice(1).split('=')
|
||||
if (key === scriptKey) {
|
||||
const script = atob(scriptBase64)
|
||||
thunkDispatch({ type: 'updateCode', payload: script })
|
||||
}
|
||||
window.location.hash = ''
|
||||
setTimeout(() => handleRender()) // definitely a little hacky, timeout with no delay is just to push it into the next event loop.
|
||||
}, [cadPackage])
|
||||
function handleRender() {
|
||||
thunkDispatch((dispatch, getState) => {
|
||||
const state = getState()
|
||||
@@ -37,14 +53,6 @@ const IdeToolbarNew = () => {
|
||||
<IdeContext.Provider value={{ state, thunkDispatch: thunkDispatch }}>
|
||||
<div className="h-full flex flex-col">
|
||||
<nav className="flex">
|
||||
<button
|
||||
onClick={() =>
|
||||
setIdeType(state.ideType === 'openScad' ? 'cadQuery' : 'openScad')
|
||||
}
|
||||
className="p-2 br-2 border-2 m-2 bg-blue-200"
|
||||
>
|
||||
Switch to {state.ideType === 'openScad' ? 'CadQuery' : 'OpenSCAD'}
|
||||
</button>
|
||||
<button onClick={handleRender} className="p-2 br-2 border-2 m-2">
|
||||
Render
|
||||
</button>
|
||||
|
||||
48
web/src/components/NavPlusButton/NavPlusButton.tsx
Normal file
48
web/src/components/NavPlusButton/NavPlusButton.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import Svg from 'src/components/Svg/Svg'
|
||||
import { Popover } from '@headlessui/react'
|
||||
|
||||
const NavPlusButton: React.FC = () => {
|
||||
return (
|
||||
<Popover className="relative outline-none w-full h-full">
|
||||
<Popover.Button className="h-full w-full outline-none">
|
||||
<Svg name="plus" className="text-indigo-300" />
|
||||
</Popover.Button>
|
||||
|
||||
<Popover.Panel className="absolute z-10">
|
||||
<ul className="bg-gray-200 mt-4 rounded shadow-md overflow-hidden">
|
||||
{[
|
||||
{
|
||||
name: 'OpenSCAD',
|
||||
sub: 'beta',
|
||||
ideType: 'openScad',
|
||||
},
|
||||
{ name: 'CadQuery', sub: 'beta', ideType: 'cadQuery' },
|
||||
{
|
||||
name: 'CascadeStudio',
|
||||
sub: 'soon to be deprecated',
|
||||
},
|
||||
].map(({ name, sub, ideType }) => (
|
||||
<li
|
||||
key={name}
|
||||
className="px-4 py-2 hover:bg-gray-400 text-gray-800"
|
||||
>
|
||||
<Link
|
||||
to={
|
||||
name === 'CascadeStudio'
|
||||
? routes.draftPart()
|
||||
: routes.devIde({ cadPackage: ideType })
|
||||
}
|
||||
>
|
||||
<div>{name}</div>
|
||||
<div className="text-xs text-gray-600 font-light">{sub}</div>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
export default NavPlusButton
|
||||
@@ -13,6 +13,9 @@ export const render = async ({ code, settings }) => {
|
||||
},
|
||||
file: code,
|
||||
})
|
||||
if (!settings.camera.position) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const response = await fetch(lambdaBaseURL + '/openscad/preview', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -8,7 +8,8 @@ function withThunk(dispatch, getState) {
|
||||
: dispatch(actionOrThunk)
|
||||
}
|
||||
|
||||
const donutInitCode = `
|
||||
const initCodeMap = {
|
||||
openScad: `
|
||||
color(c="DarkGoldenrod")rotate_extrude()translate([20,0])circle(d=30);
|
||||
donut();
|
||||
module donut() {
|
||||
@@ -21,16 +22,31 @@ module stick(basewid, angl){
|
||||
sphere(7);
|
||||
translate([0,0,10])sphere(9);
|
||||
}
|
||||
}`
|
||||
}`,
|
||||
cadQuery: `import cadquery as cq
|
||||
from cadquery import exporters
|
||||
|
||||
diam = 5.0
|
||||
|
||||
result = (cq.Workplane().circle(diam).extrude(20.0)
|
||||
.faces(">Z").workplane(invert=True).circle(1.05).cutBlind(8.0)
|
||||
.faces("<Z").workplane(invert=True).circle(0.8).cutBlind(12.0)
|
||||
.edges("%CIRCLE").chamfer(0.15))
|
||||
|
||||
# exporters.export(coupler, "/home/jwright/Downloads/coupler.stl", exporters.ExportTypes.STL)
|
||||
|
||||
show_object(result)
|
||||
`,
|
||||
}
|
||||
|
||||
export const codeStorageKey = 'Last-openscad-code'
|
||||
let mutableState = null
|
||||
|
||||
export const useIdeState = () => {
|
||||
const code = localStorage.getItem(codeStorageKey) || donutInitCode
|
||||
const code = localStorage.getItem(codeStorageKey) || initCodeMap.openscad
|
||||
const initialState = {
|
||||
ideType: 'cadQuery',
|
||||
consoleMessages: [{ type: 'message', message: 'Initialising OpenSCAD' }],
|
||||
ideType: 'INIT',
|
||||
consoleMessages: [{ type: 'message', message: 'Initialising' }],
|
||||
code,
|
||||
objectData: {
|
||||
type: 'stl',
|
||||
@@ -52,6 +68,12 @@ export const useIdeState = () => {
|
||||
}
|
||||
const reducer = (state, { type, payload }) => {
|
||||
switch (type) {
|
||||
case 'initIde':
|
||||
return {
|
||||
...state,
|
||||
code: initCodeMap[payload.cadPackage] || initCodeMap.openscad,
|
||||
ideType: payload.cadPackage,
|
||||
}
|
||||
case 'updateCode':
|
||||
return { ...state, code: payload }
|
||||
case 'healthyRender':
|
||||
@@ -74,11 +96,6 @@ export const useIdeState = () => {
|
||||
: payload.message,
|
||||
isLoading: false,
|
||||
}
|
||||
case 'setIdeType':
|
||||
return {
|
||||
...state,
|
||||
ideType: payload.message,
|
||||
}
|
||||
case 'setLayout':
|
||||
return {
|
||||
...state,
|
||||
@@ -122,26 +139,28 @@ export const requestRender = ({
|
||||
camera,
|
||||
viewerSize,
|
||||
}) => {
|
||||
cadPackages[state.ideType]
|
||||
.render({
|
||||
code,
|
||||
settings: {
|
||||
camera,
|
||||
viewerSize,
|
||||
},
|
||||
})
|
||||
.then(({ objectData, message, status }) => {
|
||||
if (status === 'error') {
|
||||
dispatch({
|
||||
type: 'errorRender',
|
||||
payload: { message },
|
||||
})
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'healthyRender',
|
||||
payload: { objectData, message },
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => dispatch({ type: 'resetLoading' })) // TODO should probably display something to the user here
|
||||
state.ideType !== 'INIT' &&
|
||||
!state.isLoading &&
|
||||
cadPackages[state.ideType]
|
||||
.render({
|
||||
code,
|
||||
settings: {
|
||||
camera,
|
||||
viewerSize,
|
||||
},
|
||||
})
|
||||
.then(({ objectData, message, status }) => {
|
||||
if (status === 'error') {
|
||||
dispatch({
|
||||
type: 'errorRender',
|
||||
payload: { message },
|
||||
})
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'healthyRender',
|
||||
payload: { objectData, message, lastRunCode: code },
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(() => dispatch({ type: 'resetLoading' })) // TODO should probably display something to the user here
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getActiveClasses } from 'get-active-classes'
|
||||
import Footer from 'src/components/Footer'
|
||||
import { useLocation } from '@redwoodjs/router'
|
||||
import LoginModal from 'src/components/LoginModal'
|
||||
import NavPlusButton from 'src/components/NavPlusButton'
|
||||
import ReactGA from 'react-ga'
|
||||
import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
||||
|
||||
@@ -132,9 +133,7 @@ const MainLayout = ({ children, shouldRemoveFooterInIde }) => {
|
||||
'mr-8 h-10 w-10 rounded-full border-2 border-indigo-300 flex items-center justify-center'
|
||||
)}
|
||||
>
|
||||
<Link className="h-full w-full" to={routes.draftPart()}>
|
||||
<Svg name="plus" className="text-indigo-300 w-full h-full" />
|
||||
</Link>
|
||||
<NavPlusButton />
|
||||
</li>
|
||||
{isAuthenticated ? (
|
||||
<li
|
||||
|
||||
@@ -3,7 +3,7 @@ import Seo from 'src/components/Seo/Seo'
|
||||
import IdeToolbar from 'src/components/IdeToolbarNew'
|
||||
import OutBound from 'src/components/OutBound'
|
||||
|
||||
const DevIdePage = () => {
|
||||
const DevIdePage = ({ cadPackage }) => {
|
||||
return (
|
||||
<div className="h-screen flex flex-col">
|
||||
<MainLayout shouldRemoveFooterInIde>
|
||||
@@ -12,10 +12,9 @@ const DevIdePage = () => {
|
||||
description="new ide in development"
|
||||
lang="en-US"
|
||||
/>
|
||||
<div className="py-4 bg-pink-200">
|
||||
<div className="mx-auto max-w-6xl">
|
||||
Woah, woah. You shouldn't be here! We're still working on this.
|
||||
Since you've seen it now, have a look what{' '}
|
||||
<div className="py-2 bg-pink-200">
|
||||
<div className="mx-auto max-w-3xl">
|
||||
We're still working on this. Since you're here, have a look what{' '}
|
||||
<OutBound
|
||||
className="text-pink-700"
|
||||
to="https://github.com/Irev-Dev/cadhub/discussions/212"
|
||||
@@ -27,7 +26,7 @@ const DevIdePage = () => {
|
||||
</div>
|
||||
</MainLayout>
|
||||
<div className="flex-auto">
|
||||
<IdeToolbar />
|
||||
<IdeToolbar cadPackage={cadPackage} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1404,6 +1404,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-2.0.0.tgz#5bb2193eb685c0007540ca61d166d4e1edaf918d"
|
||||
integrity sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==
|
||||
|
||||
"@headlessui/react@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.0.0.tgz#661b50ebfd25041abb45d8eedd85e7559056bcaf"
|
||||
integrity sha512-mjqRJrgkbcHQBfAHnqH0yRxO/y/22jYrdltpE7WkurafREKZ+pj5bPBwYHMt935Sdz/n16yRcVmsSCqDFHee9A==
|
||||
|
||||
"@icons/material@^0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
||||
|
||||
Reference in New Issue
Block a user