1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
/web/src/cascade/*
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -17,7 +17,9 @@
|
||||
"./web/src/Routes.js",
|
||||
],
|
||||
"cSpell.words": [
|
||||
"Initialised",
|
||||
"Uploader",
|
||||
"initialise",
|
||||
"redwoodjs"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ const Routes = () => {
|
||||
return (
|
||||
<Router>
|
||||
<Route path="/" page={PartsPage} name="home" />
|
||||
{/* <Route path="/blah/*" page={PartsPage} name="home" /> */}
|
||||
<Route notfound page={NotFoundPage} />
|
||||
|
||||
{/* Ownership enforced routes */}
|
||||
@@ -24,7 +23,7 @@ const Routes = () => {
|
||||
|
||||
<Route path="/u/{userName}" page={User2Page} name="user2" />
|
||||
<Route path="/u/{userName}/{partTitle}" page={Part2Page} name="part2" />
|
||||
{/* <Route path="/u/{userName}/{partTitle}/ide" page={Part2Page} name="part2" /> */}
|
||||
<Route path="/u/{userName}/{partTitle}/ide" page={IdePartPage} name="ide" />
|
||||
|
||||
{/* GENERATED ROUTES BELOW, probably going to clean these up and delete most of them, but the CRUD functionality is useful for now */}
|
||||
{/* All private by default for safety and because the routes that are left after clean up will probably be admin pages */}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB |
Submodule web/src/cascade updated: e634591e27...37cea9eeb2
@@ -1,41 +1,57 @@
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
// import BlogPostsCell from 'src/components/BlogPostsCell'
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { Link, routes, navigate } from '@redwoodjs/router'
|
||||
import { initialize } from 'src/cascade/js/MainPage/CascadeMain'
|
||||
import CascadeController from 'src/helpers/cascadeController'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const starterCode = `// Welcome to Cascade Studio! Here are some useful functions:
|
||||
// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()
|
||||
// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()
|
||||
// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),
|
||||
// FilletEdges(), ChamferEdges(),
|
||||
// Slider(), Button(), Checkbox()
|
||||
|
||||
// Uncomment and hover over them to see their apis
|
||||
|
||||
let holeRadius = Slider("Radius", 30 , 20 , 40);
|
||||
|
||||
let sphere = Sphere(50);
|
||||
let cylinderZ = Cylinder(holeRadius, 200, true);
|
||||
let cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));
|
||||
let cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));
|
||||
|
||||
Translate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));
|
||||
|
||||
Translate([-100, 0, 100], Text3D("cadhub.xyz"));
|
||||
|
||||
// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!
|
||||
const DELETE_PART_MUTATION = gql`
|
||||
mutation DeletePartMutation($id: Int!) {
|
||||
deletePart(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
const domNode = document.createElement('div').setAttribute('id', 'sickId')
|
||||
|
||||
const HomePage1 = () => {
|
||||
const [code, setCode] = useState(starterCode)
|
||||
const IdeCascadeStudio = ({ part, saveCode, loading, error }) => {
|
||||
const [code, setCode] = useState(part.code)
|
||||
useEffect(() => {
|
||||
const sickCallback = (code) => setCode(code)
|
||||
new initialize(sickCallback, starterCode)
|
||||
const onCodeChange = (code) => setCode(code)
|
||||
CascadeController.initialise(onCodeChange, part.code, domNode)
|
||||
const element = document.getElementById('cascade-container')
|
||||
element.setAttribute('style', 'height: auto; display: block; opacity: 100%') // eslint-disable-line
|
||||
return () => {
|
||||
element.setAttribute('style', 'height: auto; display: none;') // eslint-disable-line
|
||||
}
|
||||
}, [])
|
||||
const hasChanges = code !== part.code
|
||||
const { addMessage } = useFlash()
|
||||
const [deletePart] = useMutation(DELETE_PART_MUTATION, {
|
||||
onCompleted: () => {
|
||||
// navigate(routes.parts())
|
||||
addMessage('Part deleted.', { classes: 'rw-flash-success' })
|
||||
},
|
||||
})
|
||||
|
||||
const onDeleteClick = (id) => {
|
||||
if (confirm('Are you sure you want to delete part ' + id + '?')) {
|
||||
deletePart({ variables: { id } })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<div>current code {code}</div>
|
||||
<BlogPostsCell />
|
||||
<>
|
||||
<nav className="rw-button-group">
|
||||
{loading && 'Loading...'}
|
||||
{hasChanges && !loading && (
|
||||
<button
|
||||
onClick={() => saveCode({ code }, part.id)}
|
||||
className="rw-button rw-button-blue"
|
||||
>
|
||||
Save Changes
|
||||
</button>
|
||||
)}
|
||||
</nav>
|
||||
<div>
|
||||
<div id="topnav" className="topnav">
|
||||
<a href="https://github.com/zalo/CascadeStudio">
|
||||
@@ -109,15 +125,14 @@ const HomePage1 = () => {
|
||||
Reset Project
|
||||
</a>
|
||||
</div>
|
||||
<div id="cascade-container" style={{ height: 'auto' }}></div>
|
||||
<footer>footer</footer>
|
||||
{/* <div
|
||||
id="cascade-container"
|
||||
style={{ height: 'auto' }}
|
||||
// dangerouslySetInnerHTML={domNode}
|
||||
></div> */}
|
||||
</div>
|
||||
</MainLayout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const HomePage = () => {
|
||||
return <MainLayout>hi</MainLayout>
|
||||
}
|
||||
|
||||
export default HomePage
|
||||
export default IdeCascadeStudio
|
||||
@@ -0,0 +1,7 @@
|
||||
import IdeCascadeStudio from './IdeCascadeStudio'
|
||||
|
||||
export const generated = () => {
|
||||
return <IdeCascadeStudio />
|
||||
}
|
||||
|
||||
export default { title: 'Components/IdeCascadeStudio' }
|
||||
@@ -1,11 +1,11 @@
|
||||
import { render } from '@redwoodjs/testing'
|
||||
|
||||
import HomePage from './HomePage'
|
||||
import IdeCascadeStudio from './IdeCascadeStudio'
|
||||
|
||||
describe('HomePage', () => {
|
||||
describe('IdeCascadeStudio', () => {
|
||||
it('renders successfully', () => {
|
||||
expect(() => {
|
||||
render(<HomePage />)
|
||||
render(<IdeCascadeStudio />)
|
||||
}).not.toThrow()
|
||||
})
|
||||
})
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useMutation, useFlash } from '@redwoodjs/web'
|
||||
import { navigate, routes } from '@redwoodjs/router'
|
||||
// import Part from 'src/components/Part'
|
||||
import IdeCascadeStudio from 'src/components/IdeCascadeStudio'
|
||||
// import Part from 'src/components/Part'a
|
||||
|
||||
export const QUERY = gql`
|
||||
query FIND_PART_BY_ID($id: Int!) {
|
||||
part: part(id: $id) {
|
||||
query FIND_PART_BY_USENAME_TITLE($partTitle: String!, $userName: String!) {
|
||||
part: partByUserAndTitle(partTitle: $partTitle, userName: $userName) {
|
||||
id
|
||||
title
|
||||
description
|
||||
@@ -16,7 +17,7 @@ export const QUERY = gql`
|
||||
`
|
||||
|
||||
const UPDATE_PART_MUTATION = gql`
|
||||
mutation UpdatePartMutation($id: Int!, $input: UpdatePartInput!) {
|
||||
mutation UpdatePartMutation($id: String!, $input: UpdatePartInput!) {
|
||||
updatePart(id: $id, input: $input) {
|
||||
id
|
||||
}
|
||||
@@ -27,7 +28,7 @@ export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => <div>Part not found</div>
|
||||
|
||||
export const Success = ({ part }) => {
|
||||
export const Success = ({ part, refetch }) => {
|
||||
const { addMessage } = useFlash()
|
||||
const [updatePart, { loading, error }] = useMutation(UPDATE_PART_MUTATION, {
|
||||
onCompleted: () => {
|
||||
@@ -40,7 +41,14 @@ export const Success = ({ part }) => {
|
||||
const saveCode = (input, id) => {
|
||||
console.log(id, input, 'wowow')
|
||||
updatePart({ variables: { id, input } })
|
||||
refetch()
|
||||
}
|
||||
return <div>TODO part</div>
|
||||
// return <Part part={{...part, code: part.code}} saveCode={saveCode} loading={loading} error={error} />
|
||||
return (
|
||||
<IdeCascadeStudio
|
||||
part={part}
|
||||
saveCode={saveCode}
|
||||
loading={loading}
|
||||
error={error}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -92,14 +92,21 @@ const PartProfile = ({
|
||||
>
|
||||
Comments 11
|
||||
</Button>
|
||||
<Button
|
||||
className="mt-4 ml-auto shadow-md hover:shadow-lg bg-indigo-200"
|
||||
shouldAnimateHover
|
||||
iconName="terminal"
|
||||
onClick={() => {}}
|
||||
<Link
|
||||
to={routes.ide({
|
||||
userName: userPart.userName,
|
||||
partTitle: part.title,
|
||||
})}
|
||||
>
|
||||
Open IDE
|
||||
</Button>
|
||||
<Button
|
||||
className="mt-4 ml-auto shadow-md hover:shadow-lg bg-indigo-200"
|
||||
shouldAnimateHover
|
||||
iconName="terminal"
|
||||
onClick={() => {}}
|
||||
>
|
||||
Open IDE
|
||||
</Button>
|
||||
</Link>
|
||||
{canEdit && (
|
||||
<Button
|
||||
className="mt-4 ml-auto shadow-md hover:shadow-lg bg-indigo-200 relative z-20"
|
||||
|
||||
25
web/src/helpers/cascadeController.js
Normal file
25
web/src/helpers/cascadeController.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { initialize, getEditor } from 'src/cascade/js/MainPage/CascadeMain'
|
||||
|
||||
class CascadeController {
|
||||
_hasInitialised = false
|
||||
incomingOnCodeChang = () => {}
|
||||
controllerOnCodeChange = (code) => {
|
||||
this.incomingOnCodeChang(code)
|
||||
}
|
||||
|
||||
initialise(onCodeChange, code) {
|
||||
// only inits on first call, after that it just updates the editor and revaluates code, maybe should rename?
|
||||
this.incomingOnCodeChang = onCodeChange
|
||||
if (!this._hasInitialised) {
|
||||
initialize(this.controllerOnCodeChange, code)
|
||||
this._hasInitialised = true
|
||||
return
|
||||
}
|
||||
const editor = getEditor()
|
||||
editor.setValue(code)
|
||||
editor.evaluateCode(false)
|
||||
return this.domNode
|
||||
}
|
||||
}
|
||||
|
||||
export default new CascadeController()
|
||||
@@ -14,16 +14,16 @@
|
||||
var cascadeStudioWorker
|
||||
var workerWorking = false
|
||||
var galleryProject = undefined
|
||||
function coolGuy() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('service-worker.js').then(function(registration) {
|
||||
registration.update(); // Always update the registration for the latest assets
|
||||
}, function() {
|
||||
console.log('Could not register Cascade Studio for offline use!');
|
||||
});
|
||||
} else {
|
||||
console.log('Browser does not support offline access!');
|
||||
}
|
||||
function initCascadeStudio() {
|
||||
// if ('serviceWorker' in navigator) {
|
||||
// navigator.serviceWorker.register('service-worker.js').then(function(registration) {
|
||||
// registration.update(); // Always update the registration for the latest assets
|
||||
// }, function() {
|
||||
// console.log('Could not register Cascade Studio for offline use!');
|
||||
// });
|
||||
// } else {
|
||||
// console.log('Browser does not support offline access!');
|
||||
// }
|
||||
|
||||
// Begins loading the CAD Kernel Web Worker
|
||||
if (window.Worker) {
|
||||
@@ -38,10 +38,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// coolGuy()
|
||||
initCascadeStudio()
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="redwood-app"></div>
|
||||
<div
|
||||
id="cascade-container"
|
||||
style="height: auto; opacity: 0;"
|
||||
></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import HomePage from './HomePage'
|
||||
|
||||
export const generated = () => {
|
||||
return <HomePage />
|
||||
}
|
||||
|
||||
export default { title: 'Pages/HomePage' }
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import MainLayout from 'src/layouts/MainLayout'
|
||||
import IdePartCell from 'src/components/IdePartCell'
|
||||
|
||||
const IdePartPage = ({ id }) => {
|
||||
const IdePartPage = ({ userName, partTitle }) => {
|
||||
return (
|
||||
<MainLayout>
|
||||
<IdePartCell id={id} />
|
||||
<IdePartCell userName={userName} partTitle={partTitle} />
|
||||
</MainLayout>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user