From 5ca9afa9e804d3189fd524a61d42299e4df9f2fe Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Mon, 15 Apr 2024 19:53:12 -0400 Subject: [PATCH 1/9] restored --- website/src/components/Udels/UdelFrame.jsx | 33 ++++++ website/src/components/Udels/Udels.jsx | 115 +++++++++++++++++++++ website/src/layouts/MainLayout.astro | 2 +- website/src/pages/index.astro | 4 +- website/src/pages/udels/index.astro | 12 +++ website/src/repl/Repl.jsx | 7 +- website/src/repl/panel/PatternsTab.jsx | 4 +- website/src/repl/panel/SettingsTab.jsx | 8 +- website/src/repl/util.mjs | 4 + website/src/settings.mjs | 9 +- 10 files changed, 185 insertions(+), 13 deletions(-) create mode 100644 website/src/components/Udels/UdelFrame.jsx create mode 100644 website/src/components/Udels/Udels.jsx create mode 100644 website/src/pages/udels/index.astro diff --git a/website/src/components/Udels/UdelFrame.jsx b/website/src/components/Udels/UdelFrame.jsx new file mode 100644 index 00000000..78d28944 --- /dev/null +++ b/website/src/components/Udels/UdelFrame.jsx @@ -0,0 +1,33 @@ +import { useRef } from 'react'; + +export function UdelFrame({ onEvaluate, hash, instance }) { + const ref = useRef(); + + window.addEventListener('message', (message) => { + const childWindow = ref?.current?.contentWindow; + if (message == null || message.source !== childWindow) { + return; // Skip message in this event listener + } + onEvaluate(message.data); + }); + + const url = new URL(window.location.origin); + url.hash = hash; + url.searchParams.append('instance', instance); + const source = url.toString(); + + return ( + + ); +} diff --git a/website/src/components/Udels/Udels.jsx b/website/src/components/Udels/Udels.jsx new file mode 100644 index 00000000..b2d81ea9 --- /dev/null +++ b/website/src/components/Udels/Udels.jsx @@ -0,0 +1,115 @@ +import { code2hash } from '@strudel/core'; + +import { UdelFrame } from './UdelFrame'; +import { useState } from 'react'; + +function NumberInput({ value, onChange, label = '', min, max }) { + const [localState, setLocalState] = useState(value); + const [isFocused, setIsFocused] = useState(false); + + return ( + + ); +} +const defaultHash = 'c3RhY2soCiAgCik%3D'; + +const getHashesFromUrl = () => { + return window.location.hash?.slice(1).split(','); +}; +const updateURLHashes = (hashes) => { + const newHash = '#' + hashes.join(','); + window.location.hash = newHash; +}; +export function Udels() { + const hashes = getHashesFromUrl(); + + const [numWindows, setNumWindows] = useState(hashes?.length ?? 1); + const numWindowsOnChange = (num) => { + setNumWindows(num); + const hashes = getHashesFromUrl(); + const newHashes = []; + for (let i = 0; i < num; i++) { + newHashes[i] = hashes[i] ?? defaultHash; + } + updateURLHashes(newHashes); + }; + + const onEvaluate = (key, code) => { + const hashes = getHashesFromUrl(); + hashes[key] = code2hash(code); + updateURLHashes(hashes); + }; + // useEffect(() => { + // prebake(); + // }, []); + + return ( +
+
+ +
+
+ {hashes.map((hash, key) => { + return ( + { + onEvaluate(key, code); + }} + hash={hash} + key={key} + /> + ); + })} +
+ {/* */} +
+ ); +} diff --git a/website/src/layouts/MainLayout.astro b/website/src/layouts/MainLayout.astro index 49952a7e..c6f6653c 100644 --- a/website/src/layouts/MainLayout.astro +++ b/website/src/layouts/MainLayout.astro @@ -30,7 +30,7 @@ const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`; - +
diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro index 760cf448..29cf2fad 100644 --- a/website/src/pages/index.astro +++ b/website/src/pages/index.astro @@ -3,12 +3,12 @@ import HeadCommon from '../components/HeadCommon.astro'; import { Repl } from '../repl/Repl'; --- - + Strudel REPL - + diff --git a/website/src/pages/udels/index.astro b/website/src/pages/udels/index.astro new file mode 100644 index 00000000..4ab699e7 --- /dev/null +++ b/website/src/pages/udels/index.astro @@ -0,0 +1,12 @@ +--- +import { Udels } from '../../components/Udels/Udels.jsx'; + + +const { BASE_URL } = import.meta.env; +const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; +--- + + + + + \ No newline at end of file diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 9c472eb4..0c1ad91d 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -34,7 +34,7 @@ import Loader from './Loader'; import { Panel } from './panel/Panel'; import { useStore } from '@nanostores/react'; import { prebake } from './prebake.mjs'; -import { getRandomTune, initCode, loadModules, shareCode, ReplContext } from './util.mjs'; +import { getRandomTune, initCode, loadModules, shareCode, ReplContext, isUdels } from './util.mjs'; import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import './Repl.css'; import { setInterval, clearInterval } from 'worker-timers'; @@ -221,6 +221,7 @@ export function Repl({ embedded = false }) { handleEvaluate, }; + const showPanel = !isEmbedded || isUdels(); return (
@@ -246,12 +247,12 @@ export function Repl({ embedded = false }) { } }} > - {panelPosition === 'right' && !isEmbedded && } + {panelPosition === 'right' && showPanel && }
{error && (
{error.message || 'Unknown Error :-/'}
)} - {panelPosition === 'bottom' && !isEmbedded && } + {panelPosition === 'bottom' && showPanel && }
); diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx index f6499d79..cacbe897 100644 --- a/website/src/repl/panel/PatternsTab.jsx +++ b/website/src/repl/panel/PatternsTab.jsx @@ -9,7 +9,7 @@ import { import { useMemo } from 'react'; import { getMetadata } from '../../metadata_parser'; import { useExamplePatterns } from '../useExamplePatterns'; -import { parseJSON } from '../util.mjs'; +import { parseJSON, isUdels } from '../util.mjs'; import { ButtonGroup } from './Forms.jsx'; import { settingsMap, useSettings } from '../../settings.mjs'; @@ -99,7 +99,7 @@ export function PatternsTab({ context }) { }; const viewingPatternID = viewingPatternData?.id; - const autoResetPatternOnChange = !window.parent?.location.pathname.includes('oodles'); + const autoResetPatternOnChange = !isUdels(); return (
diff --git a/website/src/repl/panel/SettingsTab.jsx b/website/src/repl/panel/SettingsTab.jsx index ae290189..36ec12bd 100644 --- a/website/src/repl/panel/SettingsTab.jsx +++ b/website/src/repl/panel/SettingsTab.jsx @@ -1,12 +1,13 @@ import { defaultSettings, settingsMap, useSettings } from '../../settings.mjs'; import { themes } from '@strudel/codemirror'; +import { isUdels } from '../util.mjs'; import { ButtonGroup } from './Forms.jsx'; import { AudioDeviceSelector } from './AudioDeviceSelector.jsx'; -function Checkbox({ label, value, onChange }) { +function Checkbox({ label, value, onChange, disabled = false }) { return ( ); @@ -96,7 +97,7 @@ export function SettingsTab({ started }) { panelPosition, audioDeviceName, } = useSettings(); - + const shouldAlwaysSync = isUdels(); return (
{AudioContext.prototype.setSinkId != null && ( @@ -197,6 +198,7 @@ export function SettingsTab({ started }) { window.location.reload(); } }} + disabled={shouldAlwaysSync} value={isSyncEnabled} /> diff --git a/website/src/repl/util.mjs b/website/src/repl/util.mjs index 6dba7dab..67584760 100644 --- a/website/src/repl/util.mjs +++ b/website/src/repl/util.mjs @@ -132,6 +132,10 @@ export async function shareCode(codeToShare) { export const ReplContext = createContext(null); +export const isUdels = () => { + return window.parent?.location.pathname.includes('udels'); +}; + export const getAudioDevices = async () => { await navigator.mediaDevices.getUserMedia({ audio: true }); let mediaDevices = await navigator.mediaDevices.enumerateDevices(); diff --git a/website/src/settings.mjs b/website/src/settings.mjs index a70c4202..3f1ca051 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/core'; +import { isUdels } from './repl/util.mjs'; export const defaultAudioDeviceName = 'System Standard'; @@ -28,8 +29,12 @@ export const defaultSettings = { userPatterns: '{}', audioDeviceName: defaultAudioDeviceName, }; +const search = new URLSearchParams(window.location.search); +// if running multiple instance in one window, it will use the settings for that instance. else default to normal +const instance = parseInt(search.get('instance') ?? '0'); +const settings_key = `strudel-settings${instance > 0 ? instance : ''}`; -export const settingsMap = persistentMap('strudel-settings', defaultSettings); +export const settingsMap = persistentMap(settings_key, defaultSettings); const parseBoolean = (booleanlike) => ([true, 'true'].includes(booleanlike) ? true : false); @@ -54,7 +59,7 @@ export function useSettings() { isTooltipEnabled: parseBoolean(state.isTooltipEnabled), isLineWrappingEnabled: parseBoolean(state.isLineWrappingEnabled), isFlashEnabled: parseBoolean(state.isFlashEnabled), - isSyncEnabled: parseBoolean(state.isSyncEnabled), + isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled), fontSize: Number(state.fontSize), panelPosition: state.activeFooter !== '' ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is! userPatterns: userPatterns, From 6c9e0aaa1aa9bacc2793cc0cdfd2669350465e46 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Fri, 14 Jun 2024 01:24:08 -0400 Subject: [PATCH 2/9] added udels editor and header --- website/src/components/Udels/Udels.jsx | 7 ++- website/src/components/Udels/UdelsEditor.jsx | 34 ++++++++++ website/src/components/Udels/UdelsHeader.tsx | 25 ++++++++ website/src/repl/Repl.jsx | 10 ++- website/src/repl/components/BigPlayButton.jsx | 22 +++++++ website/src/repl/components/Code.jsx | 23 +++++++ .../components/UserFacingErrorMessage.jsx | 8 +++ website/src/repl/panel/NumberInput.jsx | 62 +++++++++++++++++++ website/src/settings.mjs | 6 +- 9 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 website/src/components/Udels/UdelsEditor.jsx create mode 100644 website/src/components/Udels/UdelsHeader.tsx create mode 100644 website/src/repl/components/BigPlayButton.jsx create mode 100644 website/src/repl/components/Code.jsx create mode 100644 website/src/repl/components/UserFacingErrorMessage.jsx create mode 100644 website/src/repl/panel/NumberInput.jsx diff --git a/website/src/components/Udels/Udels.jsx b/website/src/components/Udels/Udels.jsx index b2d81ea9..72d983e0 100644 --- a/website/src/components/Udels/Udels.jsx +++ b/website/src/components/Udels/Udels.jsx @@ -2,6 +2,7 @@ import { code2hash } from '@strudel/core'; import { UdelFrame } from './UdelFrame'; import { useState } from 'react'; +import UdelsHeader from './UdelsHeader'; function NumberInput({ value, onChange, label = '', min, max }) { const [localState, setLocalState] = useState(value); @@ -68,7 +69,6 @@ export function Udels() { return (
-
+ {/*
-
+
*/}
, +// editorRef: React.MutableRefObject, +// error: Error +// init: () => void +// } + +export default function UdelsEditor(Props) { + const { context, containerRef, editorRef, error, init } = Props; + const { pending, started, handleTogglePlay } = context; + return ( + +
+ + {/*
*/} + +
+ +
+ + +
+
+ ); +} diff --git a/website/src/components/Udels/UdelsHeader.tsx b/website/src/components/Udels/UdelsHeader.tsx new file mode 100644 index 00000000..7555e182 --- /dev/null +++ b/website/src/components/Udels/UdelsHeader.tsx @@ -0,0 +1,25 @@ +import NumberInput from '@src/repl/panel/NumberInput'; + +export default function UdelsHeader(Props) { + const { numWindows, setNumWindows } = Props; + + return ( + + ); +} diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index a4b7ba73..87ff653c 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -39,6 +39,7 @@ import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import './Repl.css'; import { setInterval, clearInterval } from 'worker-timers'; import { getMetadata } from '../metadata_parser'; +import UdelsEditor from '@components/Udels/UdelsEditor'; const { latestCode } = settingsMap.get(); @@ -234,7 +235,14 @@ export function Repl({ embedded = false }) { handleEvaluate, }; - const showPanel = !isEmbedded || isUdels(); + if (isUdels()) { + return ( + + ); + } + + const showPanel = !isEmbedded; + return (
diff --git a/website/src/repl/components/BigPlayButton.jsx b/website/src/repl/components/BigPlayButton.jsx new file mode 100644 index 00000000..80a4d345 --- /dev/null +++ b/website/src/repl/components/BigPlayButton.jsx @@ -0,0 +1,22 @@ +import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; + +// type Props = { +// started: boolean; +// handleTogglePlay: () => void; +// }; +export default function BigPlayButton(Props) { + const { started, handleTogglePlay } = Props; + if (started) { + return; + } + + return ( + + ); +} diff --git a/website/src/repl/components/Code.jsx b/website/src/repl/components/Code.jsx new file mode 100644 index 00000000..5afc53eb --- /dev/null +++ b/website/src/repl/components/Code.jsx @@ -0,0 +1,23 @@ + + +// type Props = { +// containerRef: React.MutableRefObject, +// editorRef: React.MutableRefObject, +// init: () => void +// } +export function Code(Props) { +const {editorRef, containerRef, init} = Props; + + return ( +
{ + containerRef.current = el; + if (!editorRef.current) { + init(); + } + }} + >
+ ); +} diff --git a/website/src/repl/components/UserFacingErrorMessage.jsx b/website/src/repl/components/UserFacingErrorMessage.jsx new file mode 100644 index 00000000..ec8d8be3 --- /dev/null +++ b/website/src/repl/components/UserFacingErrorMessage.jsx @@ -0,0 +1,8 @@ +// type Props = { error: Error | null }; +export default function UserFacingErrorMessage(Props) { + const { error } = Props; + if (error == null) { + return; + } + return
{error.message || 'Unknown Error :-/'}
; +} diff --git a/website/src/repl/panel/NumberInput.jsx b/website/src/repl/panel/NumberInput.jsx new file mode 100644 index 00000000..d6683587 --- /dev/null +++ b/website/src/repl/panel/NumberInput.jsx @@ -0,0 +1,62 @@ +function Button(Props) { + const { children, onClick } = Props; + + return ( + + ); +} +export default function NumberInput(Props) { + const { value = 0, setValue, max, min} = Props; + + return ( +
+ + setValue(e.target.value)} + /> + +
+ ); + + +} diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 3f1ca051..c7958912 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -1,7 +1,7 @@ import { persistentMap } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { register } from '@strudel/core'; -import { isUdels } from './repl/util.mjs'; +import { isUdels, } from './repl/util.mjs'; export const defaultAudioDeviceName = 'System Standard'; @@ -25,7 +25,7 @@ export const defaultSettings = { isZen: false, soundsFilter: 'all', patternFilter: 'community', - panelPosition: 'right', + panelPosition: 'right', userPatterns: '{}', audioDeviceName: defaultAudioDeviceName, }; @@ -61,7 +61,7 @@ export function useSettings() { isFlashEnabled: parseBoolean(state.isFlashEnabled), isSyncEnabled: isUdels() ? true : parseBoolean(state.isSyncEnabled), fontSize: Number(state.fontSize), - panelPosition: state.activeFooter !== '' ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is! + panelPosition: state.activeFooter !== '' && !isUdels() ? state.panelPosition : 'bottom', // <-- keep this 'bottom' where it is! userPatterns: userPatterns, }; } From 2a2ddf205abf51c8d4a0edc450ee63474c585980 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Fri, 14 Jun 2024 14:26:23 -0400 Subject: [PATCH 3/9] need to fix window message --- website/src/components/Oven/Oven.jsx | 2 +- website/src/components/Udels/UdelFrame.jsx | 3 +- website/src/components/Udels/Udels.jsx | 41 +----------- website/src/components/Udels/UdelsEditor.jsx | 4 +- website/src/components/Udels/UdelsHeader.tsx | 2 +- website/src/repl/Repl.jsx | 50 ++++----------- website/src/repl/{ => components}/Header.jsx | 4 +- website/src/repl/{ => components}/Loader.jsx | 0 website/src/repl/components/NumberInput.jsx | 54 ++++++++++++++++ website/src/repl/components/ReplEditor.jsx | 39 ++++++++++++ .../panel/AudioDeviceSelector.jsx | 2 +- .../{ => components}/panel/ConsoleTab.jsx | 0 .../repl/{ => components}/panel/FilesTab.jsx | 2 +- .../src/repl/{ => components}/panel/Forms.jsx | 0 .../panel/ImportSoundsButton.jsx | 2 +- .../src/repl/{ => components}/panel/Panel.jsx | 2 +- .../{ => components}/panel/PatternsTab.jsx | 10 +-- .../repl/{ => components}/panel/Reference.jsx | 2 +- .../{ => components}/panel/SelectInput.jsx | 0 .../{ => components}/panel/SettingsTab.jsx | 4 +- .../repl/{ => components}/panel/SoundsTab.jsx | 2 +- .../{ => components}/panel/WelcomeTab.jsx | 0 website/src/repl/panel/NumberInput.jsx | 62 ------------------- 23 files changed, 126 insertions(+), 161 deletions(-) rename website/src/repl/{ => components}/Header.jsx (98%) rename website/src/repl/{ => components}/Loader.jsx (100%) create mode 100644 website/src/repl/components/NumberInput.jsx create mode 100644 website/src/repl/components/ReplEditor.jsx rename website/src/repl/{ => components}/panel/AudioDeviceSelector.jsx (94%) rename website/src/repl/{ => components}/panel/ConsoleTab.jsx (100%) rename website/src/repl/{ => components}/panel/FilesTab.jsx (97%) rename website/src/repl/{ => components}/panel/Forms.jsx (100%) rename website/src/repl/{ => components}/panel/ImportSoundsButton.jsx (97%) rename website/src/repl/{ => components}/panel/Panel.jsx (98%) rename website/src/repl/{ => components}/panel/PatternsTab.jsx (95%) rename website/src/repl/{ => components}/panel/Reference.jsx (98%) rename website/src/repl/{ => components}/panel/SelectInput.jsx (100%) rename website/src/repl/{ => components}/panel/SettingsTab.jsx (99%) rename website/src/repl/{ => components}/panel/SoundsTab.jsx (98%) rename website/src/repl/{ => components}/panel/WelcomeTab.jsx (100%) delete mode 100644 website/src/repl/panel/NumberInput.jsx diff --git a/website/src/components/Oven/Oven.jsx b/website/src/components/Oven/Oven.jsx index a4199b5e..eb3c8692 100644 --- a/website/src/components/Oven/Oven.jsx +++ b/website/src/components/Oven/Oven.jsx @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; import { loadFeaturedPatterns, loadPublicPatterns } from '@src/user_pattern_utils.mjs'; import { MiniRepl } from '@src/docs/MiniRepl'; -import { PatternLabel } from '@src/repl/panel/PatternsTab'; +import { PatternLabel } from '@src/repl/components/panel/PatternsTab'; function PatternList({ patterns }) { return ( diff --git a/website/src/components/Udels/UdelFrame.jsx b/website/src/components/Udels/UdelFrame.jsx index 78d28944..856aa831 100644 --- a/website/src/components/Udels/UdelFrame.jsx +++ b/website/src/components/Udels/UdelFrame.jsx @@ -2,8 +2,9 @@ import { useRef } from 'react'; export function UdelFrame({ onEvaluate, hash, instance }) { const ref = useRef(); - + console.info('frame') window.addEventListener('message', (message) => { + console.info(message, 'message') const childWindow = ref?.current?.contentWindow; if (message == null || message.source !== childWindow) { return; // Skip message in this event listener diff --git a/website/src/components/Udels/Udels.jsx b/website/src/components/Udels/Udels.jsx index 72d983e0..c3062419 100644 --- a/website/src/components/Udels/Udels.jsx +++ b/website/src/components/Udels/Udels.jsx @@ -4,36 +4,7 @@ import { UdelFrame } from './UdelFrame'; import { useState } from 'react'; import UdelsHeader from './UdelsHeader'; -function NumberInput({ value, onChange, label = '', min, max }) { - const [localState, setLocalState] = useState(value); - const [isFocused, setIsFocused] = useState(false); - return ( - - ); -} const defaultHash = 'c3RhY2soCiAgCik%3D'; const getHashesFromUrl = () => { @@ -60,6 +31,7 @@ export function Udels() { const onEvaluate = (key, code) => { const hashes = getHashesFromUrl(); hashes[key] = code2hash(code); + updateURLHashes(hashes); }; // useEffect(() => { @@ -78,17 +50,6 @@ export function Udels() { }} > - {/*
- -
*/}
-
- -
- {isEmbedded && !started && ( - - )} -
-
{ - containerRef.current = el; - if (!editorRef.current) { - init(); - } - }} - >
- {panelPosition === 'right' && showPanel && } -
- {error && ( -
{error.message || 'Unknown Error :-/'}
- )} - {panelPosition === 'bottom' && showPanel && } -
- + ); } diff --git a/website/src/repl/Header.jsx b/website/src/repl/components/Header.jsx similarity index 98% rename from website/src/repl/Header.jsx rename to website/src/repl/components/Header.jsx index 748b84e4..288822dd 100644 --- a/website/src/repl/Header.jsx +++ b/website/src/repl/components/Header.jsx @@ -5,9 +5,9 @@ import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import SparklesIcon from '@heroicons/react/20/solid/SparklesIcon'; import StopCircleIcon from '@heroicons/react/20/solid/StopCircleIcon'; import cx from '@src/cx.mjs'; -import { useSettings, setIsZen } from '../settings.mjs'; +import { useSettings, setIsZen } from '../../settings.mjs'; // import { ReplContext } from './Repl'; -import './Repl.css'; +import '../Repl.css'; const { BASE_URL } = import.meta.env; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; diff --git a/website/src/repl/Loader.jsx b/website/src/repl/components/Loader.jsx similarity index 100% rename from website/src/repl/Loader.jsx rename to website/src/repl/components/Loader.jsx diff --git a/website/src/repl/components/NumberInput.jsx b/website/src/repl/components/NumberInput.jsx new file mode 100644 index 00000000..0c3e7e53 --- /dev/null +++ b/website/src/repl/components/NumberInput.jsx @@ -0,0 +1,54 @@ +function Button(Props) { + const { children, onClick } = Props; + + return ( + + ); +} +export default function NumberInput(Props) { + const { value = 0, setValue, max, min } = Props; + + return ( +
+ + setValue(e.target.value)} + /> + +
+ ); +} diff --git a/website/src/repl/components/ReplEditor.jsx b/website/src/repl/components/ReplEditor.jsx new file mode 100644 index 00000000..57eabb71 --- /dev/null +++ b/website/src/repl/components/ReplEditor.jsx @@ -0,0 +1,39 @@ +import { ReplContext } from '@src/repl/util.mjs'; + +import Loader from '@src/repl/components/Loader'; +import { Panel } from '@src/repl/components/panel/Panel'; +import { Code } from '@src/repl/components/Code'; +import BigPlayButton from '@src/repl/components/BigPlayButton'; +import UserFacingErrorMessage from '@src/repl/components/UserFacingErrorMessage'; +import { Header } from './Header'; + + +// type Props = { +// context: replcontext, +// containerRef: React.MutableRefObject, +// editorRef: React.MutableRefObject, +// error: Error +// init: () => void +// isEmbedded: boolean +// } + +export default function ReplEditor(Props) { + const { context, containerRef, editorRef, error, init, panelPosition } = Props; + const { pending, started, handleTogglePlay, isEmbedded } = context; + const showPanel = !isEmbedded; + return ( + +
+ +
+ {isEmbedded && } +
+ + {panelPosition === 'right' && showPanel && } +
+ + {panelPosition === 'bottom' && showPanel && } +
+
+ ); +} diff --git a/website/src/repl/panel/AudioDeviceSelector.jsx b/website/src/repl/components/panel/AudioDeviceSelector.jsx similarity index 94% rename from website/src/repl/panel/AudioDeviceSelector.jsx rename to website/src/repl/components/panel/AudioDeviceSelector.jsx index 969bf387..d1f13c22 100644 --- a/website/src/repl/panel/AudioDeviceSelector.jsx +++ b/website/src/repl/components/panel/AudioDeviceSelector.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { getAudioDevices, setAudioDevice } from '../util.mjs'; +import { getAudioDevices, setAudioDevice } from '../../util.mjs'; import { SelectInput } from './SelectInput'; const initdevices = new Map(); diff --git a/website/src/repl/panel/ConsoleTab.jsx b/website/src/repl/components/panel/ConsoleTab.jsx similarity index 100% rename from website/src/repl/panel/ConsoleTab.jsx rename to website/src/repl/components/panel/ConsoleTab.jsx diff --git a/website/src/repl/panel/FilesTab.jsx b/website/src/repl/components/panel/FilesTab.jsx similarity index 97% rename from website/src/repl/panel/FilesTab.jsx rename to website/src/repl/components/panel/FilesTab.jsx index d78ec1ec..2e121fb5 100644 --- a/website/src/repl/panel/FilesTab.jsx +++ b/website/src/repl/components/panel/FilesTab.jsx @@ -1,6 +1,6 @@ import { Fragment, useEffect } from 'react'; import React, { useMemo, useState } from 'react'; -import { isAudioFile, readDir, dir, playFile } from '../files.mjs'; +import { isAudioFile, readDir, dir, playFile } from '../../files.mjs'; export function FilesTab() { const [path, setPath] = useState([]); diff --git a/website/src/repl/panel/Forms.jsx b/website/src/repl/components/panel/Forms.jsx similarity index 100% rename from website/src/repl/panel/Forms.jsx rename to website/src/repl/components/panel/Forms.jsx diff --git a/website/src/repl/panel/ImportSoundsButton.jsx b/website/src/repl/components/panel/ImportSoundsButton.jsx similarity index 97% rename from website/src/repl/panel/ImportSoundsButton.jsx rename to website/src/repl/components/panel/ImportSoundsButton.jsx index da45705f..7862b766 100644 --- a/website/src/repl/panel/ImportSoundsButton.jsx +++ b/website/src/repl/components/panel/ImportSoundsButton.jsx @@ -1,5 +1,5 @@ import React, { useCallback, useState } from 'react'; -import { registerSamplesFromDB, uploadSamplesToDB, userSamplesDBConfig } from '../idbutils.mjs'; +import { registerSamplesFromDB, uploadSamplesToDB, userSamplesDBConfig } from '../../idbutils.mjs'; //choose a directory to locally import samples export default function ImportSoundsButton({ onComplete }) { diff --git a/website/src/repl/panel/Panel.jsx b/website/src/repl/components/panel/Panel.jsx similarity index 98% rename from website/src/repl/panel/Panel.jsx rename to website/src/repl/components/panel/Panel.jsx index 7d35f0e4..a7bb6a83 100644 --- a/website/src/repl/panel/Panel.jsx +++ b/website/src/repl/components/panel/Panel.jsx @@ -4,7 +4,7 @@ import useEvent from '@src/useEvent.mjs'; import cx from '@src/cx.mjs'; import { nanoid } from 'nanoid'; import { useCallback, useLayoutEffect, useEffect, useRef, useState } from 'react'; -import { setActiveFooter, useSettings } from '../../settings.mjs'; +import { setActiveFooter, useSettings } from '../../../settings.mjs'; import { ConsoleTab } from './ConsoleTab'; import { FilesTab } from './FilesTab'; import { Reference } from './Reference'; diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/components/panel/PatternsTab.jsx similarity index 95% rename from website/src/repl/panel/PatternsTab.jsx rename to website/src/repl/components/panel/PatternsTab.jsx index cacbe897..5e9119b1 100644 --- a/website/src/repl/panel/PatternsTab.jsx +++ b/website/src/repl/components/panel/PatternsTab.jsx @@ -5,13 +5,13 @@ import { useActivePattern, useViewingPatternData, userPattern, -} from '../../user_pattern_utils.mjs'; +} from '../../../user_pattern_utils.mjs'; import { useMemo } from 'react'; -import { getMetadata } from '../../metadata_parser'; -import { useExamplePatterns } from '../useExamplePatterns'; -import { parseJSON, isUdels } from '../util.mjs'; +import { getMetadata } from '../../../metadata_parser.js'; +import { useExamplePatterns } from '../../useExamplePatterns.jsx'; +import { parseJSON, isUdels } from '../../util.mjs'; import { ButtonGroup } from './Forms.jsx'; -import { settingsMap, useSettings } from '../../settings.mjs'; +import { settingsMap, useSettings } from '../../../settings.mjs'; function classNames(...classes) { return classes.filter(Boolean).join(' '); diff --git a/website/src/repl/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx similarity index 98% rename from website/src/repl/panel/Reference.jsx rename to website/src/repl/components/panel/Reference.jsx index 9483e9c5..04297c0b 100644 --- a/website/src/repl/panel/Reference.jsx +++ b/website/src/repl/components/panel/Reference.jsx @@ -1,4 +1,4 @@ -import jsdocJson from '../../../../doc.json'; +import jsdocJson from '../../../../../doc.json'; const visibleFunctions = jsdocJson.docs .filter(({ name, description }) => name && !name.startsWith('_') && !!description) .sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); diff --git a/website/src/repl/panel/SelectInput.jsx b/website/src/repl/components/panel/SelectInput.jsx similarity index 100% rename from website/src/repl/panel/SelectInput.jsx rename to website/src/repl/components/panel/SelectInput.jsx diff --git a/website/src/repl/panel/SettingsTab.jsx b/website/src/repl/components/panel/SettingsTab.jsx similarity index 99% rename from website/src/repl/panel/SettingsTab.jsx rename to website/src/repl/components/panel/SettingsTab.jsx index 36ec12bd..e1d047ea 100644 --- a/website/src/repl/panel/SettingsTab.jsx +++ b/website/src/repl/components/panel/SettingsTab.jsx @@ -1,6 +1,6 @@ -import { defaultSettings, settingsMap, useSettings } from '../../settings.mjs'; +import { defaultSettings, settingsMap, useSettings } from '../../../settings.mjs'; import { themes } from '@strudel/codemirror'; -import { isUdels } from '../util.mjs'; +import { isUdels } from '../../util.mjs'; import { ButtonGroup } from './Forms.jsx'; import { AudioDeviceSelector } from './AudioDeviceSelector.jsx'; diff --git a/website/src/repl/panel/SoundsTab.jsx b/website/src/repl/components/panel/SoundsTab.jsx similarity index 98% rename from website/src/repl/panel/SoundsTab.jsx rename to website/src/repl/components/panel/SoundsTab.jsx index 9b35d04b..8b7b36a8 100644 --- a/website/src/repl/panel/SoundsTab.jsx +++ b/website/src/repl/components/panel/SoundsTab.jsx @@ -2,7 +2,7 @@ import useEvent from '@src/useEvent.mjs'; import { useStore } from '@nanostores/react'; import { getAudioContext, soundMap, connectToDestination } from '@strudel/webaudio'; import React, { useMemo, useRef } from 'react'; -import { settingsMap, useSettings } from '../../settings.mjs'; +import { settingsMap, useSettings } from '../../../settings.mjs'; import { ButtonGroup } from './Forms.jsx'; import ImportSoundsButton from './ImportSoundsButton.jsx'; diff --git a/website/src/repl/panel/WelcomeTab.jsx b/website/src/repl/components/panel/WelcomeTab.jsx similarity index 100% rename from website/src/repl/panel/WelcomeTab.jsx rename to website/src/repl/components/panel/WelcomeTab.jsx diff --git a/website/src/repl/panel/NumberInput.jsx b/website/src/repl/panel/NumberInput.jsx deleted file mode 100644 index d6683587..00000000 --- a/website/src/repl/panel/NumberInput.jsx +++ /dev/null @@ -1,62 +0,0 @@ -function Button(Props) { - const { children, onClick } = Props; - - return ( - - ); -} -export default function NumberInput(Props) { - const { value = 0, setValue, max, min} = Props; - - return ( -
- - setValue(e.target.value)} - /> - -
- ); - - -} From 1d95da7a3a0aa62ec9168311fdb718e6bd7cc7c1 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Fri, 14 Jun 2024 15:28:24 -0400 Subject: [PATCH 4/9] fixed build window issue: --- packages/core/evaluate.mjs | 2 ++ website/src/components/Udels/UdelFrame.jsx | 2 -- website/src/settings.mjs | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/core/evaluate.mjs b/packages/core/evaluate.mjs index 23cd44c1..af02a9a9 100644 --- a/packages/core/evaluate.mjs +++ b/packages/core/evaluate.mjs @@ -39,6 +39,8 @@ function safeEval(str, options = {}) { export const evaluate = async (code, transpiler, transpilerOptions) => { let meta = {}; + //post to iframe parent (like Udels) if it exists... + window.parent?.postMessage(code); if (transpiler) { // transform syntactically correct js code to semantically usable code const transpiled = transpiler(code, transpilerOptions); diff --git a/website/src/components/Udels/UdelFrame.jsx b/website/src/components/Udels/UdelFrame.jsx index 856aa831..8bbbe14e 100644 --- a/website/src/components/Udels/UdelFrame.jsx +++ b/website/src/components/Udels/UdelFrame.jsx @@ -2,9 +2,7 @@ import { useRef } from 'react'; export function UdelFrame({ onEvaluate, hash, instance }) { const ref = useRef(); - console.info('frame') window.addEventListener('message', (message) => { - console.info(message, 'message') const childWindow = ref?.current?.contentWindow; if (message == null || message.source !== childWindow) { return; // Skip message in this event listener diff --git a/website/src/settings.mjs b/website/src/settings.mjs index c7958912..1405fbf1 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -29,9 +29,13 @@ export const defaultSettings = { userPatterns: '{}', audioDeviceName: defaultAudioDeviceName, }; -const search = new URLSearchParams(window.location.search); + +let search = null; +if (typeof window !== 'undefined') { + search = new URLSearchParams(window.location.search); +} // if running multiple instance in one window, it will use the settings for that instance. else default to normal -const instance = parseInt(search.get('instance') ?? '0'); +const instance = parseInt(search?.get('instance') ?? '0'); const settings_key = `strudel-settings${instance > 0 ? instance : ''}`; export const settingsMap = persistentMap(settings_key, defaultSettings); From f3b83b41f5da6f1562d8ed43865ec8816b55bae3 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Fri, 14 Jun 2024 15:40:37 -0400 Subject: [PATCH 5/9] prettier --- website/src/components/Udels/Udels.jsx | 3 +-- website/src/components/Udels/UdelsHeader.tsx | 13 ++++--------- website/src/repl/components/Code.jsx | 4 +--- website/src/repl/components/ReplEditor.jsx | 3 +-- website/src/settings.mjs | 6 +++--- 5 files changed, 10 insertions(+), 19 deletions(-) diff --git a/website/src/components/Udels/Udels.jsx b/website/src/components/Udels/Udels.jsx index c3062419..0de70050 100644 --- a/website/src/components/Udels/Udels.jsx +++ b/website/src/components/Udels/Udels.jsx @@ -4,7 +4,6 @@ import { UdelFrame } from './UdelFrame'; import { useState } from 'react'; import UdelsHeader from './UdelsHeader'; - const defaultHash = 'c3RhY2soCiAgCik%3D'; const getHashesFromUrl = () => { @@ -31,7 +30,7 @@ export function Udels() { const onEvaluate = (key, code) => { const hashes = getHashesFromUrl(); hashes[key] = code2hash(code); - + updateURLHashes(hashes); }; // useEffect(() => { diff --git a/website/src/components/Udels/UdelsHeader.tsx b/website/src/components/Udels/UdelsHeader.tsx index 7049e781..d56f3a1d 100644 --- a/website/src/components/Udels/UdelsHeader.tsx +++ b/website/src/components/Udels/UdelsHeader.tsx @@ -7,16 +7,11 @@ export default function UdelsHeader(Props) {