diff --git a/app/web/src/components/Customizer/Customizer.tsx b/app/web/src/components/Customizer/Customizer.tsx index 1767897..37e8c1a 100644 --- a/app/web/src/components/Customizer/Customizer.tsx +++ b/app/web/src/components/Customizer/Customizer.tsx @@ -1,6 +1,6 @@ import { useRender } from 'src/components/IdeWrapper/useRender' import { useIdeContext } from 'src/helpers/hooks/useIdeContext' -import { genParams, getParams } from 'src/helpers/cadPackages/jscadParams' +import { genParams, getParams } from 'src/helpers/cadPackages/jsCad/jscadParams' const Customizer = () => { const [open, setOpen] = React.useState(true) diff --git a/app/web/src/components/IdeWrapper/useRender.ts b/app/web/src/components/IdeWrapper/useRender.ts index 52d233d..17824d6 100644 --- a/app/web/src/components/IdeWrapper/useRender.ts +++ b/app/web/src/components/IdeWrapper/useRender.ts @@ -1,9 +1,10 @@ import { makeCodeStoreKey, requestRender } from 'src/helpers/hooks/useIdeState' import { useIdeContext } from 'src/helpers/hooks/useIdeContext' +import type { RawCustomizerParams } from 'src/helpers/cadPackages/common' export const useRender = () => { const { state, thunkDispatch } = useIdeContext() - return (parameters) => { + return (parameters?: RawCustomizerParams) => { thunkDispatch((dispatch, getState) => { const state = getState() dispatch({ type: 'setLoading' }) diff --git a/app/web/src/helpers/cadPackages/common.ts b/app/web/src/helpers/cadPackages/common.ts index 4bdec2a..95a60c3 100644 --- a/app/web/src/helpers/cadPackages/common.ts +++ b/app/web/src/helpers/cadPackages/common.ts @@ -35,6 +35,10 @@ export interface HealthyResponse { lastParameters?: any } +export interface RawCustomizerParams { + [paramName: string]: number | string | boolean +} + export function createHealthyResponse({ date, data, diff --git a/app/web/src/helpers/cadPackages/index.ts b/app/web/src/helpers/cadPackages/index.ts index 145717e..568e9b9 100644 --- a/app/web/src/helpers/cadPackages/index.ts +++ b/app/web/src/helpers/cadPackages/index.ts @@ -3,7 +3,7 @@ import type { CadPackage } from 'src/helpers/hooks/useIdeState' import openscad from './openScadController' import cadquery from './cadQueryController' -import jscad from './jsCadController' +import jscad from './jsCad/jsCadController' export const cadPackages: { [key in CadPackage]: DefaultKernelExport } = { openscad, diff --git a/app/web/src/helpers/cadPackages/jsCadController.ts b/app/web/src/helpers/cadPackages/jsCad/jsCadController.ts similarity index 99% rename from app/web/src/helpers/cadPackages/jsCadController.ts rename to app/web/src/helpers/cadPackages/jsCad/jsCadController.ts index b0c4ddc..6cabb4a 100644 --- a/app/web/src/helpers/cadPackages/jsCadController.ts +++ b/app/web/src/helpers/cadPackages/jsCad/jsCadController.ts @@ -3,7 +3,7 @@ import { DefaultKernelExport, createUnhealthyResponse, createHealthyResponse, -} from './common' +} from '../common' import { MeshPhongMaterial, LineBasicMaterial, diff --git a/app/web/src/helpers/cadPackages/jscadParams.js b/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts similarity index 77% rename from app/web/src/helpers/cadPackages/jscadParams.js rename to app/web/src/helpers/cadPackages/jsCad/jscadParams.ts index 66e6527..b43911a 100644 --- a/app/web/src/helpers/cadPackages/jscadParams.js +++ b/app/web/src/helpers/cadPackages/jsCad/jscadParams.ts @@ -1,20 +1,25 @@ +import type { RawCustomizerParams } from '../common' + const GROUP_SELECTOR = 'DIV[type="group"]' const INPUT_SELECTOR = 'INPUT, SELECT' -function forEachInput(target, callback) { +function forEachInput( + target: HTMLElement, + callback: (e: HTMLInputElement) => void +) { target.querySelectorAll(INPUT_SELECTOR).forEach(callback) } -function forEachGroup(target, callback) { +function forEachGroup(target: HTMLElement, callback: (e: HTMLElement) => void) { target.querySelectorAll(GROUP_SELECTOR).forEach(callback) } const numeric = { number: 1, float: 1, int: 1, range: 1, slider: 1 } function applyRange(inp) { - let label = inp.previousElementSibling + const label = inp.previousElementSibling if (label && label.tagName == 'LABEL') { - let info = label.querySelector('I') + const info = label.querySelector('I') if (info) info.innerHTML = inp.value } } @@ -26,10 +31,8 @@ export function genParams( callback = undefined, buttons = ['reset', 'save', 'load', 'edit', 'link'] ) { - let funcs = { - group: function ({ name, type, caption, captions, value, min, max }) { - return '' - }, + const funcs = { + group: () => '', choice: inputChoice, radio: inputRadio, float: inputNumber, @@ -43,17 +46,8 @@ export function genParams( 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' : '' + checkbox: function ({ name, value }) { + const checkedStr = value === 'checked' || value === true ? 'checked' : '' return `` }, number: inputNumber, @@ -65,7 +59,8 @@ export function genParams( let ret = '
' for (let i = 0; i < values.length; i++) { - let checked = value == values[i] || value == captions[i] ? 'checked' : '' + const checked = + value == values[i] || value == captions[i] ? 'checked' : '' ret += `` @@ -81,7 +76,8 @@ export function genParams( }">` for (let i = 0; i < values.length; i++) { - let checked = value == values[i] || value == captions[i] ? 'selected' : '' + const checked = + value == values[i] || value == captions[i] ? 'selected' : '' ret += `` } return ret + '' @@ -93,7 +89,7 @@ export function genParams( let inputType = type if (type == 'int' || type == 'float') inputType = 'number' if (type == 'range' || type == 'slider') inputType = 'range' - var str = ` { - let { type, caption, name } = def + const { type, caption, name } = def if (storedParams[name] !== undefined) { def.value = storedParams[name] @@ -140,7 +136,7 @@ export function genParams( html += '
\n' }) - let missingKeys = Object.keys(missing) + const missingKeys = Object.keys(missing) if (missingKeys.length) console.log('missing param impl', missingKeys) function _callback(source = 'change') { @@ -148,9 +144,9 @@ export function genParams( } html += '
' - buttons.forEach((b) => { - if (typeof b === 'string') b = { id: b, name: b } - let { id, name } = b + buttons.forEach((button) => { + const { id, name } = + typeof button === 'string' ? { id: button, name: button } : button html += `` }) html += '
' @@ -158,7 +154,7 @@ export function genParams( target.innerHTML = html forEachInput(target, (inp) => { - let type = inp.type + const type = inp.type inp.addEventListener('input', function (evt) { applyRange(inp) if (inp.getAttribute('live') === '1') _callback('live') @@ -168,10 +164,9 @@ export function genParams( }) function groupClick(evt) { - var groupDiv = evt.target + let groupDiv = evt.target if (groupDiv.tagName === 'LABEL') groupDiv = groupDiv.parentNode - var closed = groupDiv.getAttribute('closed') == '1' ? '0' : '1' - var name = evt.target.getAttribute('name') + const closed = groupDiv.getAttribute('closed') == '1' ? '0' : '1' do { groupDiv.setAttribute('closed', closed) groupDiv = groupDiv.nextElementSibling @@ -184,20 +179,20 @@ export function genParams( }) } -export function getParams(target) { - let params = {} +export function getParams(target: HTMLElement): RawCustomizerParams { + const params = {} if (!target) return params forEachGroup(target, (elem) => { - let name = elem.getAttribute('name') + const name = elem.getAttribute('name') params[name] = elem.getAttribute('closed') == '1' ? 'closed' : '' }) forEachInput(target, (elem) => { - let name = elem.name - let value = elem.value + const name = elem.name + let value: RawCustomizerParams[string] = elem.value if (elem.tagName == 'INPUT') { - if (elem.type == 'checkbox') value = elem.checked + if (elem.type == 'checkbox') value = elem?.checked if (elem.type == 'range' || elem.type == 'color') applyRange(elem) } @@ -205,7 +200,7 @@ export function getParams(target) { numeric[elem.getAttribute('type')] || elem.getAttribute('numeric') == '1' ) - value = parseFloat(value || 0) + value = parseFloat(String(value || 0)) if (elem.type == 'radio' && !elem.checked) return // skip if not checked radio button