import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import cx from '@src/cx.mjs'; import NumberInput from './NumberInput'; import { useEffect, useState } from 'react'; import { Textbox } from './textbox/Textbox'; import { setMultiChannelOrbits as setStrudelMultiChannelOrbits, setMaxPolyphony as setStrudelMaxPolyphony, getAudioContext } from '@strudel/webaudio'; import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; function Checkbox({ label, value, onChange, disabled = false }) { return ( ); } function FormItem({ label, children, disabled }) { return (
{children}
); } export default function ExportModal(Props) { const { started, isEmbedded, handleExport } = Props; const [downloadName, setDownloadName] = useState("") // TODO: make a form? const [startCycle, setStartCycle] = useState(0) const [endCycle, setEndCycle] = useState(1) const [sampleRate, setSampleRate] = useState(48000) const [multiChannelOrbits, setMultiChannelOrbits] = useState(true) const [maxPolyphony, setMaxPolyphony] = useState(1024) const [exporting, setExporting] = useState(false) const [progress, setProgress] = useState(0) const [length, setLength] = useState(1) const refreshProgress = () => { const audioContext = getAudioContext() if (audioContext instanceof OfflineAudioContext) { setProgress(audioContext.currentTime) setLength(audioContext.length / sampleRate) setTimeout(refreshProgress, 100); } } return ( <>
{ setDownloadName(e.target.value) }} onChange={v => { setDownloadName(v) }} disabled={exporting} placeholder="Leave empty to use current date" className={cx("placeholder:opacity-50", exporting && "opacity-50 border-opacity-50")} value={downloadName ?? ''} />
{ let v = parseInt(e.target.value); v = isNaN(v) ? 0 : Math.max(0, v); setStartCycle(v); }} onChange={v => { v = parseInt(v) setStartCycle(v); }} type="number" placeholder="" disabled={exporting} className={cx(exporting && "opacity-50 border-opacity-50")} value={startCycle ?? ''} /> { let v = parseInt(e.target.value); v = isNaN(v) ? Math.max(startCycle + 1, parseInt(v)) : v; setEndCycle(v); }} onChange={(v) => { v = parseInt(v) setEndCycle(v); }} type="number" placeholder="" disabled={exporting} className={cx(exporting && "opacity-50 border-opacity-50")} value={endCycle ?? ''} />
{ let v = parseInt(e.target.value); v = isNaN(v) ? 1 : Math.max(1, v); setSampleRate(v); }} onChange={v => { v = parseInt(v) setSampleRate(v); }} type="number" placeholder="" disabled={exporting} className={cx(exporting && "opacity-50 border-opacity-50")} value={sampleRate ?? ''} /> { let v = parseInt(e.target.value); v = isNaN(v) ? Math.max(1, parseInt(v)) : v; setMaxPolyphony(v); }} onChange={(v) => { v = Math.max(1, parseInt(v)); setMaxPolyphony(v); }} type="number" placeholder="" disabled={exporting} className={cx(exporting && "opacity-50 border-opacity-50")} value={maxPolyphony ?? ''} />
{ const val = cbEvent.target.checked; setMultiChannelOrbits(val) }} disabled={exporting} value={multiChannelOrbits} />
); }