import { useEffect, useMemo, useState } from 'react'; import { Channel, InputChannel, OutputChannel } from '../../types'; import Button from '../../../../components/Button/Button'; import Card from '../../../../components/Card/Card'; import ChoiceSelect from '../../../../components/ChoiceSelect/ChoiceSelect'; import './CopyChannelModal.css'; const INPUT_CHANNELS: readonly string[] = Object.values(InputChannel); const OUTPUT_CHANNELS: readonly string[] = Object.values(OutputChannel); const ALL_CHANNELS: readonly string[] = [...INPUT_CHANNELS, ...OUTPUT_CHANNELS]; const isInputChannel = (raw: string) => INPUT_CHANNELS.includes(raw); /** Wraps a raw enum string back into the { Input } / { Output } shape. */ const wrapChannel = (raw: string): Channel => isInputChannel(raw) ? { Input: raw as InputChannel } : { Output: raw as OutputChannel }; /** The channels a given source can be copied onto: same type, minus itself. */ const destinationsFor = (source: string): string[] => (isInputChannel(source) ? INPUT_CHANNELS : OUTPUT_CHANNELS).filter( (channel) => channel !== source ); function CopyChannelModal({ onClose, copyChannel, }: { onClose: () => void; copyChannel: (channel1: Channel, channel2: Channel) => Promise; }) { const [source, setSource] = useState(ALL_CHANNELS[0]); const [destination, setDestination] = useState(() => destinationsFor(ALL_CHANNELS[0])[0]); const [isCopying, setIsCopying] = useState(false); const destinationOptions = useMemo(() => destinationsFor(source), [source]); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); const handleSourceChange = (nextSource: string) => { setSource(nextSource); // Picking a source of the other type (or picking the current // destination as source) invalidates the destination. const nextDestinations = destinationsFor(nextSource); if (!nextDestinations.includes(destination)) { setDestination(nextDestinations[0]); } }; const handleCopy = async () => { setIsCopying(true); try { await copyChannel(wrapChannel(source), wrapChannel(destination)); onClose(); } finally { setIsCopying(false); } }; return (
{ if (e.target === e.currentTarget) { onClose(); } }} >

Copy Channel

Copy every setting of one channel onto another. Channels can only be copied onto channels of the same type.

id="copy-channel-source" value={source} options={ALL_CHANNELS} onChange={handleSourceChange} />
id="copy-channel-destination" value={destination} options={destinationOptions} onChange={setDestination} />

{destination} will take the settings of {source}.
This overwrites {destination}.

); } export default CopyChannelModal;