From d3b6aefbc731e6218c8212c30f6e30bea6156b23 Mon Sep 17 00:00:00 2001 From: Jared Johnson Date: Sun, 28 Jun 2026 13:02:57 -0400 Subject: [PATCH 1/4] conditionally debounce based on the last render time and add a reset all button --- site/src/App.tsx | 56 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/site/src/App.tsx b/site/src/App.tsx index 39cba2fee..1967f97fd 100644 --- a/site/src/App.tsx +++ b/site/src/App.tsx @@ -95,9 +95,23 @@ export default function App() { const width = config.layout?.type === 'standard' ? (config.layout.width ?? 900) : 900; const notationFont = config.fonts?.notation?.family ?? 'Bravura'; - const reset = ( - key: 'noteSpacing' | 'softmaxFactor' | 'systemSpacing' | 'maxSystemFill', - ) => setConfig(({ [key]: _, ...rest }) => rest); + const resetKeys = [ + 'noteSpacing', + 'softmaxFactor', + 'systemSpacing', + 'maxSystemFill', + ] as const; + const reset = (key: (typeof resetKeys)[number]) => + setConfig(({ [key]: _, ...rest }) => rest); + const canReset = resetKeys.some((k) => config[k] !== undefined); + const resetAll = () => + setConfig((c) => { + const next = { ...c }; + for (const k of resetKeys) { + delete next[k]; + } + return next; + }); // `config` stays live so the sliders/reset respond instantly; `renderConfig` lags // behind it by the debounce so dragging a slider re-renders once it settles, not on @@ -109,13 +123,20 @@ export default function App() { skipConfigDebounce.current = false; return; } + // If the last render was fast, apply config changes immediately; only debounce + // once renders get slow enough to lag the sliders. + if (renderMs != null && renderMs <= 50) { + setRenderConfig(config); + setDebouncing(false); + return; + } setDebouncing(true); const t = setTimeout(() => { setRenderConfig(config); setDebouncing(false); }, 500); return () => clearTimeout(t); - }, [config]); + }, [config, renderMs]); useEffect(() => { const canvas = canvasRef.current; @@ -216,6 +237,13 @@ export default function App() { setDebouncing(false); return; } + // If the last render was fast, just render on every keystroke; only debounce + // once renders get slow enough to lag typing. + if (renderMs != null && renderMs <= 50) { + setDebouncing(false); + setInput(value); + return; + } // Spinner shows while we wait out the typing, then render the settled text. setDebouncing(true); debounceRef.current = setTimeout(() => { @@ -369,9 +397,23 @@ export default function App() {
- - Config - +
+ + Config + + +
+

+ With only a single system, some controls (e.g. system spacing + and max system fill) won't have a visible effect. +