From 8d325b96ead0769ad047f038d1a210b2773ca1a4 Mon Sep 17 00:00:00 2001 From: "Jade (Rose) Rowland" Date: Sat, 6 Jan 2024 14:49:52 -0500 Subject: [PATCH] init --- website/src/repl/Repl.jsx | 8 ++-- .../src/repl/panel/AudioDeviceSelector.jsx | 36 +---------------- website/src/repl/util.mjs | 39 ++++++++++++++++++- website/src/settings.mjs | 6 ++- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index d53e7e5b..7f8bd06a 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -8,9 +8,10 @@ import { code2hash, getDrawContext, logger, silence } from '@strudel.cycles/core import cx from '@src/cx.mjs'; import { transpiler } from '@strudel.cycles/transpiler'; import { getAudioContext, initAudioOnFirstClick, webaudioOutput } from '@strudel.cycles/webaudio'; -import { defaultAudioDeviceName, getAudioDevices, setAudioDevice } from './panel/AudioDeviceSelector'; +import { defaultAudioDeviceName } from '../settings.mjs'; +import { getAudioDevices, setAudioDevice } from './util.mjs'; import { StrudelMirror, defaultSettings } from '@strudel/codemirror'; -import { createContext, useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { initUserCode, setActivePattern, @@ -24,12 +25,11 @@ import Loader from './Loader'; import { Panel } from './panel/Panel'; import { useStore } from '@nanostores/react'; import { prebake } from './prebake.mjs'; -import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs'; +import { getRandomTune, initCode, loadModules, shareCode, ReplContext } from './util.mjs'; import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import './Repl.css'; const { code: randomTune, name } = getRandomTune(); -export const ReplContext = createContext(null); const { latestCode } = settingsMap.get(); diff --git a/website/src/repl/panel/AudioDeviceSelector.jsx b/website/src/repl/panel/AudioDeviceSelector.jsx index 98e3e068..969bf387 100644 --- a/website/src/repl/panel/AudioDeviceSelector.jsx +++ b/website/src/repl/panel/AudioDeviceSelector.jsx @@ -1,42 +1,8 @@ import React, { useState } from 'react'; -import { getAudioContext, initializeAudioOutput, setDefaultAudioContext } from '@strudel.cycles/webaudio'; +import { getAudioDevices, setAudioDevice } from '../util.mjs'; import { SelectInput } from './SelectInput'; -import { logger } from '@strudel.cycles/core'; const initdevices = new Map(); -export const defaultAudioDeviceName = 'System Standard'; - -export const getAudioDevices = async () => { - await navigator.mediaDevices.getUserMedia({ audio: true }); - let mediaDevices = await navigator.mediaDevices.enumerateDevices(); - mediaDevices = mediaDevices.filter((device) => device.kind === 'audiooutput' && device.deviceId !== 'default'); - const devicesMap = new Map(); - devicesMap.set(defaultAudioDeviceName, ''); - mediaDevices.forEach((device) => { - devicesMap.set(device.label, device.deviceId); - }); - return devicesMap; -}; - -export const setAudioDevice = async (id) => { - let audioCtx = getAudioContext(); - if (audioCtx.sinkId === id) { - return; - } - await audioCtx.suspend(); - await audioCtx.close(); - audioCtx = setDefaultAudioContext(); - await audioCtx.resume(); - const isValidID = (id ?? '').length > 0; - if (isValidID) { - try { - await audioCtx.setSinkId(id); - } catch { - logger('failed to set audio interface', 'warning'); - } - } - initializeAudioOutput(); -}; // Allows the user to select an audio interface for Strudel to play through export function AudioDeviceSelector({ audioDeviceName, onChange, isDisabled }) { diff --git a/website/src/repl/util.mjs b/website/src/repl/util.mjs index 2b93b619..27745eec 100644 --- a/website/src/repl/util.mjs +++ b/website/src/repl/util.mjs @@ -1,11 +1,14 @@ import { controls, evalScope, hash2code, logger } from '@strudel.cycles/core'; -import { settingPatterns } from '../settings.mjs'; +import { settingPatterns, defaultAudioDeviceName } from '../settings.mjs'; +import { getAudioContext, initializeAudioOutput, setDefaultAudioContext } from '@strudel.cycles/webaudio'; + import { isTauri } from '../tauri.mjs'; import './Repl.css'; import * as tunes from './tunes.mjs'; import { createClient } from '@supabase/supabase-js'; import { nanoid } from 'nanoid'; import { writeText } from '@tauri-apps/api/clipboard'; +import { createContext } from 'react'; // Create a single supabase client for interacting with your database const supabase = createClient( @@ -110,3 +113,37 @@ export async function shareCode(codeToShare) { logger(message); } } + +export const ReplContext = createContext(null); + +export const getAudioDevices = async () => { + await navigator.mediaDevices.getUserMedia({ audio: true }); + let mediaDevices = await navigator.mediaDevices.enumerateDevices(); + mediaDevices = mediaDevices.filter((device) => device.kind === 'audiooutput' && device.deviceId !== 'default'); + const devicesMap = new Map(); + devicesMap.set(defaultAudioDeviceName, ''); + mediaDevices.forEach((device) => { + devicesMap.set(device.label, device.deviceId); + }); + return devicesMap; +}; + +export const setAudioDevice = async (id) => { + let audioCtx = getAudioContext(); + if (audioCtx.sinkId === id) { + return; + } + await audioCtx.suspend(); + await audioCtx.close(); + audioCtx = setDefaultAudioContext(); + await audioCtx.resume(); + const isValidID = (id ?? '').length > 0; + if (isValidID) { + try { + await audioCtx.setSinkId(id); + } catch { + logger('failed to set audio interface', 'warning'); + } + } + initializeAudioOutput(); +}; \ No newline at end of file diff --git a/website/src/settings.mjs b/website/src/settings.mjs index c7413636..5ede6c03 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -2,9 +2,10 @@ import { persistentMap, persistentAtom } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { register } from '@strudel.cycles/core'; import * as tunes from './repl/tunes.mjs'; -import { defaultAudioDeviceName } from './repl/panel/AudioDeviceSelector'; import { logger } from '@strudel.cycles/core'; +export const defaultAudioDeviceName = 'System Standard'; + export const defaultSettings = { activeFooter: 'intro', keybindings: 'codemirror', @@ -171,6 +172,7 @@ export function updateUserCode(code) { setActivePattern(example); return; } + if (!activePattern) { // create new user pattern activePattern = newUserPattern(); @@ -241,4 +243,4 @@ export async function exportPatterns() { document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); -} +} \ No newline at end of file