Skip to content

Commit

Permalink
Merge pull request #852 from tidalcycles/import-export-patterns
Browse files Browse the repository at this point in the history
patterns tab: import patterns + style
  • Loading branch information
felixroos authored Dec 8, 2023
2 parents ac2e450 + 31cd626 commit c3e48f1
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 49 deletions.
10 changes: 8 additions & 2 deletions website/src/repl/Repl.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,15 @@ export function Repl({ embedded = false }) {
stop();
}
};
const handleUpdate = (newCode) => {
const handleUpdate = async (newCode, reset = false) => {
if (reset) {
clearCanvas();
resetLoadedSounds();
scheduler.setCps(1);
await prebake(); // declare default samples
}
(newCode || isDirty) && activateCode(newCode);
logger('[repl] code updated! tip: you can also update the code by pressing ctrl+enter', 'highlight');
logger('[repl] code updated!');
};

const handleShuffle = async () => {
Expand Down
104 changes: 61 additions & 43 deletions website/src/repl/panel/PatternsTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
duplicateActivePattern,
getUserPattern,
renameActivePattern,
addUserPattern,
} from '../../settings.mjs';
import { logger } from '@strudel.cycles/core';

function classNames(...classes) {
return classes.filter(Boolean).join(' ');
Expand All @@ -18,16 +20,15 @@ function classNames(...classes) {
export function PatternsTab({ context }) {
const { userPatterns, activePattern } = useSettings();
return (
<div className="px-4 w-full text-foreground space-y-4">
<div className="px-4 w-full dark:text-white text-stone-900 space-y-4 pb-4">
<section>
<h2 className="text-xl mb-2">Pattern Collection</h2>
<div className="space-x-4 border-b border-foreground mb-1">
<div className="px-4 space-x-4 border-b border-foreground mb-2 h-8">
<button
className="hover:opacity-50"
onClick={() => {
const name = newUserPattern();
const { code } = getUserPattern(name);
context.handleUpdate(code);
context.handleUpdate(code, true);
}}
>
new
Expand All @@ -44,50 +45,67 @@ export function PatternsTab({ context }) {
<button className="hover:opacity-50" onClick={() => clearUserPatterns()}>
clear
</button>
<label className="hover:opacity-50 cursor-pointer">
<input
style={{ display: 'none' }}
type="file"
multiple
accept="text/plain"
onChange={async (e) => {
const files = Array.from(e.target.files);
await Promise.all(
files.map(async (file, i) => {
const code = await file.text();
const name = file.name.replace(/\.[^/.]+$/, '');
console.log(i, name, code);
addUserPattern(name, { code });
}),
);
logger(`import done!`);
}}
/>
import
</label>
</div>
<div className="font-mono text-sm">
{Object.entries(userPatterns).map(([key, up]) => (
<a
key={key}
className={classNames(
'mr-4 hover:opacity-50 cursor-pointer inline-block',
key === activePattern ? 'outline outline-1' : '',
)}
onClick={() => {
const { code } = up;
setActivePattern(key);
context.handleUpdate(code, true);
}}
>
{key}
</a>
))}
</div>
{Object.entries(userPatterns).map(([key, up]) => (
<a
key={key}
className={classNames(
'mr-4 hover:opacity-50 cursor-pointer inline-block',
key === activePattern ? 'underline' : '',
)}
onClick={() => {
const { code } = up;
setActivePattern(key);
context.handleUpdate(code);
}}
>
{key}
</a>
))}
</section>
<section>
<h2 className="text-xl mb-2">Examples</h2>
{Object.entries(tunes).map(([key, tune]) => (
<a
key={key}
className={classNames(
'mr-4 hover:opacity-50 cursor-pointer inline-block',
key === activePattern ? 'underline' : '',
)}
onClick={() => {
setActivePattern(key);
context.handleUpdate(tune);
}}
>
{key}
</a>
))}
<div className="font-mono text-sm">
{Object.entries(tunes).map(([key, tune]) => (
<a
key={key}
className={classNames(
'mr-4 hover:opacity-50 cursor-pointer inline-block',
key === activePattern ? 'outline outline-1' : '',
)}
onClick={() => {
setActivePattern(key);
context.handleUpdate(tune, true);
}}
>
{key}
</a>
))}
</div>
</section>
</div>
);
}

/*
selectable examples
if example selected
type character -> create new user pattern with exampleName_n
even if
clicking (+) opens the "new" example with same behavior as above
*/
6 changes: 3 additions & 3 deletions website/src/repl/panel/SoundsTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ export function SoundsTab() {
});
});
return (
<div id="sounds-tab" className="flex flex-col w-full h-full dark:text-white text-stone-900">
<div className="px-2 pb-2 flex-none">
<div id="sounds-tab" className="px-4 flex flex-col w-full h-full dark:text-white text-stone-900">
<div className="pb-2 flex-none">
<ButtonGroup
value={soundsFilter}
onChange={(value) => settingsMap.setKey('soundsFilter', value)}
Expand All @@ -55,7 +55,7 @@ export function SoundsTab() {
}}
></ButtonGroup>
</div>
<div className="p-2 min-h-0 max-h-full grow overflow-auto font-mono text-sm break-normal">
<div className="min-h-0 max-h-full grow overflow-auto font-mono text-sm break-normal">
{soundEntries.map(([name, { data, onTrigger }]) => (
<span
key={name}
Expand Down
1 change: 0 additions & 1 deletion website/src/settings.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,5 @@ export function duplicateActivePattern() {
}

export function setActivePattern(key) {
console.log('set', key);
settingsMap.setKey('activePattern', key);
}

0 comments on commit c3e48f1

Please sign in to comment.