diff --git a/app/web/src/helpers/cadPackages/common.ts b/app/web/src/helpers/cadPackages/common.ts
index 5dab46d..4bdec2a 100644
--- a/app/web/src/helpers/cadPackages/common.ts
+++ b/app/web/src/helpers/cadPackages/common.ts
@@ -12,7 +12,7 @@ export const stlToGeometry = (url) =>
export interface RenderArgs {
code: State['code']
- parameters: any,
+ parameters: any
settings: {
camera: State['camera']
viewerSize: State['viewerSize']
@@ -42,7 +42,7 @@ export function createHealthyResponse({
type,
customizerParams,
lastParameters,
- }: {
+}: {
date: Date
data: any
consoleMessage: string
diff --git a/app/web/src/helpers/cadPackages/jsCadController.ts b/app/web/src/helpers/cadPackages/jsCadController.ts
index 5be10d1..b0c4ddc 100644
--- a/app/web/src/helpers/cadPackages/jsCadController.ts
+++ b/app/web/src/helpers/cadPackages/jsCadController.ts
@@ -86,7 +86,9 @@ export const render: DefaultKernelExport['render'] = async ({
settings,
}: RenderArgs) => {
if (!scriptWorker) {
- console.trace('************************** creating new worker ************************')
+ console.trace(
+ '************************** creating new worker ************************'
+ )
const baseURI = document.baseURI.toString()
const script = `let baseURI = '${baseURI}'
importScripts(new URL('${scriptUrl}',baseURI))
@@ -127,14 +129,14 @@ export const render: DefaultKernelExport['render'] = async ({
scriptWorker.postMessage({ action: 'init', baseURI, alias: [] })
}
- if(parameters){
+ if (parameters) {
// we are not evaluating code, but reacting to parameters change
scriptWorker.postMessage({
action: 'updateParams',
worker: 'script',
params: parameters,
})
- }else{
+ } else {
scriptWorker.postMessage({
action: 'runScript',
worker: 'script',
@@ -154,7 +156,7 @@ export const render: DefaultKernelExport['render'] = async ({
await waitResult
resolveReference = null
- if(parameters) delete response.customizerParams
+ if (parameters) delete response.customizerParams
return response
}
diff --git a/app/web/src/helpers/cadPackages/jscadParams.js b/app/web/src/helpers/cadPackages/jscadParams.js
index bd1e23a..66e6527 100644
--- a/app/web/src/helpers/cadPackages/jscadParams.js
+++ b/app/web/src/helpers/cadPackages/jscadParams.js
@@ -1,192 +1,215 @@
const GROUP_SELECTOR = 'DIV[type="group"]'
const INPUT_SELECTOR = 'INPUT, SELECT'
-function forEachInput(target, callback){
- target.querySelectorAll(INPUT_SELECTOR).forEach(callback)
+function forEachInput(target, callback) {
+ target.querySelectorAll(INPUT_SELECTOR).forEach(callback)
}
-function forEachGroup(target, callback){
- target.querySelectorAll(GROUP_SELECTOR).forEach(callback)
+function forEachGroup(target, callback) {
+ target.querySelectorAll(GROUP_SELECTOR).forEach(callback)
}
-const numeric = {number:1, float:1, int:1, range:1, slider:1}
+const numeric = { number: 1, float: 1, int: 1, range: 1, slider: 1 }
-function applyRange(inp){
- let label = inp.previousElementSibling
- if(label && label.tagName == 'LABEL'){
- let info = label.querySelector('I')
- if(info) info.innerHTML = inp.value
+function applyRange(inp) {
+ let label = inp.previousElementSibling
+ if (label && label.tagName == 'LABEL') {
+ let info = label.querySelector('I')
+ if (info) info.innerHTML = inp.value
+ }
+}
+
+export function genParams(
+ defs,
+ target,
+ storedParams = {},
+ callback = undefined,
+ buttons = ['reset', 'save', 'load', 'edit', 'link']
+) {
+ let funcs = {
+ group: function ({ name, type, caption, captions, value, min, max }) {
+ return ''
+ },
+ choice: inputChoice,
+ radio: inputRadio,
+ float: inputNumber,
+ range: inputNumber,
+ slider: inputNumber,
+ int: inputNumber,
+ text: inputNumber,
+ url: inputNumber,
+ email: inputNumber,
+ date: inputNumber,
+ password: inputNumber,
+ color: inputNumber,
+ // TODO radio similar options as choice
+ checkbox: function ({
+ name,
+ type,
+ caption,
+ captions,
+ value,
+ checked,
+ min,
+ max,
+ }) {
+ let checkedStr = value === 'checked' || value === true ? 'checked' : ''
+ return `
`
+ },
+ number: inputNumber,
+ }
+
+ function inputRadio({ name, type, captions, value, values }) {
+ if (!captions) captions = values
+
+ let ret = '
'
+
+ for (let i = 0; i < values.length; i++) {
+ let checked = value == values[i] || value == captions[i] ? 'checked' : ''
+ ret += ` ${captions[i]} `
}
-}
+ return ret + '
'
+ }
-export function genParams(defs, target, storedParams={}, callback=undefined, buttons=['reset','save','load','edit','link']){
+ function inputChoice({ name, type, captions, value, values }) {
+ if (!captions) captions = values
- let funcs = {
- group:function({name,type, caption, captions, value, min,max}){
- return ''
- },
- choice:inputChoice,
- radio:inputRadio,
- float: inputNumber,
- range: inputNumber,
- slider: inputNumber,
- int: inputNumber,
- text: inputNumber,
- url: inputNumber,
- email: inputNumber,
- date: inputNumber,
- password: inputNumber,
- color: inputNumber,
- // TODO radio similar options as choice
- checkbox :function({name,type, caption, captions, value, checked, min,max}){
- let checkedStr = (value === 'checked' || value === true) ? 'checked':''
- return `
`
- },
- number: inputNumber,
- }
+ let ret = `
`
- function inputRadio({name, type, captions, value, values}){
- if(!captions) captions = values
+ for (let i = 0; i < values.length; i++) {
+ let checked = value == values[i] || value == captions[i] ? 'selected' : ''
+ ret += `${captions[i]} `
+ }
+ return ret + ' '
+ }
- let ret = '
'
+ function inputNumber(def) {
+ let { name, type, value, min, max, step, placeholder, live } = def
+ if (value === null || value === undefined) value = numeric[type] ? 0 : ''
+ let inputType = type
+ if (type == 'int' || type == 'float') inputType = 'number'
+ if (type == 'range' || type == 'slider') inputType = 'range'
+ var str = ` '
+ }
- for(let i =0; i ${captions[i]}`
- }
- return ret +'
'
- }
-
- function inputChoice({name, type, captions, value, values}){
- if(!captions) captions = values
+ let html = ''
+ let closed = false
+ let missing = {}
- let ret = `
`
+ defs.forEach((def) => {
+ let { type, caption, name } = def
- for(let i =0; i${captions[i]}`
- }
- return ret + ' '
- }
+ if (storedParams[name] !== undefined) {
+ def.value = storedParams[name]
+ } else {
+ def.value = def.initial || def['default'] || def.checked
+ }
- function inputNumber(def){
- let {name,type, value, min,max, step, placeholder, live} = def
- if(value === null || value === undefined) value = numeric[type] ? 0:'';
- let inputType = type
- if(type == 'int' || type=='float') inputType = 'number'
- if(type == 'range' || type=='slider') inputType = 'range'
- var str = `
';
- }
+ if (type == 'group') {
+ closed = def.value == 'closed'
+ }
+ def.closed = closed
- let html = '';
- let closed = false
- let missing = {}
+ html += `
\n'
+ })
- let missingKeys = Object.keys(missing)
- if(missingKeys.length) console.log('missing param impl',missingKeys);
+ let missingKeys = Object.keys(missing)
+ if (missingKeys.length) console.log('missing param impl', missingKeys)
- function _callback(source='change'){
- if(callback) callback(getParams(target), source)
- }
+ function _callback(source = 'change') {
+ if (callback) callback(getParams(target), source)
+ }
- html +='
'
+ html += '
'
- target.innerHTML = html
+ target.innerHTML = html
- forEachInput(target, inp=>{
- let type = inp.type
- inp.addEventListener('input', function(evt){
- applyRange(inp)
- if(inp.getAttribute('live') === '1') _callback('live');
- })
- if(inp.getAttribute('live') !== '1') inp.addEventListener('change', _callback)
-
- })
-
- function groupClick(evt){
- var groupDiv = evt.target
- if(groupDiv.tagName === 'LABEL') groupDiv = groupDiv.parentNode
- var closed = (groupDiv.getAttribute('closed') == '1') ? '0':'1'
- var name = evt.target.getAttribute('name')
- do{
- groupDiv.setAttribute('closed', closed)
- groupDiv = groupDiv.nextElementSibling
- }while(groupDiv && groupDiv.getAttribute('type') != 'group')
- _callback('group')
- }
-
- forEachGroup(target, div=>{
- div.onclick=groupClick
- })
-}
-
-export function getParams(target){
- let params = {}
- if(!target) return params
-
- forEachGroup(target,elem=>{
- let name = elem.getAttribute('name')
- params[name] = (elem.getAttribute('closed') == '1') ? 'closed':''
+ forEachInput(target, (inp) => {
+ let type = inp.type
+ inp.addEventListener('input', function (evt) {
+ applyRange(inp)
+ if (inp.getAttribute('live') === '1') _callback('live')
})
+ if (inp.getAttribute('live') !== '1')
+ inp.addEventListener('change', _callback)
+ })
- forEachInput(target,elem=>{
- let name = elem.name
- let value = elem.value
- if(elem.tagName == 'INPUT'){
- if(elem.type == 'checkbox') value = elem.checked
- if(elem.type == 'range' || elem.type == 'color') applyRange(elem)
- }
+ function groupClick(evt) {
+ var groupDiv = evt.target
+ if (groupDiv.tagName === 'LABEL') groupDiv = groupDiv.parentNode
+ var closed = groupDiv.getAttribute('closed') == '1' ? '0' : '1'
+ var name = evt.target.getAttribute('name')
+ do {
+ groupDiv.setAttribute('closed', closed)
+ groupDiv = groupDiv.nextElementSibling
+ } while (groupDiv && groupDiv.getAttribute('type') != 'group')
+ _callback('group')
+ }
- if(numeric[elem.getAttribute('type')] || elem.getAttribute('numeric') == '1') value = parseFloat(value || 0)
-
- if(elem.type == 'radio' && !elem.checked) return // skip if not checked radio button
-
- params[name] = value
- })
- return params;
+ forEachGroup(target, (div) => {
+ div.onclick = groupClick
+ })
}
+export function getParams(target) {
+ let params = {}
+ if (!target) return params
+
+ forEachGroup(target, (elem) => {
+ let name = elem.getAttribute('name')
+ params[name] = elem.getAttribute('closed') == '1' ? 'closed' : ''
+ })
+
+ forEachInput(target, (elem) => {
+ let name = elem.name
+ let value = elem.value
+ if (elem.tagName == 'INPUT') {
+ if (elem.type == 'checkbox') value = elem.checked
+ if (elem.type == 'range' || elem.type == 'color') applyRange(elem)
+ }
+
+ if (
+ numeric[elem.getAttribute('type')] ||
+ elem.getAttribute('numeric') == '1'
+ )
+ value = parseFloat(value || 0)
+
+ if (elem.type == 'radio' && !elem.checked) return // skip if not checked radio button
+
+ params[name] = value
+ })
+ return params
+}
diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts
index d4f5200..2de05d4 100644
--- a/app/web/src/helpers/hooks/useIdeState.ts
+++ b/app/web/src/helpers/hooks/useIdeState.ts
@@ -180,7 +180,8 @@ export const useIdeState = (): [State, (actionOrThunk: any) => any] => {
...state.objectData,
type: payload.objectData?.type,
data: payload.objectData?.data,
- customizerParams: payload.customizerParams || state.objectData.customizerParams,
+ customizerParams:
+ payload.customizerParams || state.objectData.customizerParams,
lastParameters: payload.lastParameters,
},
consoleMessages: payload.message
@@ -246,7 +247,7 @@ export const useIdeState = (): [State, (actionOrThunk: any) => any] => {
interface RequestRenderArgs {
state: State
dispatch: any
- parameters: any,
+ parameters: any
code: State['code']
camera: State['camera']
viewerSize: State['viewerSize']
@@ -280,26 +281,28 @@ export const requestRender = ({
quality,
},
})
- .then(({ objectData, message, status, customizerParams, lastParameters }) => {
- if (status === 'error') {
- dispatch({
- type: 'errorRender',
- payload: { message },
- })
- } else {
- dispatch({
- type: 'healthyRender',
- payload: {
- objectData,
- message,
- lastRunCode: code,
- customizerParams,
- lastParameters,
- },
- })
- return objectData
+ .then(
+ ({ objectData, message, status, customizerParams, lastParameters }) => {
+ if (status === 'error') {
+ dispatch({
+ type: 'errorRender',
+ payload: { message },
+ })
+ } else {
+ dispatch({
+ type: 'healthyRender',
+ payload: {
+ objectData,
+ message,
+ lastRunCode: code,
+ customizerParams,
+ lastParameters,
+ },
+ })
+ return objectData
+ }
}
- })
+ )
.catch(() => dispatch({ type: 'resetLoading' })) // TODO should probably display something to the user here
}
}