diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx
index 384e78d3..1c45c47f 100644
--- a/website/src/repl/Repl.jsx
+++ b/website/src/repl/Repl.jsx
@@ -16,18 +16,19 @@ import {
setActivePattern,
setLatestCode,
settingsMap,
- updateUserCode,
useSettings,
getViewingPattern,
setViewingPattern,
- getNextCloneName,
+ createPatternID,
+ userPattern,
+ examplePattern,
+ getNextCloneID,
} from '../settings.mjs';
import { Header } from './Header';
import Loader from './Loader';
import { Panel } from './panel/Panel';
import { useStore } from '@nanostores/react';
import { prebake } from './prebake.mjs';
-import * as tunes from './tunes.mjs';
import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs';
import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon';
import './Repl.css';
@@ -76,22 +77,26 @@ export function Repl({ embedded = false }) {
},
afterEval: ({ code }) => {
setLatestCode(code);
- let pattern = getViewingPattern();
+ const data = { code };
+ let id = getViewingPattern();
window.location.hash = '#' + code2hash(code);
- const isExamplePattern = !!tunes[pattern];
+ const examplePatternData = examplePattern.getPatternData(id);
+ const isExamplePattern = examplePatternData != null;
if (isExamplePattern) {
- const codeHasChanged = code !== tunes[pattern];
+ const codeHasChanged = code !== examplePatternData.code;
if (codeHasChanged) {
// fork example
- pattern = getNextCloneName(pattern);
- setViewingPattern(pattern);
- updateUserCode(pattern, code);
+ id = getNextCloneID(id);
+ setViewingPattern(id);
+ userPattern.update(id, data);
}
- setActivePattern(pattern);
+ setActivePattern(id);
} else {
- setActivePattern(pattern);
- updateUserCode(pattern, code);
+ id = id == null ? createPatternID() : id;
+ setActivePattern(id);
+ setViewingPattern(id);
+ userPattern.update(id, data);
}
},
bgFill: false,
@@ -159,21 +164,25 @@ export function Repl({ embedded = false }) {
// payload = {reset?: boolean, code?: string, evaluate?: boolean, pattern?: string }
const handleUpdate = async (payload) => {
- const { reset = false, code = null, evaluate = true, pattern = null } = payload;
+ const { id, code } = payload;
+ setViewingPattern(id);
+ editorRef.current.setCode(code);
- if (reset) {
- clearCanvas();
- resetLoadedSounds();
- editorRef.current.repl.setCps(1);
- await prebake(); // declare default samples
- }
- if (code != null && pattern != null) {
- editorRef.current.setCode(code);
- setViewingPattern(pattern);
- }
- if (evaluate) {
- editorRef.current.evaluate();
- }
+ // const { reset = false, code = null, evaluate = true, pattern = null } = payload;
+
+ // if (reset) {
+ // clearCanvas();
+ // resetLoadedSounds();
+ // editorRef.current.repl.setCps(1);
+ // await prebake(); // declare default samples
+ // }
+ // if (code != null && pattern != null) {
+ // setViewingPattern(pattern);
+ // editorRef.current.setCode(code);
+ // }
+ // if (evaluate) {
+ // editorRef.current.evaluate();
+ // }
};
const handleShuffle = async () => {
// window.postMessage('strudel-shuffle');
diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx
index 70a581ad..d8ce363e 100644
--- a/website/src/repl/panel/PatternsTab.jsx
+++ b/website/src/repl/panel/PatternsTab.jsx
@@ -1,19 +1,15 @@
import { DocumentDuplicateIcon, PencilSquareIcon, TrashIcon } from '@heroicons/react/20/solid';
import {
- clearUserPatterns,
- deletePattern,
- createDuplicatePattern,
exportPatterns,
- addUserPattern,
importPatterns,
- createNewUserPattern,
- renamePattern,
useActivePattern,
useViewingPattern,
useSettings,
+ userPattern,
+ examplePattern,
} from '../../settings.mjs';
-import * as tunes from '../tunes.mjs';
+import { useMemo } from 'react';
function classNames(...classes) {
return classes.filter(Boolean).join(' ');
@@ -34,16 +30,16 @@ function PatternButton({ showOutline, onClick, label, showHiglight }) {
);
}
-function PatternButtons({ patterns, activePattern, onClick, viewingPattern }) {
+function PatternButtons({ patterns, activePattern, onClick, viewingPattern, isExample = false }) {
return (
- {Object.entries(patterns).map(([key, data]) => (
+ {Object.entries(patterns).map(([id]) => (
onClick(key, data)}
+ key={id}
+ label={id}
+ showHiglight={id === viewingPattern}
+ showOutline={id === activePattern}
+ onClick={() => onClick(id, isExample)}
/>
))}
@@ -52,20 +48,20 @@ function PatternButtons({ patterns, activePattern, onClick, viewingPattern }) {
export function PatternsTab({ context }) {
const { userPatterns } = useSettings();
+ const examplePatterns = useMemo(() => examplePattern.getAll(), []);
const activePattern = useActivePattern();
const viewingPattern = useViewingPattern();
- const onPatternClick = (pattern, data) => {
+
+ const updateCodeWindow = (id, code) => {
+ context.handleUpdate({ code, id, evaluate: false });
+ };
+ const onPatternBtnClick = (id, isExample) => {
+ const code = isExample ? examplePatterns[id].code : userPatterns[id].code;
+
// display selected pattern code in the window
- context.handleUpdate({ pattern, code: data.code, evaluate: false });
+ updateCodeWindow(id, code);
};
- const addPattern = ({ pattern, code }) => {
- addUserPattern(pattern, { code });
- context.handleUpdate({ code, pattern, evaluate: false });
- };
-
- const examplePatterns = {};
- Object.entries(tunes).forEach(([key, code]) => (examplePatterns[key] = { code }));
const isExample = examplePatterns[viewingPattern] != null;
return (
@@ -75,14 +71,27 @@ export function PatternsTab({ context }) {
{viewingPattern}
{!isExample && (
-
)}
{
- addPattern(createNewUserPattern());
+ const { id, data } = userPattern.create();
+ updateCodeWindow(id, data.code);
}}
>
new
- clearUserPatterns()}>
+ {
+ const { id, data } = userPattern.clearAll();
+ updateCodeWindow(id, data.code);
+ }}
+ >
clear