Start adding ide colors, includes adding custom theme to openscad
Resolves #365
This commit is contained in:
@@ -42,6 +42,8 @@ RUN npm install
|
|||||||
RUN echo "OPENSCADPATH=/var/task/openscad" >>/etc/profile && \
|
RUN echo "OPENSCADPATH=/var/task/openscad" >>/etc/profile && \
|
||||||
wget -P /var/task/openscad/ https://github.com/Irev-Dev/Round-Anything/archive/refs/tags/1.0.4.zip && \
|
wget -P /var/task/openscad/ https://github.com/Irev-Dev/Round-Anything/archive/refs/tags/1.0.4.zip && \
|
||||||
unzip /var/task/openscad/1.0.4
|
unzip /var/task/openscad/1.0.4
|
||||||
|
# Add our own theming (based on DeepOcean with a different "background" and "opencsg-face-back")
|
||||||
|
COPY openscad/cadhubtheme.json /usr/share/openscad/color-schemes/render/
|
||||||
|
|
||||||
COPY openscad/*.js /var/task/
|
COPY openscad/*.js /var/task/
|
||||||
COPY common/*.js /var/common/
|
COPY common/*.js /var/common/
|
||||||
|
|||||||
19
app/api/src/docker/openscad/cadhubtheme.json
Normal file
19
app/api/src/docker/openscad/cadhubtheme.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name" : "CadHub",
|
||||||
|
"index" : 1600,
|
||||||
|
"show-in-gui" : true,
|
||||||
|
|
||||||
|
"colors" : {
|
||||||
|
"background" : "#1A1A1D",
|
||||||
|
"axes-color" : "#c1c1c1",
|
||||||
|
"opencsg-face-front" : "#eeeeee",
|
||||||
|
"opencsg-face-back" : "#8732F2",
|
||||||
|
"cgal-face-front" : "#eeeeee",
|
||||||
|
"cgal-face-back" : "#0babc8",
|
||||||
|
"cgal-face-2d" : "#9370db",
|
||||||
|
"cgal-edge-front" : "#0000ff",
|
||||||
|
"cgal-edge-back" : "#0000ff",
|
||||||
|
"cgal-edge-2d" : "#ff00ff",
|
||||||
|
"crosshair" : "#f0f0f0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ module.exports.runScad = async ({
|
|||||||
const { x: px, y: py, z: pz } = position
|
const { x: px, y: py, z: pz } = position
|
||||||
const cameraArg = `--camera=${px},${py},${pz},${rx},${ry},${rz},${dist}`
|
const cameraArg = `--camera=${px},${py},${pz},${rx},${ry},${rz},${dist}`
|
||||||
const fullPath = `/tmp/${tempFile}/output.png`
|
const fullPath = `/tmp/${tempFile}/output.png`
|
||||||
const command = `xvfb-run --auto-servernum --server-args "-screen 0 1024x768x24" openscad -o ${fullPath} ${cameraArg} --imgsize=${x},${y} --colorscheme DeepOcean /tmp/${tempFile}/main.scad`
|
const command = `xvfb-run --auto-servernum --server-args "-screen 0 1024x768x24" openscad -o ${fullPath} ${cameraArg} --imgsize=${x},${y} --colorscheme CadHub /tmp/${tempFile}/main.scad`
|
||||||
console.log('command', command)
|
console.log('command', command)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ const EditorMenu = () => {
|
|||||||
const isOpenScad = state.ideType === 'openScad'
|
const isOpenScad = state.ideType === 'openScad'
|
||||||
const isCadQuery = state.ideType === 'cadQuery'
|
const isCadQuery = state.ideType === 'cadQuery'
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-between bg-gray-500 text-gray-100">
|
<div className="flex justify-between bg-ch-gray-760 text-gray-100">
|
||||||
<div className="flex items-center h-9 w-full cursor-grab">
|
<div className="flex items-center h-9 w-full cursor-grab">
|
||||||
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
<div className=" text-ch-gray-760 bg-ch-gray-300 cursor-grab px-2 h-full flex items-center">
|
||||||
<Svg name="drag-grid" className="w-4 p-px" />
|
<Svg name="drag-grid" className="w-4 p-px" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-6 px-5">
|
<div className="flex gap-6 px-5">
|
||||||
@@ -31,10 +31,12 @@ const EditorMenu = () => {
|
|||||||
<button className="cursor-not-allowed" disabled>
|
<button className="cursor-not-allowed" disabled>
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
<ViewDropdown handleLayoutReset={() => thunkDispatch({type: 'resetLayout'})} />
|
<ViewDropdown
|
||||||
|
handleLayoutReset={() => thunkDispatch({ type: 'resetLayout' })}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="text-gray-300 h-full cursor-not-allowed"
|
className="text-ch-gray-300 h-full cursor-not-allowed"
|
||||||
aria-label="editor settings"
|
aria-label="editor settings"
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
@@ -112,12 +114,18 @@ function ViewDropdown({ handleLayoutReset }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Dropdown({ name, children }: {name: string, children: React.ReactNode}) {
|
function Dropdown({
|
||||||
|
name,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
name: string
|
||||||
|
children: React.ReactNode
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Button className="text-gray-100">{name}</Menu.Button>
|
<Menu.Button className="text-gray-100">{name}</Menu.Button>
|
||||||
<Menu.Items className="absolute flex flex-col mt-4 bg-gray-500 rounded shadow-md text-gray-100 overflow-hidden whitespace-nowrap">
|
<Menu.Items className="absolute flex flex-col mt-4 bg-ch-gray-760 rounded text-gray-100 overflow-hidden whitespace-nowrap border border-ch-gray-700">
|
||||||
{children}
|
{children}
|
||||||
</Menu.Items>
|
</Menu.Items>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
||||||
import { matchEditorVsDarkTheme } from 'src/components/IdeEditor'
|
|
||||||
|
|
||||||
const IdeConsole = () => {
|
const IdeConsole = () => {
|
||||||
const { state } = useIdeContext()
|
const { state } = useIdeContext()
|
||||||
@@ -12,21 +11,14 @@ const IdeConsole = () => {
|
|||||||
}, [state.consoleMessages])
|
}, [state.consoleMessages])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="p-2 px-8 pt-4 min-h-full bg-ch-gray-800">
|
||||||
className="p-2 px-8 pt-14 min-h-full"
|
|
||||||
style={matchEditorVsDarkTheme.Bg}
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
{state.consoleMessages?.map(({ type, message, time }, index) => (
|
{state.consoleMessages?.map(({ type, message, time }, index) => (
|
||||||
<pre
|
<pre
|
||||||
className="font-mono text-sm"
|
className="font-mono text-sm text-gray-300"
|
||||||
style={matchEditorVsDarkTheme.Text}
|
|
||||||
key={`${message} ${index}`}
|
key={`${message} ${index}`}
|
||||||
>
|
>
|
||||||
<div
|
<div className="text-xs font-bold pt-2 text-ch-blue-600">
|
||||||
className="text-xs font-bold pt-2"
|
|
||||||
style={matchEditorVsDarkTheme.TextBrown}
|
|
||||||
>
|
|
||||||
{time?.toLocaleString()}
|
{time?.toLocaleString()}
|
||||||
</div>
|
</div>
|
||||||
<div className={(type === 'error' ? 'text-red-400' : '') + ' pl-4'}>
|
<div className={(type === 'error' ? 'text-red-400' : '') + ' pl-4'}>
|
||||||
|
|||||||
@@ -1,17 +1,43 @@
|
|||||||
import { useRef, useEffect } from 'react'
|
import { useRef, useEffect, Suspense, lazy } from 'react'
|
||||||
import { Mosaic, MosaicWindow } from 'react-mosaic-component'
|
import { Mosaic, MosaicWindow } from 'react-mosaic-component'
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
||||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||||
import IdeEditor from 'src/components/IdeEditor'
|
|
||||||
import IdeViewer from 'src/components/IdeViewer'
|
|
||||||
import IdeConsole from 'src/components/IdeConsole'
|
import IdeConsole from 'src/components/IdeConsole'
|
||||||
import 'react-mosaic-component/react-mosaic-component.css'
|
import 'react-mosaic-component/react-mosaic-component.css'
|
||||||
import EditorMenu from 'src/components/EditorMenu/EditorMenu'
|
import EditorMenu from 'src/components/EditorMenu/EditorMenu'
|
||||||
import PanelToolbar from 'src/components/PanelToolbar'
|
import PanelToolbar from 'src/components/PanelToolbar'
|
||||||
|
|
||||||
|
const IdeEditor = lazy(() => import('src/components/IdeEditor/IdeEditor'))
|
||||||
|
const IdeViewer = lazy(() => import('src/components/IdeViewer/IdeViewer'))
|
||||||
|
|
||||||
|
const SmallLoadingPing = (
|
||||||
|
<div className="bg-ch-gray-800 text-gray-200 font-ropa-sans relative w-full h-full flex justify-center items-center">
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-0 flex justify-center items-center">
|
||||||
|
<div className="h-4 w-4 bg-purple-600 rounded-full animate-ping"></div>
|
||||||
|
</div>
|
||||||
|
<div className="relative">. . . loading</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const BigLoadingPing = () => (
|
||||||
|
<div className="inset-0 absolute flex items-center justify-center">
|
||||||
|
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
const ELEMENT_MAP = {
|
const ELEMENT_MAP = {
|
||||||
Editor: <IdeEditor />,
|
Editor: (
|
||||||
Viewer: <IdeViewer />,
|
<Suspense fallback={SmallLoadingPing}>
|
||||||
|
<IdeEditor Loading={SmallLoadingPing} />
|
||||||
|
</Suspense>
|
||||||
|
),
|
||||||
|
Viewer: (
|
||||||
|
<Suspense fallback={BigLoadingPing}>
|
||||||
|
<IdeViewer Loading={BigLoadingPing} />
|
||||||
|
</Suspense>
|
||||||
|
),
|
||||||
Console: <IdeConsole />,
|
Console: <IdeConsole />,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +104,10 @@ const IdeContainer = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="cadhub-ide" className="mosaic-toolbar-overrides flex-auto h-full">
|
<div
|
||||||
|
id="cadhub-ide"
|
||||||
|
className="mosaic-toolbar-overrides flex-auto h-full bg-red-500"
|
||||||
|
>
|
||||||
<Mosaic
|
<Mosaic
|
||||||
renderTile={(id, path) => {
|
renderTile={(id, path) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,22 +1,43 @@
|
|||||||
import { Suspense, lazy } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
||||||
import { makeCodeStoreKey } from 'src/helpers/hooks/useIdeState'
|
import { makeCodeStoreKey } from 'src/helpers/hooks/useIdeState'
|
||||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||||
const Editor = lazy(() => import('@monaco-editor/react'))
|
import Editor, { useMonaco } from '@monaco-editor/react'
|
||||||
|
import { theme } from 'src/../tailwind.config'
|
||||||
|
|
||||||
export const matchEditorVsDarkTheme = {
|
const colors = theme.extend.colors
|
||||||
// Some colors to roughly match the vs-dark editor theme
|
|
||||||
Bg: { backgroundColor: 'rgb(30,30,30)' },
|
|
||||||
Text: { color: 'rgb(212,212,212)' },
|
|
||||||
TextBrown: { color: 'rgb(206,144,120)' },
|
|
||||||
}
|
|
||||||
|
|
||||||
const IdeEditor = () => {
|
const IdeEditor = ({ Loading }) => {
|
||||||
const { state, thunkDispatch } = useIdeContext()
|
const { state, thunkDispatch } = useIdeContext()
|
||||||
|
const [theme, setTheme] = useState('vs-dark')
|
||||||
const ideTypeToLanguageMap = {
|
const ideTypeToLanguageMap = {
|
||||||
cadQuery: 'python',
|
cadQuery: 'python',
|
||||||
openScad: 'cpp',
|
openScad: 'cpp',
|
||||||
}
|
}
|
||||||
|
const monaco = useMonaco()
|
||||||
|
useEffect(() => {
|
||||||
|
if (monaco) {
|
||||||
|
const themeName = 'cadhub'
|
||||||
|
monaco.editor.defineTheme(themeName, {
|
||||||
|
base: 'vs-dark',
|
||||||
|
inherit: true,
|
||||||
|
rules: [
|
||||||
|
{ background: colors['ch-gray'][750] },
|
||||||
|
{
|
||||||
|
token: 'comment',
|
||||||
|
foreground: colors['ch-blue'][600],
|
||||||
|
fontStyle: 'italic',
|
||||||
|
},
|
||||||
|
{ token: 'keyword', foreground: colors['ch-purple'][600] },
|
||||||
|
{ token: 'string', foreground: colors['ch-pink'][300] },
|
||||||
|
],
|
||||||
|
colors: {
|
||||||
|
'editor.background': colors['ch-gray'][800],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
setTheme(themeName)
|
||||||
|
}
|
||||||
|
}, [monaco])
|
||||||
|
|
||||||
function handleCodeChange(value, _event) {
|
function handleCodeChange(value, _event) {
|
||||||
thunkDispatch({ type: 'updateCode', payload: value })
|
thunkDispatch({ type: 'updateCode', payload: value })
|
||||||
@@ -40,33 +61,22 @@ const IdeEditor = () => {
|
|||||||
localStorage.setItem(makeCodeStoreKey(state.ideType), state.code)
|
localStorage.setItem(makeCodeStoreKey(state.ideType), state.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const loading = (
|
|
||||||
<div
|
|
||||||
className="text-gray-700 font-ropa-sans relative"
|
|
||||||
style={{ backgroundColor: 'red' }}
|
|
||||||
>
|
|
||||||
<div className="absolute inset-0 text-center flex items-center w-32">
|
|
||||||
. . . loading
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
<div // eslint-disable-line jsx-a11y/no-static-element-interactions
|
<div // eslint-disable-line jsx-a11y/no-static-element-interactions
|
||||||
className="h-full"
|
className="h-full"
|
||||||
onKeyDown={handleSaveHotkey}
|
onKeyDown={handleSaveHotkey}
|
||||||
>
|
>
|
||||||
<Suspense fallback={loading}>
|
<Editor
|
||||||
<Editor
|
defaultValue={state.code}
|
||||||
defaultValue={state.code}
|
value={state.code}
|
||||||
value={state.code}
|
theme={theme}
|
||||||
theme="vs-dark"
|
loading={Loading}
|
||||||
loading={loading}
|
// TODO #247 cpp seems better than js for the time being
|
||||||
// TODO #247 cpp seems better than js for the time being
|
defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
||||||
defaultLanguage={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
||||||
language={ideTypeToLanguageMap[state.ideType] || 'cpp'}
|
onChange={handleCodeChange}
|
||||||
onChange={handleCodeChange}
|
/>
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,38 +2,39 @@ import { Popover } from '@headlessui/react'
|
|||||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
|
||||||
import FullScriptEncoding from 'src/components/EncodedUrl/FullScriptEncoding'
|
import FullScriptEncoding from 'src/components/EncodedUrl/FullScriptEncoding'
|
||||||
import ExternalScript from 'src/components/EncodedUrl/ExternalScript'
|
import ExternalScript from 'src/components/EncodedUrl/ExternalScript'
|
||||||
|
import Svg from 'src/components/Svg/Svg'
|
||||||
|
|
||||||
const TopButton = ({
|
const TopButton = ({
|
||||||
onClick,
|
onClick,
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
iconColor,
|
name,
|
||||||
}: {
|
}: {
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
iconColor: string
|
name: string
|
||||||
}) => (
|
}) => (
|
||||||
<button
|
<button
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={`flex bg-gray-200 h-10 justify-center items-center px-4 rounded ${className}`}
|
className={`flex bg-gray-200 h-10 justify-center items-center px-4 rounded ${className}`}
|
||||||
>
|
>
|
||||||
<div className={`rounded-full h-6 w-6 mr-4 ${iconColor}`} />
|
|
||||||
{children}
|
{children}
|
||||||
|
{name}
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
const IdeHeader = ({ handleRender }: { handleRender: () => void }) => {
|
const IdeHeader = ({ handleRender }: { handleRender: () => void }) => {
|
||||||
return (
|
return (
|
||||||
<div className="h-16 w-full bg-gray-900 flex justify-between items-center">
|
<div className="h-16 w-full bg-ch-gray-900 flex justify-between items-center">
|
||||||
<div className="bg-gray-700 pr-48 h-full"></div>
|
<div className="bg-ch-gray-700 pr-48 h-full"></div>
|
||||||
<div className="text-gray-200 flex gap-4 mr-4">
|
<div className="text-gray-200 flex gap-4 mr-4">
|
||||||
<TopButton
|
<TopButton
|
||||||
className="bg-gray-600 text-gray-200"
|
className="bg-ch-pink-800 bg-opacity-30 hover:bg-opacity-80 text-ch-gray-300"
|
||||||
iconColor="bg-gray-300"
|
|
||||||
onClick={handleRender}
|
onClick={handleRender}
|
||||||
|
name="Preview"
|
||||||
>
|
>
|
||||||
Render
|
<Svg name="photograph" className="w-6 h-6 text-ch-pink-500 mr-2" />
|
||||||
</TopButton>
|
</TopButton>
|
||||||
|
|
||||||
<Popover className="relative outline-none w-full h-full">
|
<Popover className="relative outline-none w-full h-full">
|
||||||
@@ -41,8 +42,14 @@ const IdeHeader = ({ handleRender }: { handleRender: () => void }) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Popover.Button className="h-full w-full outline-none">
|
<Popover.Button className="h-full w-full outline-none">
|
||||||
<TopButton iconColor="bg-gray-600" className="text-gray-700">
|
<TopButton
|
||||||
Share
|
name="Share"
|
||||||
|
className=" bg-ch-purple-400 bg-opacity-30 hover:bg-opacity-80 text-ch-gray-300"
|
||||||
|
>
|
||||||
|
<Svg
|
||||||
|
name="share"
|
||||||
|
className="w-6 h-6 text-ch-purple-500 mr-2 mt-1"
|
||||||
|
/>
|
||||||
</TopButton>
|
</TopButton>
|
||||||
</Popover.Button>
|
</Popover.Button>
|
||||||
{open && (
|
{open && (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Svg from 'src/components/Svg/Svg'
|
|||||||
const IdeSideBar = () => {
|
const IdeSideBar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col justify-between">
|
<div className="h-full flex flex-col justify-between">
|
||||||
<div className="w-16 h-16 flex items-center justify-center bg-gray-900">
|
<div className="w-16 h-16 flex items-center justify-center bg-ch-gray-900">
|
||||||
<Link to={routes.home()}>
|
<Link to={routes.home()}>
|
||||||
<Svg className="w-12" name="favicon" />
|
<Svg className="w-12" name="favicon" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ function Sphere(props) {
|
|||||||
</mesh>
|
</mesh>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const IdeViewer = () => {
|
const IdeViewer = ({ Loading }) => {
|
||||||
const { state, thunkDispatch } = useIdeContext()
|
const { state, thunkDispatch } = useIdeContext()
|
||||||
const [isDragging, setIsDragging] = useState(false)
|
const [isDragging, setIsDragging] = useState(false)
|
||||||
const [image, setImage] = useState()
|
const [image, setImage] = useState()
|
||||||
@@ -146,21 +146,13 @@ const IdeViewer = () => {
|
|||||||
setIsDragging(false)
|
setIsDragging(false)
|
||||||
}, [state.objectData?.type, state.objectData?.data])
|
}, [state.objectData?.type, state.objectData?.data])
|
||||||
|
|
||||||
const openSCADDeepOceanThemeBackground = '#323232'
|
|
||||||
// the following are tailwind colors in hex, can't use these classes to color three.js meshes.
|
// the following are tailwind colors in hex, can't use these classes to color three.js meshes.
|
||||||
const pink400 = '#F472B6'
|
const pink400 = '#F472B6'
|
||||||
const indigo300 = '#A5B4FC'
|
const indigo300 = '#A5B4FC'
|
||||||
const indigo900 = '#312E81'
|
const indigo900 = '#312E81'
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="relative h-full bg-ch-gray-800">
|
||||||
className="relative h-full"
|
{state.isLoading && <Loading />}
|
||||||
style={{ backgroundColor: openSCADDeepOceanThemeBackground }}
|
|
||||||
>
|
|
||||||
{state.isLoading && (
|
|
||||||
<div className="inset-0 absolute flex items-center justify-center">
|
|
||||||
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{image && (
|
{image && (
|
||||||
<div
|
<div
|
||||||
className={`absolute inset-0 transition-opacity duration-500 ${
|
className={`absolute inset-0 transition-opacity duration-500 ${
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex">
|
<div className="h-full flex">
|
||||||
<div className="w-16 bg-gray-700 flex-shrink-0">
|
<div className="w-16 bg-ch-gray-700 flex-shrink-0">
|
||||||
<IdeSideBar />
|
<IdeSideBar />
|
||||||
</div>
|
</div>
|
||||||
<div className="h-full flex flex-grow flex-col">
|
<div className="h-full flex flex-grow flex-col">
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ const PanelToolbar = ({ panelName }: { panelName: string }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="absolute top-0 right-0 flex items-center h-9">
|
<div className="absolute top-0 right-0 flex items-center h-9">
|
||||||
<button
|
<button
|
||||||
className="bg-gray-500 text-gray-300 px-3 rounded-bl-lg h-full cursor-not-allowed"
|
className="bg-ch-gray-760 text-ch-gray-300 px-3 rounded-bl-lg h-full cursor-not-allowed"
|
||||||
aria-label={`${panelName} settings`}
|
aria-label={`${panelName} settings`}
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
<Svg name="gear" className="w-7 p-px" />
|
<Svg name="gear" className="w-7 p-px" />
|
||||||
</button>
|
</button>
|
||||||
{mosaicWindowActions.connectDragSource(
|
{mosaicWindowActions.connectDragSource(
|
||||||
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
<div className=" text-ch-gray-760 bg-ch-gray-300 cursor-grab px-2 h-full flex items-center">
|
||||||
<Svg name="drag-grid" className="w-4 p-px" />
|
<Svg name="drag-grid" className="w-4 p-px" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ type SvgNames =
|
|||||||
| 'logout'
|
| 'logout'
|
||||||
| 'mac-cmd-key'
|
| 'mac-cmd-key'
|
||||||
| 'pencil'
|
| 'pencil'
|
||||||
|
| 'photograph'
|
||||||
| 'plus'
|
| 'plus'
|
||||||
| 'plus-circle'
|
| 'plus-circle'
|
||||||
| 'refresh'
|
| 'refresh'
|
||||||
| 'save'
|
| 'save'
|
||||||
|
| 'share'
|
||||||
| 'terminal'
|
| 'terminal'
|
||||||
| 'trash'
|
| 'trash'
|
||||||
| 'x'
|
| 'x'
|
||||||
@@ -345,6 +347,22 @@ const Svg = ({
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
photograph: (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="h-6 w-6"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
plus: (
|
plus: (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -400,6 +418,14 @@ const Svg = ({
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
share: (
|
||||||
|
<svg viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M14.4224 0.355957L21.9999 7.44407L14.4224 14.4997V10.1184C-0.365345 10.1184 0.407131 17.6436 0.407131 17.6436C0.407131 17.6436 -3.73829 4.71837 14.4224 4.71837L14.4224 0.355957Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
terminal: (
|
terminal: (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
|
|||||||
|
|
||||||
export const lambdaBaseURL =
|
export const lambdaBaseURL =
|
||||||
process.env.CAD_LAMBDA_BASE_URL ||
|
process.env.CAD_LAMBDA_BASE_URL ||
|
||||||
'https://2inlbple1b.execute-api.us-east-1.amazonaws.com/prod2'
|
'https://oxt2p7ddgj.execute-api.us-east-1.amazonaws.com/prod'
|
||||||
|
|
||||||
export const stlToGeometry = (url) =>
|
export const stlToGeometry = (url) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
|
|||||||
@@ -44,10 +44,20 @@
|
|||||||
@apply list-disc;
|
@apply list-disc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cadhub-ide.mosaic-toolbar-overrides .mosaic-blueprint-theme {
|
||||||
|
background-color: #0D0D13;
|
||||||
|
}
|
||||||
|
#cadhub-ide.mosaic-toolbar-overrides .mosaic-root {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
.mosaic-toolbar-overrides .mosaic-window .mosaic-window-toolbar {
|
.mosaic-toolbar-overrides .mosaic-window .mosaic-window-toolbar {
|
||||||
/* makes the height of the toolbar based off the content inside instead of hardcoded to 30px */
|
/* makes the height of the toolbar based off the content inside instead of hardcoded to 30px */
|
||||||
height: unset;
|
height: unset;
|
||||||
}
|
}
|
||||||
|
/* used in IdeContainer component */
|
||||||
|
#cadhub-ide .mosaic-window.console .mosaic-window-body {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Used for LandingSection.js, if it's gone or these class isn't used there you can probably delete it */
|
/* Used for LandingSection.js, if it's gone or these class isn't used there you can probably delete it */
|
||||||
@@ -102,7 +112,3 @@ input.error, textarea.error {
|
|||||||
border: 1px solid red;
|
border: 1px solid red;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used in IdeContainer component */
|
|
||||||
#cadhub-ide .mosaic-window.console .mosaic-window-body {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,16 +3,46 @@ module.exports = {
|
|||||||
darkMode: false, // or 'media' or 'class'
|
darkMode: false, // or 'media' or 'class'
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
backgroundImage: () => ({
|
|
||||||
texture: `url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%236a49c3' fill-opacity='0.47' fill-rule='evenodd'/%3E%3C/svg%3E");`,
|
|
||||||
}),
|
|
||||||
animation: {
|
animation: {
|
||||||
'bounce-sm-slow': 'bounce-sm 5s linear infinite',
|
'bounce-sm-slow': 'bounce-sm 5s linear infinite',
|
||||||
'twist-sm-slow': 'twist-sm 10s infinite',
|
'twist-sm-slow': 'twist-sm 10s infinite',
|
||||||
},
|
},
|
||||||
|
backgroundImage: () => ({
|
||||||
|
texture: `url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%236a49c3' fill-opacity='0.47' fill-rule='evenodd'/%3E%3C/svg%3E");`,
|
||||||
|
}),
|
||||||
|
borderRadius: {
|
||||||
|
half: '50%',
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
'ch-gray': {
|
||||||
|
900: '#0D0D13',
|
||||||
|
800: '#1A1A1D',
|
||||||
|
750: '#222222',
|
||||||
|
760: '#232532',
|
||||||
|
700: '#2A3038',
|
||||||
|
300: '#CFCFD8',
|
||||||
|
},
|
||||||
|
'ch-purple': {
|
||||||
|
400: '#3B0480',
|
||||||
|
500: '#8732F2',
|
||||||
|
600: '#A663FA',
|
||||||
|
},
|
||||||
|
'ch-blue': {
|
||||||
|
600: '#79B2F8',
|
||||||
|
},
|
||||||
|
'ch-pink': {
|
||||||
|
800: '#93064F',
|
||||||
|
500: '#DF5CA0',
|
||||||
|
300: '#F98CC5',
|
||||||
|
},
|
||||||
|
},
|
||||||
cursor: {
|
cursor: {
|
||||||
grab: 'grab'
|
grab: 'grab'
|
||||||
},
|
},
|
||||||
|
fontFamily: {
|
||||||
|
'ropa-sans': ['Ropa Sans', 'Arial', 'sans-serif'],
|
||||||
|
roboto: ['Roboto', 'Arial', 'sans-serif'],
|
||||||
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
'bounce-sm': {
|
'bounce-sm': {
|
||||||
'0%, 100%': {
|
'0%, 100%': {
|
||||||
@@ -41,16 +71,9 @@ module.exports = {
|
|||||||
minHeight: {
|
minHeight: {
|
||||||
md: '28rem',
|
md: '28rem',
|
||||||
},
|
},
|
||||||
fontFamily: {
|
|
||||||
'ropa-sans': ['Ropa Sans', 'Arial', 'sans-serif'],
|
|
||||||
roboto: ['Roboto', 'Arial', 'sans-serif'],
|
|
||||||
},
|
|
||||||
skew: {
|
skew: {
|
||||||
'-20': '-20deg',
|
'-20': '-20deg',
|
||||||
},
|
},
|
||||||
borderRadius: {
|
|
||||||
half: '50%',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
variants: {},
|
variants: {},
|
||||||
|
|||||||
Reference in New Issue
Block a user