From fd0a910bfbcf9127d0f970c8475f445b94082f96 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Wed, 22 Oct 2025 19:38:22 -0400 Subject: [PATCH 1/9] Voicings JSDoc --- packages/core/controls.mjs | 53 +++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index a3ca638a..6f247180 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1750,17 +1750,58 @@ export const { semitone } = registerControl('semitone'); // TODO: synth param export const { voice } = registerControl('voice'); // voicings // https://codeberg.org/uzu/strudel/issues/506 -// chord to voice, like C Eb Fm7 G7. the symbols can be defined via addVoicings +/** + * The chord to voice + * @name chord + * @param {string | Pattern} symbols chord symbols to voice e.g., C, Eb, Fm7, G7. The symbols can be defined via addVoicings + * @example + * chord("").voicing() + **/ export const { chord } = registerControl('chord'); -// which dictionary to use for the voicings +/** + * Which dictionary to use for the voicings. This falls back to the default dictionary if not provided + * + * @name dictionary + * @param {string} dictionaryName which dictionary (having been defined with `addVoicings`) to use + * @example + * chord("Am C D F Am E Am E").dict('house').voicing + **/ export const { dictionary, dict } = registerControl('dictionary', 'dict'); -// the top note to align the voicing to, defaults to c5 +/** The top note to align the voicing to. Defaults to c5 + * + * @name anchor + * @param {string | Pattern} anchorNote the note to align the voicings to + * @example + * anchor("").chord("C").voicing() + **/ export const { anchor } = registerControl('anchor'); -// how the voicing is offset from the anchored position +/** + * Sets how the voicing is offset from the anchored position + * + * @name offset + * @param {number | Pattern} shift the amount to shift the voicing up or down + * @example + * chord("").offset("<0 1 2 3 4 5>") // alter the voicing each time + **/ export const { offset } = registerControl('offset'); -// how many octaves are voicing steps spread apart, defaults to 1 +/** + * How many octaves are voicing steps spread apart, defaults to 1 + * + * @name octaves + * @param {number | Pattern} count the number of octaves + * @example + * chord("").octaves("<2 4>").voicing() + **/ export const { octaves } = registerControl('octaves'); -// below = anchor note will be removed from the voicing, useful for melody harmonization +/** + * Remove anchor note from the voicing. Useful for melody harmonization + * + * @name mode + * @param {string | Pattern} modeName one of {below | above | duck | root} + * @example + * mode("").chord("C").voicing() + * + **/ export const { mode } = registerControl(['mode', 'anchor']); /** From a8c613b7eb46df2c3bdfa39b2930434306225cc4 Mon Sep 17 00:00:00 2001 From: Ignacio Ortega Date: Thu, 23 Oct 2025 12:45:44 +0200 Subject: [PATCH 2/9] Refactor sound stopping and triggering logic in SoundsTab component --- .../src/repl/components/panel/SoundsTab.jsx | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/website/src/repl/components/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx index 363f6b98..a9f10bf1 100644 --- a/website/src/repl/components/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -62,11 +62,9 @@ export function SoundsTab() { // stop current sound on mouseup useEvent('mouseup', () => { - const t = trigRef.current; + const ref = trigRef.current; trigRef.current = undefined; - t?.then((ref) => { - ref?.stop(getAudioContext().currentTime + 0.01); - }); + ref?.stop?.(getAudioContext().currentTime + 0.01); }); return (
@@ -124,12 +122,19 @@ export function SoundsTab() { duration: 0.5, }; soundPreviewIdx++; - const time = ctx.currentTime + 0.05; const onended = () => trigRef.current?.node?.disconnect(); - trigRef.current = Promise.resolve(onTrigger(time, params, onended)); - trigRef.current.then((ref) => { - connectToDestination(ref?.node); - }); + try { + // Pre-load the sample by calling onTrigger with a future time + // This triggers the loading but schedules playback for later + const time = ctx.currentTime + 0.5; // Give 500ms for loading + const ref = await onTrigger(time, params, onended); + trigRef.current = ref; + if (ref?.node) { + connectToDestination(ref.node); + } + } catch (err) { + console.warn('Failed to trigger sound:', err); + } }} > {' '} From 20bbda30f8aa9d8d56c9cf65c98dc51ccc78f8a2 Mon Sep 17 00:00:00 2001 From: moumar Date: Thu, 23 Oct 2025 23:15:21 +0200 Subject: [PATCH 3/9] Add setting to toggle pattern auto-start on pattern change --- website/src/repl/components/panel/PatternsTab.jsx | 12 ++++++------ website/src/repl/components/panel/SettingsTab.jsx | 6 ++++++ website/src/settings.mjs | 1 + 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 8e2b75b9..51946144 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -79,13 +79,11 @@ const updateCodeWindow = (context, patternData, reset = false) => { context.handleUpdate(patternData, reset); }; -const autoResetPatternOnChange = !isUdels(); - function UserPatterns({ context }) { const activePattern = useActivePattern(); const viewingPatternStore = useViewingPatternData(); const viewingPatternData = parseJSON(viewingPatternStore); - const { userPatterns, patternFilter } = useSettings(); + const { userPatterns, patternFilter, patternAutoStart } = useSettings(); const viewingPatternID = viewingPatternData?.id; return (
@@ -139,7 +137,7 @@ function UserPatterns({ context }) { updateCodeWindow( context, { ...userPatterns[id], collection: userPattern.collection }, - autoResetPatternOnChange, + patternAutoStart, ) } patterns={userPatterns} @@ -188,6 +186,7 @@ function FeaturedPatterns({ context }) { const examplePatterns = useExamplePatterns(); const collections = examplePatterns.collections; const patterns = collections.get(patternFilterName.featured); + const { patternAutoStart } = useSettings(); return ( { @@ -213,13 +212,14 @@ function LatestPatterns({ context }) { const examplePatterns = useExamplePatterns(); const collections = examplePatterns.collections; const patterns = collections.get(patternFilterName.public); + const { patternAutoStart } = useSettings(); return ( { - updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.public }, autoResetPatternOnChange); + updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.public }, patternAutoStart); }} paginationOnChange={async (pageNum) => { await loadAndSetPublicPatterns(pageNum - 1); diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 80daef01..c898609d 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -112,6 +112,7 @@ export function SettingsTab({ started }) { multiChannelOrbits, isTabIndentationEnabled, isMultiCursorEnabled, + patternAutoStart } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; @@ -304,6 +305,11 @@ export function SettingsTab({ started }) { onChange={(cbEvent) => settingsMap.setKey('isCSSAnimationDisabled', cbEvent.target.checked)} value={isCSSAnimationDisabled} /> + settingsMap.setKey('patternAutoStart', cbEvent.target.checked)} + value={patternAutoStart} + /> Try clicking the logo in the top left! diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 9365a6db..bbf89355 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,6 +96,7 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), + patternAutoStart: isUdels() ? false : parseBoolean(state.patternAutoStart) }; } From 1a362bd8ea640cfc250832db66255d1b95ff0db7 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Fri, 24 Oct 2025 09:19:02 -0400 Subject: [PATCH 4/9] Fix example --- packages/core/controls.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 6f247180..e317af35 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1764,7 +1764,13 @@ export const { chord } = registerControl('chord'); * @name dictionary * @param {string} dictionaryName which dictionary (having been defined with `addVoicings`) to use * @example - * chord("Am C D F Am E Am E").dict('house').voicing + * addVoicings('house', { +'': ['7 12 16', '0 7 16', '4 7 12'], +'m': ['0 3 7'] +}) +chord("") +.dict('house').anchor(66) +.voicing().room(.5) **/ export const { dictionary, dict } = registerControl('dictionary', 'dict'); /** The top note to align the voicing to. Defaults to c5 From 6d4787ee33df83f83a8ee54ae7338e4c90702e60 Mon Sep 17 00:00:00 2001 From: Jason Dufair Date: Fri, 24 Oct 2025 09:21:04 -0400 Subject: [PATCH 5/9] Test snapshot --- test/__snapshots__/examples.test.mjs.snap | 123 ++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index c39bb87b..8ab10e8e 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -840,6 +840,31 @@ exports[`runs examples > example "amp" example index 0 1`] = ` ] `; +exports[`runs examples > example "anchor" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:E2 ]", + "[ 0/1 → 1/1 | note:C3 ]", + "[ 0/1 → 1/1 | note:E3 ]", + "[ 0/1 → 1/1 | note:G3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:C3 ]", + "[ 1/1 → 2/1 | note:G3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 2/1 → 3/1 | note:E3 ]", + "[ 2/1 → 3/1 | note:C4 ]", + "[ 2/1 → 3/1 | note:E4 ]", + "[ 2/1 → 3/1 | note:G4 ]", + "[ 2/1 → 3/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:G4 ]", + "[ 3/1 → 4/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:E5 ]", + "[ 3/1 → 4/1 | note:G5 ]", +] +`; + exports[`runs examples > example "apply" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:C3 ]", @@ -1847,6 +1872,31 @@ exports[`runs examples > example "chop" example index 0 1`] = ` ] `; +exports[`runs examples > example "chord" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:A4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:E3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 2/1 → 3/1 | note:D3 ]", + "[ 2/1 → 3/1 | note:A3 ]", + "[ 2/1 → 3/1 | note:D4 ]", + "[ 2/1 → 3/1 | note:Gb4 ]", + "[ 2/1 → 3/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:F3 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:F4 ]", + "[ 3/1 → 4/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:C5 ]", +] +`; + exports[`runs examples > example "chorus" example index 0 1`] = ` [ "[ 0/1 → 1/4 | note:d s:sawtooth chorus:0.5 ]", @@ -2739,6 +2789,23 @@ exports[`runs examples > example "detune" example index 0 1`] = ` ] `; +exports[`runs examples > example "dictionary" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 room:0.5 ]", + "[ 0/1 → 1/1 | note:C4 room:0.5 ]", + "[ 0/1 → 1/1 | note:E4 room:0.5 ]", + "[ 1/1 → 2/1 | note:G3 room:0.5 ]", + "[ 1/1 → 2/1 | note:C4 room:0.5 ]", + "[ 1/1 → 2/1 | note:E4 room:0.5 ]", + "[ 2/1 → 3/1 | note:A3 room:0.5 ]", + "[ 2/1 → 3/1 | note:D4 room:0.5 ]", + "[ 2/1 → 3/1 | note:Gb4 room:0.5 ]", + "[ 3/1 → 4/1 | note:A3 room:0.5 ]", + "[ 3/1 → 4/1 | note:C4 room:0.5 ]", + "[ 3/1 → 4/1 | note:F4 room:0.5 ]", +] +`; + exports[`runs examples > example "distort" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh distort:0 ]", @@ -6496,6 +6563,28 @@ exports[`runs examples > example "miditouch" example index 0 1`] = ` ] `; +exports[`runs examples > example "mode" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:E3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:G4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:G5 ]", + "[ 1/1 → 2/1 | note:C6 ]", + "[ 1/1 → 2/1 | note:E6 ]", + "[ 2/1 → 3/1 | note:E3 ]", + "[ 2/1 → 3/1 | note:C4 ]", + "[ 2/1 → 3/1 | note:E4 ]", + "[ 2/1 → 3/1 | note:G4 ]", + "[ 3/1 → 4/1 | note:C5 ]", + "[ 3/1 → 4/1 | note:G5 ]", + "[ 3/1 → 4/1 | note:C6 ]", + "[ 3/1 → 4/1 | note:E6 ]", +] +`; + exports[`runs examples > example "morph" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh ]", @@ -6814,6 +6903,31 @@ exports[`runs examples > example "octave" example index 0 1`] = ` ] `; +exports[`runs examples > example "octaves" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | note:A3 ]", + "[ 0/1 → 1/1 | note:C4 ]", + "[ 0/1 → 1/1 | note:E4 ]", + "[ 0/1 → 1/1 | note:A4 ]", + "[ 0/1 → 1/1 | note:C5 ]", + "[ 1/1 → 2/1 | note:E3 ]", + "[ 1/1 → 2/1 | note:C4 ]", + "[ 1/1 → 2/1 | note:E4 ]", + "[ 1/1 → 2/1 | note:G4 ]", + "[ 1/1 → 2/1 | note:C5 ]", + "[ 2/1 → 3/1 | note:D3 ]", + "[ 2/1 → 3/1 | note:A3 ]", + "[ 2/1 → 3/1 | note:D4 ]", + "[ 2/1 → 3/1 | note:Gb4 ]", + "[ 2/1 → 3/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:F3 ]", + "[ 3/1 → 4/1 | note:C4 ]", + "[ 3/1 → 4/1 | note:F4 ]", + "[ 3/1 → 4/1 | note:A4 ]", + "[ 3/1 → 4/1 | note:C5 ]", +] +`; + exports[`runs examples > example "off" example index 0 1`] = ` [ "[ -5/24 ⇜ (0/1 → 1/8) | note:62 ]", @@ -6847,6 +6961,15 @@ exports[`runs examples > example "off" example index 0 1`] = ` ] `; +exports[`runs examples > example "offset" example index 0 1`] = ` +[ + "[ 0/1 → 1/1 | chord:Am offset:0 ]", + "[ 1/1 → 2/1 | chord:C offset:1 ]", + "[ 2/1 → 3/1 | chord:D offset:2 ]", + "[ 3/1 → 4/1 | chord:F offset:3 ]", +] +`; + exports[`runs examples > example "often" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:hh speed:0.5 ]", From fddf2ff2a76eb04f900f187642e6c2e978d97df9 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 26 Oct 2025 14:06:31 +0100 Subject: [PATCH 6/9] Set pattern auto-start to true by default --- website/src/settings.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/settings.mjs b/website/src/settings.mjs index bbf89355..ef074b78 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,7 +96,7 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), - patternAutoStart: isUdels() ? false : parseBoolean(state.patternAutoStart) + patternAutoStart: isUdels() ? false : state.patternAutoStart === undefined ? true : parseBoolean(state.patternAutoStart) }; } From fcd83cce5556541c4fcb72e05a2468ef902af157 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 26 Oct 2025 14:07:36 +0100 Subject: [PATCH 7/9] Re-evaluate pattern if activated --- website/src/repl/components/panel/PatternsTab.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 51946144..38b7294d 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -133,13 +133,17 @@ function UserPatterns({ context }) {
{/* {patternFilter === patternFilterName.user && ( */} + onClick={(id) => { updateCodeWindow( context, { ...userPatterns[id], collection: userPattern.collection }, patternAutoStart, ) - } + + if (context.started && activePattern === id) { + context.handleEvaluate() + } + }} patterns={userPatterns} started={context.started} activePattern={activePattern} From ee43d85f2983cad68a3dc6ae184560038053bdd4 Mon Sep 17 00:00:00 2001 From: Greg Ervin Date: Sun, 26 Oct 2025 13:31:13 -0500 Subject: [PATCH 8/9] Add stick button mappings to gamepad implementation and improve docs --- packages/gamepad/README.md | 6 ++++++ packages/gamepad/docs/gamepad.mdx | 4 ++++ packages/gamepad/gamepad.mjs | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/packages/gamepad/README.md b/packages/gamepad/README.md index 239353fb..a84177bc 100644 --- a/packages/gamepad/README.md +++ b/packages/gamepad/README.md @@ -40,6 +40,12 @@ const pattern = sequence([ - D-Pad - `up`, `down`, `left`, `right` (or `u`, `d`, `l`, `r` or uppercase) - Toggle versions: `tglUp`, `tglDown`, `tglLeft`, `tglRight`(or `tglU`, `tglD`, `tglL`, `tglR`) +- Stick Buttons + - `l3`, `r3` (or `ls`, `rs`) + - Toggle versions: `tglL3`, `tglR3` (or `tglLS`, `tglRS`) +- System Buttons + - `start`, `back` (or uppercase `START`, `BACK`) + - Toggle versions: `tglStart`, `tglBack` (or `tglSTART`, `tglBACK`) ### Analog Sticks - Left Stick diff --git a/packages/gamepad/docs/gamepad.mdx b/packages/gamepad/docs/gamepad.mdx index e2da594e..5071e3d5 100644 --- a/packages/gamepad/docs/gamepad.mdx +++ b/packages/gamepad/docs/gamepad.mdx @@ -29,6 +29,10 @@ The gamepad module provides access to buttons and analog sticks as normalized si | | Toggle versions: `tglLB`, `tglRB`, `tglLT`, `tglRT` | | D-Pad | `up`, `down`, `left`, `right` (or `u`, `d`, `l`, `r` or uppercase) | | | Toggle versions: `tglUp`, `tglDown`, `tglLeft`, `tglRight` (or `tglU`, `tglD`, `tglL`, `tglR`) | +| Stick Buttons | `l3`, 'r3' (or `ls`, `rs`) | +| | Toggle versions: `tglL3`, 'tglR3' (or `tglLs`, `tglRs`) | +| System Buttons | `start`, `back` (or uppercase `START`, `BACK`) | +| | Toggle versions: `tglStart`, `tglBack` (or `tglSTART`, `tglBACK`) | ### Analog Sticks diff --git a/packages/gamepad/gamepad.mjs b/packages/gamepad/gamepad.mjs index 7667a362..069c54af 100644 --- a/packages/gamepad/gamepad.mjs +++ b/packages/gamepad/gamepad.mjs @@ -14,6 +14,10 @@ export const buttonMap = { rt: 7, back: 8, start: 9, + l3: 10, + ls: 10, + r3: 11, + rs: 11, u: 12, up: 12, d: 13, From 809eb7132c43cb4ea6e7c22511f9d314bd403498 Mon Sep 17 00:00:00 2001 From: moumar Date: Sun, 2 Nov 2025 15:20:31 +0100 Subject: [PATCH 9/9] codeformat --- website/src/repl/components/panel/PatternsTab.jsx | 14 +++----------- website/src/repl/components/panel/SettingsTab.jsx | 2 +- website/src/settings.mjs | 6 +++++- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 38b7294d..5e0d50e7 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -134,14 +134,10 @@ function UserPatterns({ context }) { {/* {patternFilter === patternFilterName.user && ( */} { - updateCodeWindow( - context, - { ...userPatterns[id], collection: userPattern.collection }, - patternAutoStart, - ) + updateCodeWindow(context, { ...userPatterns[id], collection: userPattern.collection }, patternAutoStart); if (context.started && activePattern === id) { - context.handleEvaluate() + context.handleEvaluate(); } }} patterns={userPatterns} @@ -197,11 +193,7 @@ function FeaturedPatterns({ context }) { context={context} initialPage={featuredPageNum} patternOnClick={(id) => { - updateCodeWindow( - context, - { ...patterns[id], collection: patternFilterName.featured }, - patternAutoStart, - ); + updateCodeWindow(context, { ...patterns[id], collection: patternFilterName.featured }, patternAutoStart); }} paginationOnChange={async (pageNum) => { await loadAndSetFeaturedPatterns(pageNum - 1); diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index c898609d..85991f55 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -112,7 +112,7 @@ export function SettingsTab({ started }) { multiChannelOrbits, isTabIndentationEnabled, isMultiCursorEnabled, - patternAutoStart + patternAutoStart, } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; diff --git a/website/src/settings.mjs b/website/src/settings.mjs index ef074b78..7c62b0de 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -96,7 +96,11 @@ export function useSettings() { isPanelOpen: parseBoolean(state.isPanelOpen), userPatterns: userPatterns, multiChannelOrbits: parseBoolean(state.multiChannelOrbits), - patternAutoStart: isUdels() ? false : state.patternAutoStart === undefined ? true : parseBoolean(state.patternAutoStart) + patternAutoStart: isUdels() + ? false + : state.patternAutoStart === undefined + ? true + : parseBoolean(state.patternAutoStart), }; }