diff --git a/components/effects/EffectDevice.tsx b/components/effects/EffectDevice.tsx new file mode 100644 index 0000000..f73a897 --- /dev/null +++ b/components/effects/EffectDevice.tsx @@ -0,0 +1,108 @@ +'use client'; + +import * as React from 'react'; +import { ChevronDown, ChevronUp, Power, X } from 'lucide-react'; +import { Button } from '@/components/ui/Button'; +import { cn } from '@/lib/utils/cn'; +import type { ChainEffect } from '@/lib/audio/effects/chain'; + +export interface EffectDeviceProps { + effect: ChainEffect; + onToggleEnabled?: () => void; + onRemove?: () => void; + onUpdateParameters?: (parameters: any) => void; +} + +export function EffectDevice({ + effect, + onToggleEnabled, + onRemove, + onUpdateParameters, +}: EffectDeviceProps) { + const [isExpanded, setIsExpanded] = React.useState(false); + + return ( +
+ {/* Device Header */} +
+ +
+ + +
+
+ + {/* Device Parameters */} + {isExpanded && ( +
+
+
+ Type: {effect.type} +
+ {effect.parameters && Object.keys(effect.parameters).length > 0 && ( +
+ Parameters: +
+ {Object.entries(effect.parameters).map(([key, value]) => ( +
+ {key}: + {String(value)} +
+ ))} +
+
+ )} +
+
+ Parameter controls coming soon +
+
+ )} + + {/* Collapsed State Indicator */} + {!isExpanded && ( +
+ + {effect.type} + +
+ )} +
+ ); +} diff --git a/components/tracks/Track.tsx b/components/tracks/Track.tsx index e0af9ee..88f58ad 100644 --- a/components/tracks/Track.tsx +++ b/components/tracks/Track.tsx @@ -7,6 +7,7 @@ import { Button } from '@/components/ui/Button'; import { Slider } from '@/components/ui/Slider'; import { cn } from '@/lib/utils/cn'; import { EffectBrowser } from '@/components/effects/EffectBrowser'; +import { EffectDevice } from '@/components/effects/EffectDevice'; import { createEffect, type EffectType } from '@/lib/audio/effects/chain'; export interface TrackProps { @@ -55,7 +56,6 @@ export function Track({ const fileInputRef = React.useRef(null); const [isEditingName, setIsEditingName] = React.useState(false); const [nameInput, setNameInput] = React.useState(String(track.name || 'Untitled Track')); - const [showDevices, setShowDevices] = React.useState(true); const [effectBrowserOpen, setEffectBrowserOpen] = React.useState(false); const inputRef = React.useRef(null); @@ -390,19 +390,11 @@ export function Track({ {/* Devices/Effects Section */} -
+
- + + Devices ({track.effectChain.effects.length}) +
- {showDevices && ( -
+ {/* Horizontal scrolling device rack */} +
+
{track.effectChain.effects.length === 0 ? ( -
- No devices +
+ No devices. Click + to add an effect.
) : ( track.effectChain.effects.map((effect) => ( -
- {effect.name} -
- - -
-
+ effect={effect} + onToggleEnabled={() => onToggleEffect?.(effect.id)} + onRemove={() => onRemoveEffect?.(effect.id)} + /> )) )}
- )} +
)}