From 53160c638abfc0c2ca4301b5d3713a937b5942d6 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 29 Oct 2023 14:00:13 +0100 Subject: [PATCH] half working user pattern management --- website/src/repl/Repl.jsx | 4 +- website/src/repl/panel/Panel.jsx | 4 +- website/src/repl/panel/PatternsTab.jsx | 52 +++++++++++++++++--- website/src/settings.mjs | 67 +++++++++++++++++++++++++- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 524c7db4..7ce47c74 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -17,7 +17,7 @@ import { prebake } from './prebake.mjs'; import * as tunes from './tunes.mjs'; import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import { themes } from './themes.mjs'; -import { settingsMap, useSettings, setLatestCode } from '../settings.mjs'; +import { settingsMap, useSettings, setLatestCode, updateUserPattern } from '../settings.mjs'; import Loader from './Loader'; import { settingPatterns } from '../settings.mjs'; import { code2hash, hash2code } from './helpers.mjs'; @@ -128,6 +128,7 @@ export function Repl({ embedded = false }) { isLineWrappingEnabled, panelPosition, isZen, + activePattern, } = useSettings(); const paintOptions = useMemo(() => ({ fontFamily }), [fontFamily]); @@ -144,6 +145,7 @@ export function Repl({ embedded = false }) { cleanupDraw(); }, afterEval: ({ code, meta }) => { + updateUserPattern(code); setMiniLocations(meta.miniLocations); setWidgets(meta.widgets); setPending(false); diff --git a/website/src/repl/panel/Panel.jsx b/website/src/repl/panel/Panel.jsx index a38bdd24..711bd644 100644 --- a/website/src/repl/panel/Panel.jsx +++ b/website/src/repl/panel/Panel.jsx @@ -86,7 +86,7 @@ export function Panel({ context }) { - {/* */} + {TAURI && } @@ -101,7 +101,7 @@ export function Panel({ context }) {
{activeFooter === 'intro' && } - {/* {activeFooter === 'patterns' && } */} + {activeFooter === 'patterns' && } {activeFooter === 'console' && } {activeFooter === 'sounds' && } {activeFooter === 'reference' && } diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx index 4a4a3930..60096bc8 100644 --- a/website/src/repl/panel/PatternsTab.jsx +++ b/website/src/repl/panel/PatternsTab.jsx @@ -1,24 +1,57 @@ import React from 'react'; import * as tunes from '../tunes.mjs'; -import { useSettings, clearUserPatterns, newUserPattern } from '../../settings.mjs'; +import { + useSettings, + clearUserPatterns, + newUserPattern, + setActivePattern, + deleteActivePattern, + duplicateActivePattern, + getUserPattern, +} from '../../settings.mjs'; + +function classNames(...classes) { + return classes.filter(Boolean).join(' '); +} export function PatternsTab({ context }) { - const { userPatterns } = useSettings(); + const { userPatterns, activePattern } = useSettings(); return (

My Patterns

- - + + + +
{Object.entries(userPatterns).map(([key, up]) => ( { const { code } = up; - console.log('clikkk', code); context.handleUpdate(code); + setActivePattern(key); }} > {key} @@ -28,9 +61,12 @@ export function PatternsTab({ context }) { {Object.entries(tunes).map(([key, tune]) => ( { - console.log('clikkk', tune); + setActivePattern(key); context.handleUpdate(tune); }} > diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 72ddace4..cb580eec 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -1,6 +1,7 @@ import { persistentMap } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { register } from '@strudel.cycles/core'; +import * as tunes from './repl/tunes.mjs'; export const defaultSettings = { activeFooter: 'intro', @@ -16,6 +17,7 @@ export const defaultSettings = { soundsFilter: 'all', panelPosition: 'bottom', userPatterns: '{}', + activePattern: '', }; export const settingsMap = persistentMap('strudel-settings', defaultSettings); @@ -59,6 +61,10 @@ export const settingPatterns = { theme, fontFamily, fontSize }; function getUserPatterns() { return JSON.parse(settingsMap.get().userPatterns); } +function getSetting(key) { + return settingsMap.get()[key]; +} + function setUserPatterns(obj) { settingsMap.setKey('userPatterns', JSON.stringify(obj)); } @@ -80,9 +86,68 @@ export function newUserPattern() { const todays = Object.entries(userPatterns).filter(([name]) => name.startsWith(date)); const num = String(todays.length + 1).padStart(3, '0'); const defaultNewPattern = 's("hh")'; - addUserPattern(date + '_' + num, { code: defaultNewPattern }); + const name = date + '_' + num; + addUserPattern(name, { code: defaultNewPattern }); + setActivePattern(name); + return name; } export function clearUserPatterns() { setUserPatterns({}); } + +export function getNextCloneName(key) { + const userPatterns = getUserPatterns(); + const clones = Object.entries(userPatterns).filter(([name]) => name.startsWith(key)); + const num = String(clones.length + 1).padStart(3, '0'); + return key + '_' + num; +} + +export function getUserPattern(key) { + const userPatterns = getUserPatterns(); + return userPatterns[key]; +} + +export function updateUserPattern(code) { + const userPatterns = getUserPatterns(); + let activePattern = getSetting('activePattern'); + console.log('update', activePattern, code); + if (!activePattern) { + activePattern = newUserPattern(); + setUserPatterns({ ...userPatterns, [activePattern]: { code } }); + setActivePattern(activePattern); + } else if (!!tunes[activePattern] && code !== tunes[activePattern]) { + // is example / system pattern + activePattern = getNextCloneName(activePattern); + setUserPatterns({ ...userPatterns, [activePattern]: { code } }); + setActivePattern(activePattern); + } +} + +export function deleteActivePattern() { + let activePattern = getSetting('activePattern'); + if (!activePattern) { + console.warn('cannot delete: no pattern selected'); + return; + } + const userPatterns = getUserPatterns(); + setUserPatterns(Object.fromEntries(Object.entries(userPatterns).filter(([key]) => key !== activePattern))); + setActivePattern(''); +} + +export function duplicateActivePattern() { + let activePattern = getSetting('activePattern'); + let latestCode = getSetting('latestCode'); + if (!activePattern) { + console.warn('cannot duplicate: no pattern selected'); + return; + } + const userPatterns = getUserPatterns(); + activePattern = getNextCloneName(activePattern); + setUserPatterns({ ...userPatterns, [activePattern]: { latestCode } }); + setActivePattern(activePattern); +} + +export function setActivePattern(key) { + settingsMap.setKey('activePattern', key); +}