mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 21:58:37 +00:00
use StrudelMirror directly in MicroRepl
This commit is contained in:
parent
48e06bd213
commit
fc034830d0
@ -1 +1,2 @@
|
|||||||
export * from './repl-component.mjs';
|
export * from './repl-component.mjs';
|
||||||
|
export * from './prebake.mjs';
|
||||||
|
|||||||
@ -103,8 +103,6 @@ if (typeof HTMLElement !== 'undefined') {
|
|||||||
// init settings
|
// init settings
|
||||||
this.editor.updateSettings(this.settings);
|
this.editor.updateSettings(this.settings);
|
||||||
this.editor.setCode(this.code);
|
this.editor.setCode(this.code);
|
||||||
// settingsMap.listen((settings, key) => editor.changeSetting(key, settings[key]));
|
|
||||||
// onEvent('strudel-toggle-play', () => this.editor.toggle());
|
|
||||||
}
|
}
|
||||||
// Element functionality written in here
|
// Element functionality written in here
|
||||||
}
|
}
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -793,6 +793,9 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0(react@18.2.0)
|
version: 18.2.0(react@18.2.0)
|
||||||
|
react-hook-inview:
|
||||||
|
specifier: ^4.5.0
|
||||||
|
version: 4.5.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
rehype-autolink-headings:
|
rehype-autolink-headings:
|
||||||
specifier: ^6.1.1
|
specifier: ^6.1.1
|
||||||
version: 6.1.1
|
version: 6.1.1
|
||||||
|
|||||||
@ -34,9 +34,9 @@
|
|||||||
"@strudel.cycles/transpiler": "workspace:*",
|
"@strudel.cycles/transpiler": "workspace:*",
|
||||||
"@strudel.cycles/webaudio": "workspace:*",
|
"@strudel.cycles/webaudio": "workspace:*",
|
||||||
"@strudel.cycles/xen": "workspace:*",
|
"@strudel.cycles/xen": "workspace:*",
|
||||||
"@strudel/hydra": "workspace:*",
|
|
||||||
"@strudel/codemirror": "workspace:*",
|
"@strudel/codemirror": "workspace:*",
|
||||||
"@strudel/desktopbridge": "workspace:*",
|
"@strudel/desktopbridge": "workspace:*",
|
||||||
|
"@strudel/hydra": "workspace:*",
|
||||||
"@strudel/repl": "workspace:*",
|
"@strudel/repl": "workspace:*",
|
||||||
"@supabase/supabase-js": "^2.21.0",
|
"@supabase/supabase-js": "^2.21.0",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
@ -54,6 +54,7 @@
|
|||||||
"nanostores": "^0.8.1",
|
"nanostores": "^0.8.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hook-inview": "^4.5.0",
|
||||||
"rehype-autolink-headings": "^6.1.1",
|
"rehype-autolink-headings": "^6.1.1",
|
||||||
"rehype-slug": "^5.0.1",
|
"rehype-slug": "^5.0.1",
|
||||||
"rehype-urls": "^1.1.1",
|
"rehype-urls": "^1.1.1",
|
||||||
|
|||||||
@ -1,32 +1,78 @@
|
|||||||
import { useState, useRef, useCallback, useEffect } from 'react';
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
||||||
import { Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
import '@strudel/repl';
|
import { getDrawContext, silence } from '@strudel.cycles/core';
|
||||||
|
import { transpiler } from '@strudel.cycles/transpiler';
|
||||||
|
import { getAudioContext, webaudioOutput } from '@strudel.cycles/webaudio';
|
||||||
|
import { StrudelMirror } from '@strudel/codemirror';
|
||||||
|
import { prebake } from '@strudel/repl';
|
||||||
|
import { useInView } from 'react-hook-inview';
|
||||||
|
|
||||||
// import { useInView } from 'react-hook-inview';
|
const initialSettings = {
|
||||||
|
keybindings: 'strudelTheme',
|
||||||
|
isLineNumbersDisplayed: false,
|
||||||
|
isActiveLineHighlighted: true,
|
||||||
|
isAutoCompletionEnabled: false,
|
||||||
|
isPatternHighlightingEnabled: true,
|
||||||
|
isFlashEnabled: true,
|
||||||
|
isTooltipEnabled: false,
|
||||||
|
isLineWrappingEnabled: false,
|
||||||
|
theme: 'strudelTheme',
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontSize: 18,
|
||||||
|
};
|
||||||
|
|
||||||
export function MicroRepl({ code, hideHeader = false }) {
|
export function MicroRepl({ code, hideHeader = false, canvasHeight = 200, punchcard, punchcardLabels }) {
|
||||||
/* const [ref, isVisible] = useInView({
|
const init = useCallback(({ code }) => {
|
||||||
|
const drawContext = getDrawContext();
|
||||||
|
const drawTime = [-2, 2];
|
||||||
|
const editor = new StrudelMirror({
|
||||||
|
defaultOutput: webaudioOutput,
|
||||||
|
getTime: () => getAudioContext().currentTime,
|
||||||
|
transpiler,
|
||||||
|
root: containerRef.current,
|
||||||
|
initialCode: '// LOADING',
|
||||||
|
pattern: silence,
|
||||||
|
settings: initialSettings,
|
||||||
|
drawTime,
|
||||||
|
onDraw: (haps, time, frame, painters) => {
|
||||||
|
painters.length && drawContext.clearRect(0, 0, drawContext.canvas.width * 2, drawContext.canvas.height * 2);
|
||||||
|
painters?.forEach((painter) => {
|
||||||
|
// ctx time haps drawTime paintOptions
|
||||||
|
painter(drawContext, time, haps, drawTime, { clear: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
prebake,
|
||||||
|
onUpdateState: (state) => {
|
||||||
|
setReplState({ ...state });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// init settings
|
||||||
|
editor.updateSettings(initialSettings);
|
||||||
|
editor.setCode(code);
|
||||||
|
editorRef.current = editor;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [ref, isVisible] = useInView({
|
||||||
threshold: 0.01,
|
threshold: 0.01,
|
||||||
}); */
|
onEnter: () => {
|
||||||
|
if (!editorRef.current) {
|
||||||
|
init({ code });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
const [replState, setReplState] = useState({});
|
const [replState, setReplState] = useState({});
|
||||||
const { started, isDirty, error } = replState;
|
const { started, isDirty, error } = replState;
|
||||||
const wc = useRef();
|
const editorRef = useRef();
|
||||||
function togglePlay() {
|
const containerRef = useRef();
|
||||||
if (wc.current) {
|
|
||||||
wc.current?.editor.toggle();
|
const [canvasId] = useState(Date.now());
|
||||||
}
|
const drawContext = useCallback(
|
||||||
}
|
punchcard ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null,
|
||||||
const listener = useCallback((e) => setReplState({ ...e.detail }), []);
|
[punchcard],
|
||||||
useEffect(() => {
|
);
|
||||||
return () => {
|
|
||||||
wc.current.removeEventListener('update', listener);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="overflow-hidden rounded-t-md bg-background border border-lineHighlight" ref={ref}>
|
||||||
className="overflow-hidden rounded-t-md bg-background border border-lineHighlight"
|
|
||||||
//ref={ref}
|
|
||||||
>
|
|
||||||
{!hideHeader && (
|
{!hideHeader && (
|
||||||
<div className="flex justify-between bg-lineHighlight">
|
<div className="flex justify-between bg-lineHighlight">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
@ -35,7 +81,7 @@ export function MicroRepl({ code, hideHeader = false }) {
|
|||||||
'cursor-pointer w-16 flex items-center justify-center p-1 border-r border-lineHighlight text-foreground bg-lineHighlight hover:bg-background',
|
'cursor-pointer w-16 flex items-center justify-center p-1 border-r border-lineHighlight text-foreground bg-lineHighlight hover:bg-background',
|
||||||
started ? 'animate-pulse' : '',
|
started ? 'animate-pulse' : '',
|
||||||
)}
|
)}
|
||||||
onClick={() => togglePlay()}
|
onClick={() => editorRef.current?.toggle()}
|
||||||
>
|
>
|
||||||
<Icon type={started ? 'stop' : 'play'} />
|
<Icon type={started ? 'stop' : 'play'} />
|
||||||
</button>
|
</button>
|
||||||
@ -44,40 +90,34 @@ export function MicroRepl({ code, hideHeader = false }) {
|
|||||||
'w-16 flex items-center justify-center p-1 text-foreground border-lineHighlight bg-lineHighlight',
|
'w-16 flex items-center justify-center p-1 text-foreground border-lineHighlight bg-lineHighlight',
|
||||||
isDirty ? 'text-foreground hover:bg-background cursor-pointer' : 'opacity-50 cursor-not-allowed',
|
isDirty ? 'text-foreground hover:bg-background cursor-pointer' : 'opacity-50 cursor-not-allowed',
|
||||||
)}
|
)}
|
||||||
onClick={() => activateCode()}
|
onClick={() => editorRef.current?.evaluate()}
|
||||||
>
|
>
|
||||||
<Icon type="refresh" />
|
<Icon type="refresh" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="overflow-auto relative">
|
<div className="overflow-auto relative p-1">
|
||||||
<strudel-editor
|
<div ref={containerRef}></div>
|
||||||
is-line-numbers-displayed="0"
|
|
||||||
is-active-line-highlighted="0"
|
|
||||||
code={code}
|
|
||||||
ref={(el) => {
|
|
||||||
if (wc.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wc.current = el;
|
|
||||||
el.addEventListener('update', listener);
|
|
||||||
}}
|
|
||||||
></strudel-editor>
|
|
||||||
{error && <div className="text-right p-1 text-md text-red-200">{error.message}</div>}
|
{error && <div className="text-right p-1 text-md text-red-200">{error.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
{/* punchcard && (
|
{/* punchcard && (
|
||||||
<canvas
|
<canvas
|
||||||
id={canvasId}
|
id={canvasId}
|
||||||
className="w-full pointer-events-none"
|
className="w-full pointer-events-none border-t border-lineHighlight"
|
||||||
height={canvasHeight}
|
height={canvasHeight}
|
||||||
ref={(el) => {
|
ref={(el) => {
|
||||||
if (el && el.width !== el.clientWidth) {
|
if (el && el.width !== el.clientWidth) {
|
||||||
el.width = el.clientWidth;
|
el.width = el.clientWidth;
|
||||||
}
|
}
|
||||||
}}
|
//const ratio = el.clientWidth / canvasHeight;
|
||||||
></canvas>
|
//const targetWidth = Math.round(el.width * ratio);
|
||||||
) */}
|
//if (el.width !== targetWidth) {
|
||||||
|
// el.width = targetWidth;
|
||||||
|
//}
|
||||||
|
}}
|
||||||
|
></canvas>
|
||||||
|
) */}
|
||||||
{/* !!log.length && (
|
{/* !!log.length && (
|
||||||
<div className="bg-gray-800 rounded-md p-2">
|
<div className="bg-gray-800 rounded-md p-2">
|
||||||
{log.map(({ message }, i) => (
|
{log.map(({ message }, i) => (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user