This commit is contained in:
Jade (Rose) Rowland 2025-11-23 18:45:13 -05:00
parent 6221099af8
commit d5dfbd7aa4
8 changed files with 54 additions and 59 deletions

View file

@ -147,7 +147,6 @@ export function repl({
// set pattern methods that use this repl via closure // set pattern methods that use this repl via closure
const injectPatternMethods = () => { const injectPatternMethods = () => {
Pattern.prototype.p = function (id) { Pattern.prototype.p = function (id) {
if (typeof id === 'string' && (id.startsWith('_') || id.endsWith('_'))) { if (typeof id === 'string' && (id.startsWith('_') || id.endsWith('_'))) {
// allows muting a pattern x with x_ or _x // allows muting a pattern x with x_ or _x

View file

@ -8,27 +8,36 @@ export function ActionButton({ children, label, labelIsHidden, className, ...but
</button> </button>
); );
} }
export function ActionInput({ label, className, ...inputProps }) {
export function SpecialActionButton(props) {
const { className, ...buttonProps } = props;
return ( return (
<label className={cx("hover:opacity-50 cursor-pointer text-nowrap w-fit", className)}> <ActionButton
<input {...buttonProps}
style={{ display: 'none' }} className={cx('bg-background p-2 max-w-[300px] rounded-md hover:opacity-50', className)}
{...inputProps} />
/> );
{label} }
export function ActionInput({ label, className, ...props }) {
return (
<label className={cx('inline-flex items-center cursor-pointer', className)}>
<input {...props} className="sr-only peer" />
<span className="inline-flex items-center transition-opacity peer-hover:opacity-60 peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500">
{label}
</span>
</label> </label>
); );
} }
export function SpecialActionButton(props) { export function SpecialActionInput({ className, ...props }) {
const { className, ...buttonProps } = props return (
<ActionInput
return <ActionButton {...buttonProps} className={cx("bg-background p-2 max-w-[300px] rounded-md hover:opacity-50", className)} /> {...props}
className={className}
label={<span className="bg-background p-2 max-w-[300px] rounded-md">{props.label}</span>}
/>
);
} }
export function SpecialActionInput(props) {
const { className, ...inputProps } = props
return <ActionInput {...inputProps} className={cx("bg-background p-2 max-w-[300px] rounded-md hover:opacity-50", className)} />
}

View file

@ -3,37 +3,27 @@ import { useSettings, storeStartupScript } from '../../../settings.mjs';
import { SpecialActionInput } from '../button/action-button'; import { SpecialActionInput } from '../button/action-button';
async function importScript(script) { async function importScript(script) {
const reader = new FileReader() const reader = new FileReader();
reader.readAsText(script) reader.readAsText(script);
reader.onload = () => { reader.onload = () => {
const text = reader.result; const text = reader.result;
console.info(text) storeStartupScript(text);
storeStartupScript(text) };
};
reader.onerror = () => {
errorLogger(new Error('failed to import prebake script'), 'ImportPrebakeScriptButton')
}
reader.onerror = () => {
errorLogger(new Error('failed to import prebake script'), 'importScript');
};
} }
export function ImportPrebakeScriptButton() { export function ImportPrebakeScriptButton() {
const settings = useSettings(); const settings = useSettings();
return <SpecialActionInput type="file" return (
label="import prebake script" <SpecialActionInput
accept=".strudel, .txt" type="file"
onChange={(e) => importScript(e.target.files[0])} /> label="import prebake script"
accept=".strudel"
// return <label className="hover:opacity-50 cursor-pointer"> onChange={(e) => importScript(e.target.files[0])}
// <input />
// style={{ display: 'none' }} );
// type="file" }
// // multiple
// accept=".strudel, .txt"
// onChange={(e) => importScript(e.target.files[0])}
// />
// import prebake script
// </label>
}

View file

@ -127,7 +127,7 @@ function PanelContent({ context, tab }) {
case tabNames.reference: case tabNames.reference:
return <Reference />; return <Reference />;
case tabNames.settings: case tabNames.settings:
return <SettingsTab started={context.started} context={context} />; return <SettingsTab started={context.started} />;
case tabNames.files: case tabNames.files:
return <FilesTab />; return <FilesTab />;
default: default:

View file

@ -83,7 +83,7 @@ function UserPatterns({ context }) {
const activePattern = useActivePattern(); const activePattern = useActivePattern();
const viewingPatternStore = useViewingPatternData(); const viewingPatternStore = useViewingPatternData();
const viewingPatternData = parseJSON(viewingPatternStore); const viewingPatternData = parseJSON(viewingPatternStore);
const { userPatterns, patternFilter, patternAutoStart, } = useSettings(); const { userPatterns, patternFilter, patternAutoStart } = useSettings();
const viewingPatternID = viewingPatternData?.id; const viewingPatternID = viewingPatternData?.id;
return ( return (
<div className="flex flex-col gap-2 flex-grow overflow-hidden h-full pb-2 "> <div className="flex flex-col gap-2 flex-grow overflow-hidden h-full pb-2 ">

View file

@ -88,7 +88,7 @@ const fontFamilyOptions = {
const RELOAD_MSG = 'Changing this setting requires the window to reload itself. OK?'; const RELOAD_MSG = 'Changing this setting requires the window to reload itself. OK?';
export function SettingsTab({ started,context }) { export function SettingsTab({ started }) {
const { const {
theme, theme,
keybindings, keybindings,
@ -208,7 +208,6 @@ export function SettingsTab({ started,context }) {
</FormItem> </FormItem>
</div> </div>
<ImportPrebakeScriptButton /> <ImportPrebakeScriptButton />
{/* <SpecialActionButton label="edit startup script" onClick={() => context.editStartupScript(startupScript)}></SpecialActionButton> */}
<FormItem label="Keybindings"> <FormItem label="Keybindings">
<ButtonGroup <ButtonGroup
value={keybindings} value={keybindings}

View file

@ -1,4 +1,4 @@
import { Pattern, noteToMidi, valueToMidi } from '@strudel/core'; import { Pattern, noteToMidi, valueToMidi } from '@strudel/core';
import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio'; import { aliasBank, registerSynthSounds, registerZZFXSounds, samples } from '@strudel/webaudio';
import { registerSamplesFromDB } from './idbutils.mjs'; import { registerSamplesFromDB } from './idbutils.mjs';
import './piano.mjs'; import './piano.mjs';
@ -11,9 +11,7 @@ const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL
const baseCDN = 'https://strudel.b-cdn.net'; const baseCDN = 'https://strudel.b-cdn.net';
export async function prebake() { export async function prebake() {
// const settings = settingsMap.get() // const settings = settingsMap.get()
// const prebakeScript = settings.startupScript || ''; // const prebakeScript = settings.startupScript || '';
// await evaluate(prebakeScript); // await evaluate(prebakeScript);

View file

@ -84,9 +84,10 @@ export function useReplContext() {
pattern: silence, pattern: silence,
drawTime, drawTime,
drawContext, drawContext,
prebake: async () => Promise.all([modulesLoading, presets,]).then(() => { prebake: async () =>
return evaluate(startupScript ?? '') Promise.all([modulesLoading, presets]).then(() => {
}), return evaluate(startupScript ?? '');
}),
onUpdateState: (state) => { onUpdateState: (state) => {
setReplState({ ...state }); setReplState({ ...state });
}, },
@ -202,7 +203,6 @@ export function useReplContext() {
} }
}; };
const handleEvaluate = () => { const handleEvaluate = () => {
editorRef.current.evaluate(); editorRef.current.evaluate();
}; };