mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-23 03:28:33 +00:00
commit
09c5c07bfb
@ -7,6 +7,7 @@ class Strudel extends HTMLElement {
|
|||||||
const code = (this.innerHTML + '').replace('<!--', '').replace('-->', '').trim();
|
const code = (this.innerHTML + '').replace('<!--', '').replace('-->', '').trim();
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
const src = `https://strudel.tidalcycles.org/#${encodeURIComponent(btoa(code))}`;
|
const src = `https://strudel.tidalcycles.org/#${encodeURIComponent(btoa(code))}`;
|
||||||
|
// const src = `http://localhost:3000/#${encodeURIComponent(btoa(code))}`;
|
||||||
iframe.setAttribute('src', src);
|
iframe.setAttribute('src', src);
|
||||||
iframe.setAttribute('width', '600');
|
iframe.setAttribute('width', '600');
|
||||||
iframe.setAttribute('height', '400');
|
iframe.setAttribute('height', '400');
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<script src="https://unpkg.com/@strudel.cycles/embed@latest"></script>
|
<script src="https://unpkg.com/@strudel.cycles/embed@latest"></script>
|
||||||
|
<!-- <script src="./embed.js"></script> -->
|
||||||
<strudel-repl>
|
<strudel-repl>
|
||||||
<!--
|
<!--
|
||||||
"a4 [a3 c3] a3 c3".color('#F9D649')
|
"a4 [a3 c3] a3 c3".color('#F9D649')
|
||||||
|
|||||||
106
repl/src/App.js
106
repl/src/App.js
@ -58,6 +58,7 @@ extend(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const initialUrl = window.location.href;
|
||||||
const codeParam = window.location.href.split('#')[1];
|
const codeParam = window.location.href.split('#')[1];
|
||||||
let decoded;
|
let decoded;
|
||||||
try {
|
try {
|
||||||
@ -74,7 +75,7 @@ function getRandomTune() {
|
|||||||
|
|
||||||
const randomTune = getRandomTune();
|
const randomTune = getRandomTune();
|
||||||
const defaultSynth = getDefaultSynth();
|
const defaultSynth = getDefaultSynth();
|
||||||
|
const isEmbedded = window.location !== window.parent.location;
|
||||||
function App() {
|
function App() {
|
||||||
// const [editor, setEditor] = useState();
|
// const [editor, setEditor] = useState();
|
||||||
const [view, setView] = useState();
|
const [view, setView] = useState();
|
||||||
@ -100,7 +101,9 @@ function App() {
|
|||||||
const logBox = useRef();
|
const logBox = useRef();
|
||||||
// scroll log box to bottom when log changes
|
// scroll log box to bottom when log changes
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
logBox.current.scrollTop = logBox.current?.scrollHeight;
|
if (logBox.current) {
|
||||||
|
logBox.current.scrollTop = logBox.current?.scrollHeight;
|
||||||
|
}
|
||||||
}, [log]);
|
}, [log]);
|
||||||
|
|
||||||
// set active pattern on ctrl+enter
|
// set active pattern on ctrl+enter
|
||||||
@ -148,16 +151,19 @@ function App() {
|
|||||||
<div className="min-h-screen flex flex-col">
|
<div className="min-h-screen flex flex-col">
|
||||||
<header
|
<header
|
||||||
id="header"
|
id="header"
|
||||||
className="flex-none w-full h-14 px-2 flex border-b border-gray-200 justify-between z-[10] bg-gray-100"
|
className={cx(
|
||||||
|
'flex-none w-full px-2 flex border-b border-gray-200 justify-between z-[10] bg-gray-100',
|
||||||
|
isEmbedded ? 'h-8' : 'h-14',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<img src={logo} className="Tidal-logo w-10 h-10" alt="logo" />
|
<img src={logo} className={cx('Tidal-logo', isEmbedded ? 'w-6 h-6' : 'w-10 h-10')} alt="logo" />
|
||||||
<h1 className="text-xl">Strudel REPL</h1>
|
<h1 className={isEmbedded ? 'text-l' : 'text-xl'}>Strudel {isEmbedded ? 'Mini ' : ''}REPL</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<button onClick={() => togglePlay()} className="hover:bg-gray-300 p-2">
|
<button onClick={() => togglePlay()} className={cx('hover:bg-gray-300', !isEmbedded ? 'p-2' : 'px-2')}>
|
||||||
{!pending ? (
|
{!pending ? (
|
||||||
<span className="flex items-center w-16">
|
<span className={cx('flex items-center', isEmbedded ? 'w-16' : 'w-16')}>
|
||||||
{cycle.started ? (
|
{cycle.started ? (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||||
<path
|
<path
|
||||||
@ -181,31 +187,55 @@ function App() {
|
|||||||
<>loading...</>
|
<>loading...</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
{!isEmbedded && (
|
||||||
className="hover:bg-gray-300 p-2"
|
<button
|
||||||
onClick={async () => {
|
className="hover:bg-gray-300 p-2"
|
||||||
const _code = getRandomTune();
|
onClick={async () => {
|
||||||
console.log('tune', _code); // uncomment this to debug when random code fails
|
const _code = getRandomTune();
|
||||||
setCode(_code);
|
console.log('tune', _code); // uncomment this to debug when random code fails
|
||||||
drawHelpers.cleanup();
|
setCode(_code);
|
||||||
uiHelpers.cleanup();
|
drawHelpers.cleanup();
|
||||||
const parsed = await evaluate(_code);
|
uiHelpers.cleanup();
|
||||||
setPattern(parsed.pattern);
|
const parsed = await evaluate(_code);
|
||||||
setActiveCode(_code);
|
setPattern(parsed.pattern);
|
||||||
}}
|
setActiveCode(_code);
|
||||||
>
|
}}
|
||||||
🎲 random
|
>
|
||||||
</button>
|
🎲 random
|
||||||
<button className="hover:bg-gray-300 p-2">
|
</button>
|
||||||
<a href="./tutorial">📚 tutorial</a>
|
)}
|
||||||
</button>
|
{!isEmbedded && (
|
||||||
|
<button className={cx('hover:bg-gray-300', !isEmbedded ? 'p-2' : 'px-2')}>
|
||||||
|
<a href="./tutorial">📚 tutorial</a>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{isEmbedded && (
|
||||||
|
<button className={cx('hover:bg-gray-300 px-2')}>
|
||||||
|
<a href={window.location.href} target="_blank" rel="noopener noreferrer" title="Open in REPL">
|
||||||
|
🚀 open
|
||||||
|
</a>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{isEmbedded && (
|
||||||
|
<button className={cx('hover:bg-gray-300 px-2')}>
|
||||||
|
<a
|
||||||
|
onClick={() => {
|
||||||
|
window.location.href = initialUrl;
|
||||||
|
window.location.reload();
|
||||||
|
}}
|
||||||
|
title="Reset"
|
||||||
|
>
|
||||||
|
💔 reset
|
||||||
|
</a>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<section className="grow flex flex-col text-gray-100">
|
<section className="grow flex flex-col text-gray-100">
|
||||||
<div className="grow relative flex overflow-auto" id="code">
|
<div className="grow relative flex overflow-auto" id="code">
|
||||||
{/* onCursor={markParens} */}
|
{/* onCursor={markParens} */}
|
||||||
<CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} />
|
<CodeMirror6 value={code} onChange={setCode} onViewChanged={setView} />
|
||||||
<span className="p-4 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none">
|
<span className="z-[20] py-1 px-2 absolute top-0 right-0 text-xs whitespace-pre text-right pointer-events-none">
|
||||||
{!cycle.started ? `press ctrl+enter to play\n` : dirty ? `ctrl+enter to update\n` : 'no changes\n'}
|
{!cycle.started ? `press ctrl+enter to play\n` : dirty ? `ctrl+enter to update\n` : 'no changes\n'}
|
||||||
</span>
|
</span>
|
||||||
{error && (
|
{error && (
|
||||||
@ -214,17 +244,21 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
{!isEmbedded && (
|
||||||
className="z-[10] h-16 border-0 text-xs bg-[transparent] border-t border-slate-600 resize-none"
|
<textarea
|
||||||
value={log}
|
className="z-[10] h-16 border-0 text-xs bg-[transparent] border-t border-slate-600 resize-none"
|
||||||
readOnly
|
value={log}
|
||||||
ref={logBox}
|
readOnly
|
||||||
style={{ fontFamily: 'monospace' }}
|
ref={logBox}
|
||||||
/>
|
style={{ fontFamily: 'monospace' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
<button className="fixed right-4 bottom-2 z-[11]" onClick={() => playStatic(code)}>
|
{!isEmbedded && (
|
||||||
static
|
<button className="fixed right-4 bottom-2 z-[11]" onClick={() => playStatic(code)}>
|
||||||
</button>
|
static
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user