From 38b905e180a1ff2060442feb4c13378e900255a7 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Tue, 28 Sep 2021 06:05:22 +1000 Subject: [PATCH] Change how customizer params are applied (#529) * Only send customizer params when it's open * Add customizer reset button and have two modes of customizer vs not depending of if the customizer is open. * Remove re-render on customizer open/close in project profile --- .../src/components/Customizer/Customizer.tsx | 33 +++++++++++++++---- app/web/src/components/EncodedUrl/helpers.ts | 9 +++-- .../src/components/IdeWrapper/useRender.ts | 4 +-- .../ProjectProfile/ProjectProfile.tsx | 5 ++- app/web/src/helpers/hooks/useIdeState.ts | 30 ++++++++++++++--- 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/app/web/src/components/Customizer/Customizer.tsx b/app/web/src/components/Customizer/Customizer.tsx index 733a444..8ff5654 100644 --- a/app/web/src/components/Customizer/Customizer.tsx +++ b/app/web/src/components/Customizer/Customizer.tsx @@ -14,12 +14,23 @@ import { } from './customizerConverter' const Customizer = () => { - const [open, setOpen] = React.useState(false) const [shouldLiveUpdate, setShouldLiveUpdate] = React.useState(false) const { state, thunkDispatch } = useIdeContext() + const isOpen = state.isCustomizerOpen const customizerParams = state?.customizerParams const currentParameters = state?.currentParameters || {} const handleRender = useRender() + const toggleOpen = () => { + thunkDispatch({ type: 'setCustomizerOpenState', payload: !isOpen }) + if (state.viewerContext === 'ide') { + // don't re-render on open/close in the project profile + setTimeout(() => handleRender()) + } + } + const handleReset = () => { + thunkDispatch({ type: 'resetCustomizer' }) + setTimeout(() => handleRender(true)) + } const updateCustomizerParam = (paramName: string, paramValue: any) => { const payload = { @@ -33,20 +44,20 @@ const Customizer = () => { return (
-
Parameters
- {open && ( + {isOpen && ( <>
Auto Update
@@ -66,11 +77,17 @@ const Customizer = () => { } inline-block w-4 h-4 transform bg-white rounded-full`} /> +
-
+
{customizerParams.map((param, index) => { const otherProps = { diff --git a/app/web/src/components/EncodedUrl/helpers.ts b/app/web/src/components/EncodedUrl/helpers.ts index e02eae8..88a6c93 100644 --- a/app/web/src/components/EncodedUrl/helpers.ts +++ b/app/web/src/components/EncodedUrl/helpers.ts @@ -5,6 +5,7 @@ import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { useRender } from 'src/components/IdeWrapper/useRender' import { encode, decode } from 'src/helpers/compress' import { isBrowser } from '@redwoodjs/prerender/browserUtils' +import type { State } from 'src/helpers/hooks/useIdeState' const scriptKey = 'encoded_script' const scriptKeyV2 = 'encoded_script_v2' @@ -32,13 +33,17 @@ export function makeExternalUrl(resourceUrl: string): string { }#${fetchText}=${prepareDecodedUrl(resourceUrl)}` } -export function useIdeInit(cadPackage: string, code = '') { +export function useIdeInit( + cadPackage: State['ideType'], + code = '', + viewerContext: State['viewerContext'] = 'ide' +) { const { thunkDispatch } = useIdeContext() const handleRender = useRender() useEffect(() => { thunkDispatch({ type: 'initIde', - payload: { cadPackage, code }, + payload: { cadPackage, code, viewerContext }, }) if (code) { return diff --git a/app/web/src/components/IdeWrapper/useRender.ts b/app/web/src/components/IdeWrapper/useRender.ts index 4ac6312..cec3da8 100644 --- a/app/web/src/components/IdeWrapper/useRender.ts +++ b/app/web/src/components/IdeWrapper/useRender.ts @@ -3,7 +3,7 @@ import { useIdeContext } from 'src/helpers/hooks/useIdeContext' export const useRender = () => { const { state, thunkDispatch } = useIdeContext() - return () => { + return (disableParams = false) => { thunkDispatch((dispatch, getState) => { const state = getState() dispatch({ type: 'setLoading' }) @@ -13,7 +13,7 @@ export const useRender = () => { code: state.code, viewerSize: state.viewerSize, camera: state.camera, - parameters: state.currentParameters, + parameters: disableParams ? {} : state.currentParameters, }) }) localStorage.setItem(makeCodeStoreKey(state.ideType), state.code) diff --git a/app/web/src/components/ProjectProfile/ProjectProfile.tsx b/app/web/src/components/ProjectProfile/ProjectProfile.tsx index 90e454b..75ad9d4 100644 --- a/app/web/src/components/ProjectProfile/ProjectProfile.tsx +++ b/app/web/src/components/ProjectProfile/ProjectProfile.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef, lazy, Suspense } from 'react' +import { useState, useEffect, useRef } from 'react' import { useAuth } from '@redwoodjs/auth' import { Link, navigate, routes } from '@redwoodjs/router' import Editor from 'rich-markdown-editor' @@ -15,7 +15,6 @@ import CadPackage from 'src/components/CadPackage/CadPackage' import Gravatar from 'src/components/Gravatar/Gravatar' import { useIdeInit } from 'src/components/EncodedUrl/helpers' import ProfileViewer from '../ProfileViewer/ProfileViewer' -import Svg from 'src/components/Svg/Svg' import OpenscadStaticImageMessage from 'src/components/OpenscadStaticImageMessage/OpenscadStaticImageMessage' import KeyValue from 'src/components/KeyValue/KeyValue' @@ -51,7 +50,7 @@ const ProjectProfile = ({ }) ) }, [currentUser]) - useIdeInit(project?.cadPackage, project?.code) + useIdeInit(project?.cadPackage, project?.code, 'viewer') const [newDescription, setNewDescription] = useState(project?.description) const onDescriptionChange = (description) => setNewDescription(description()) const onEditSaveClick = () => { diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts index 9a1bf56..81847ae 100644 --- a/app/web/src/helpers/hooks/useIdeState.ts +++ b/app/web/src/helpers/hooks/useIdeState.ts @@ -33,6 +33,7 @@ interface EditorModel { export interface State { ideType: 'INIT' | CadPackageType + viewerContext: 'ide' | 'viewer' ideGuide?: string consoleMessages: { type: 'message' | 'error'; message: string; time: Date }[] code: string @@ -45,6 +46,7 @@ export interface State { } customizerParams: CadhubParams[] currentParameters?: RawCustomizerParams + isCustomizerOpen: boolean layout: any camera: { dist?: number @@ -71,6 +73,7 @@ const initialLayout = { export const initialState: State = { ideType: 'INIT', + viewerContext: 'ide', consoleMessages: [ { type: 'message', message: 'Initialising', time: new Date() }, ], @@ -83,6 +86,7 @@ export const initialState: State = { quality: 'low', }, customizerParams: [], + isCustomizerOpen: false, layout: initialLayout, camera: {}, viewerSize: { width: 0, height: 0 }, @@ -103,17 +107,28 @@ const reducer = (state: State, { type, payload }): State => { '', ideType: payload.cadPackage, ideGuide: initGuideMap[payload.cadPackage], + viewerContext: payload.viewerContext, } case 'updateCode': return { ...state, code: payload } + case 'resetCustomizer': + const resetParameters = {} + state.customizerParams.forEach(({ name, initial }) => { + resetParameters[name] = initial + }) + return { + ...state, + currentParameters: resetParameters, + } case 'healthyRender': - const customizerParams: CadhubParams[] = payload.customizerParams || [] const currentParameters = {} + + const customizerParams: CadhubParams[] = payload.customizerParams || [] customizerParams.forEach((param) => { currentParameters[param.name] = - typeof state?.currentParameters?.[param.name] !== 'undefined' - ? state?.currentParameters?.[param.name] - : param.initial + typeof state?.currentParameters?.[param.name] === 'undefined' + ? param.initial + : state?.currentParameters?.[param.name] }) return { ...state, @@ -143,6 +158,11 @@ const reducer = (state: State, { type, payload }): State => { ...state, currentParameters: payload, } + case 'setCustomizerOpenState': + return { + ...state, + isCustomizerOpen: payload, + } case 'setLayout': return { ...state, @@ -292,7 +312,7 @@ export const requestRender = ({ return renderFn({ code, settings: { - parameters, + parameters: state.isCustomizerOpen ? parameters : {}, camera, viewerSize, quality,