From 6221099af80f87e783339d46f31b685b0ce0f3ed Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 23 Nov 2025 18:09:38 -0500 Subject: [PATCH 1/7] working --- packages/core/repl.mjs | 1 + .../repl/components/button/action-button.jsx | 24 ++++++++++++ .../panel/ImportPrebakeScriptButton.jsx | 39 +++++++++++++++++++ website/src/repl/components/panel/Panel.jsx | 2 +- .../src/repl/components/panel/PatternsTab.jsx | 2 +- .../src/repl/components/panel/SettingsTab.jsx | 12 ++++-- website/src/repl/prebake.mjs | 11 +++++- website/src/repl/useReplContext.jsx | 11 ++++-- website/src/settings.mjs | 3 ++ 9 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 website/src/repl/components/panel/ImportPrebakeScriptButton.jsx diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index bcb70eec9..90b4fcbb8 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -147,6 +147,7 @@ export function repl({ // set pattern methods that use this repl via closure const injectPatternMethods = () => { + Pattern.prototype.p = function (id) { if (typeof id === 'string' && (id.startsWith('_') || id.endsWith('_'))) { // allows muting a pattern x with x_ or _x diff --git a/website/src/repl/components/button/action-button.jsx b/website/src/repl/components/button/action-button.jsx index d589b7bed..eb395212c 100644 --- a/website/src/repl/components/button/action-button.jsx +++ b/website/src/repl/components/button/action-button.jsx @@ -8,3 +8,27 @@ export function ActionButton({ children, label, labelIsHidden, className, ...but ); } +export function ActionInput({ label, className, ...inputProps }) { + return ( + + ); +} + +export function SpecialActionButton(props) { + const { className, ...buttonProps } = props + + return + +} +export function SpecialActionInput(props) { + const { className, ...inputProps } = props + return +} + + diff --git a/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx b/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx new file mode 100644 index 000000000..c521c527b --- /dev/null +++ b/website/src/repl/components/panel/ImportPrebakeScriptButton.jsx @@ -0,0 +1,39 @@ +import { errorLogger } from '@strudel/core'; +import { useSettings, storeStartupScript } from '../../../settings.mjs'; +import { SpecialActionInput } from '../button/action-button'; + +async function importScript(script) { + const reader = new FileReader() + reader.readAsText(script) + + reader.onload = () => { + const text = reader.result; + console.info(text) + storeStartupScript(text) + + }; + + reader.onerror = () => { + errorLogger(new Error('failed to import prebake script'), 'ImportPrebakeScriptButton') + } + +} +export function ImportPrebakeScriptButton() { + const settings = useSettings(); + + return importScript(e.target.files[0])} /> + + // return +} \ No newline at end of file diff --git a/website/src/repl/components/panel/Panel.jsx b/website/src/repl/components/panel/Panel.jsx index b26c2edef..1af859f81 100644 --- a/website/src/repl/components/panel/Panel.jsx +++ b/website/src/repl/components/panel/Panel.jsx @@ -127,7 +127,7 @@ function PanelContent({ context, tab }) { case tabNames.reference: return ; case tabNames.settings: - return ; + return ; case tabNames.files: return ; default: diff --git a/website/src/repl/components/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx index 5e0d50e72..67585d20a 100644 --- a/website/src/repl/components/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -83,7 +83,7 @@ function UserPatterns({ context }) { const activePattern = useActivePattern(); const viewingPatternStore = useViewingPatternData(); const viewingPatternData = parseJSON(viewingPatternStore); - const { userPatterns, patternFilter, patternAutoStart } = useSettings(); + const { userPatterns, patternFilter, patternAutoStart, } = useSettings(); const viewingPatternID = viewingPatternData?.id; return (
diff --git a/website/src/repl/components/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx index 85991f55c..2c66ed1a3 100644 --- a/website/src/repl/components/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -7,6 +7,8 @@ import { AudioDeviceSelector } from './AudioDeviceSelector.jsx'; import { AudioEngineTargetSelector } from './AudioEngineTargetSelector.jsx'; import { confirmDialog } from '../../util.mjs'; import { DEFAULT_MAX_POLYPHONY, setMaxPolyphony, setMultiChannelOrbits } from '@strudel/webaudio'; +import { ActionButton, SpecialActionButton } from '../button/action-button.jsx'; +import { ImportPrebakeScriptButton } from './ImportPrebakeScriptButton.jsx'; function Checkbox({ label, value, onChange, disabled = false }) { return ( @@ -86,7 +88,7 @@ const fontFamilyOptions = { const RELOAD_MSG = 'Changing this setting requires the window to reload itself. OK?'; -export function SettingsTab({ started }) { +export function SettingsTab({ started,context }) { const { theme, keybindings, @@ -113,6 +115,7 @@ export function SettingsTab({ started }) { isTabIndentationEnabled, isMultiCursorEnabled, patternAutoStart, + startupScript, } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; @@ -204,6 +207,8 @@ export function SettingsTab({ started }) { />
+ + {/* context.editStartupScript(startupScript)}> */} Try clicking the logo in the top left! - + ); diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index 8a6ccc7e0..960771f05 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -1,14 +1,23 @@ -import { Pattern, noteToMidi, valueToMidi } from '@strudel/core'; +import { Pattern, noteToMidi, valueToMidi } from '@strudel/core'; import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio'; import { registerSamplesFromDB } from './idbutils.mjs'; import './piano.mjs'; import './files.mjs'; +import { settingsMap } from '@src/settings.mjs'; +import { evaluate } from '@strudel/transpiler'; const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; const baseCDN = 'https://strudel.b-cdn.net'; export async function prebake() { + + // const settings = settingsMap.get() + + + // const prebakeScript = settings.startupScript || ''; + // await evaluate(prebakeScript); + // https://archive.org/details/SalamanderGrandPianoV3 // License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm await Promise.all([ diff --git a/website/src/repl/useReplContext.jsx b/website/src/repl/useReplContext.jsx index ac30fe342..4e8b2b946 100644 --- a/website/src/repl/useReplContext.jsx +++ b/website/src/repl/useReplContext.jsx @@ -6,7 +6,7 @@ This program is free software: you can redistribute it and/or modify it under th import { code2hash, getPerformanceTimeSeconds, logger, silence } from '@strudel/core'; import { getDrawContext } from '@strudel/draw'; -import { transpiler } from '@strudel/transpiler'; +import { evaluate, transpiler } from '@strudel/transpiler'; import { getAudioContextCurrentTime, webaudioOutput, @@ -47,6 +47,7 @@ if (typeof window !== 'undefined') { multiChannelOrbits: parseBoolean(multiChannelOrbits), }); modulesLoading = loadModules(); + // prebakeScript = evaluate(settingsMap.get().startupScript ?? '') presets = prebake(); drawContext = getDrawContext(); clearCanvas = () => drawContext.clearRect(0, 0, drawContext.canvas.height, drawContext.canvas.width); @@ -63,11 +64,10 @@ async function getModule(name) { const initialCode = `// LOADING`; export function useReplContext() { - const { isSyncEnabled, audioEngineTarget } = useSettings(); + const { isSyncEnabled, audioEngineTarget, startupScript } = useSettings(); const shouldUseWebaudio = audioEngineTarget !== audioEngineTargets.osc; const defaultOutput = shouldUseWebaudio ? webaudioOutput : superdirtOutput; const getTime = shouldUseWebaudio ? getAudioContextCurrentTime : getPerformanceTimeSeconds; - const init = useCallback(() => { const drawTime = [-2, 2]; const drawContext = getDrawContext(); @@ -84,7 +84,9 @@ export function useReplContext() { pattern: silence, drawTime, drawContext, - prebake: async () => Promise.all([modulesLoading, presets]), + prebake: async () => Promise.all([modulesLoading, presets,]).then(() => { + return evaluate(startupScript ?? '') + }), onUpdateState: (state) => { setReplState({ ...state }); }, @@ -200,6 +202,7 @@ export function useReplContext() { } }; + const handleEvaluate = () => { editorRef.current.evaluate(); }; diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 7c62b0ded..1fff439be 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -45,6 +45,7 @@ export const defaultSettings = { isPanelOpen: true, togglePanelTrigger: 'click', //click | hover userPatterns: '{}', + startupScript: '//edit this script to run code on startup\n', audioEngineTarget: audioEngineTargets.webaudio, isButtonRowHidden: false, isCSSAnimationDisabled: false, @@ -108,6 +109,8 @@ export const setActiveFooter = (tab) => settingsMap.setKey('activeFooter', tab); export const setPanelPinned = (bool) => settingsMap.setKey('isPanelPinned', bool); export const setIsPanelOpened = (bool) => settingsMap.setKey('isPanelOpen', bool); +export const storeStartupScript = (script) => settingsMap.setKey('startupScript', script); + export const setIsZen = (active) => settingsMap.setKey('isZen', !!active); const patternSetting = (key) => From d5dfbd7aa4d4236bdf143b94b7abddf7a9fe93c5 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sun, 23 Nov 2025 18:45:13 -0500 Subject: [PATCH 2/7] cleanup --- packages/core/repl.mjs | 1 - .../repl/components/button/action-button.jsx | 45 ++++++++++------- .../panel/ImportPrebakeScriptButton.jsx | 48 ++++++++----------- website/src/repl/components/panel/Panel.jsx | 2 +- .../src/repl/components/panel/PatternsTab.jsx | 2 +- .../src/repl/components/panel/SettingsTab.jsx | 3 +- website/src/repl/prebake.mjs | 4 +- website/src/repl/useReplContext.jsx | 8 ++-- 8 files changed, 54 insertions(+), 59 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 90b4fcbb8..bcb70eec9 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -147,7 +147,6 @@ export function repl({ // set pattern methods that use this repl via closure const injectPatternMethods = () => { - Pattern.prototype.p = function (id) { if (typeof id === 'string' && (id.startsWith('_') || id.endsWith('_'))) { // allows muting a pattern x with x_ or _x diff --git a/website/src/repl/components/button/action-button.jsx b/website/src/repl/components/button/action-button.jsx index eb395212c..7364d2af0 100644 --- a/website/src/repl/components/button/action-button.jsx +++ b/website/src/repl/components/button/action-button.jsx @@ -8,27 +8,36 @@ export function ActionButton({ children, label, labelIsHidden, className, ...but ); } -export function ActionInput({ label, className, ...inputProps }) { + +export function SpecialActionButton(props) { + const { className, ...buttonProps } = props; + return ( -