feat: add EffectBrowser dialog for adding effects to tracks
Created a beautiful effect browser dialog inspired by Ableton Live: **EffectBrowser Component:** - Modal dialog with search functionality - Effects organized by category: - Dynamics (Compressor, Limiter, Gate) - Filters (Lowpass, Highpass, Bandpass, etc.) - Time-Based (Delay, Reverb, Chorus, Flanger, Phaser) - Distortion (Distortion, Bitcrusher) - Pitch & Time (Pitch Shifter, Time Stretch) - Utility (Normalize, Fade In/Out, Reverse) - Grid layout with hover effects - Real-time search filtering - Click effect to add to track **Integration:** - "+" button in track strip opens EffectBrowser dialog - Selecting an effect adds it to the track's effect chain - Effects appear immediately in the Devices section - Full enable/disable and remove functionality **UX Flow:** 1. Click "+" in track Devices section 2. Browse or search for effect 3. Click effect to add it 4. Effect appears in Devices list 5. Toggle on/off with ●/○ 6. Remove with × button Effects are now fully manageable in the UI! Next: Apply them to audio. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,8 @@ import type { Track as TrackType } from '@/types/track';
|
||||
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 { createEffect, type EffectType } from '@/lib/audio/effects/chain';
|
||||
|
||||
export interface TrackProps {
|
||||
track: TrackType;
|
||||
@@ -25,6 +27,7 @@ export interface TrackProps {
|
||||
onLoadAudio?: (buffer: AudioBuffer) => void;
|
||||
onToggleEffect?: (effectId: string) => void;
|
||||
onRemoveEffect?: (effectId: string) => void;
|
||||
onAddEffect?: (effectType: EffectType) => void;
|
||||
}
|
||||
|
||||
export function Track({
|
||||
@@ -45,6 +48,7 @@ export function Track({
|
||||
onLoadAudio,
|
||||
onToggleEffect,
|
||||
onRemoveEffect,
|
||||
onAddEffect,
|
||||
}: TrackProps) {
|
||||
const canvasRef = React.useRef<HTMLCanvasElement>(null);
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
@@ -52,6 +56,7 @@ export function Track({
|
||||
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<HTMLInputElement>(null);
|
||||
|
||||
const handleNameClick = () => {
|
||||
@@ -401,10 +406,7 @@ export function Track({
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={() => {
|
||||
// TODO: Open effect browser/selector dialog
|
||||
console.log('Add effect clicked for track:', track.id);
|
||||
}}
|
||||
onClick={() => setEffectBrowserOpen(true)}
|
||||
title="Add effect"
|
||||
className="h-5 w-5"
|
||||
>
|
||||
@@ -498,6 +500,17 @@ export function Track({
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Effect Browser Dialog */}
|
||||
<EffectBrowser
|
||||
open={effectBrowserOpen}
|
||||
onClose={() => setEffectBrowserOpen(false)}
|
||||
onSelectEffect={(effectType) => {
|
||||
if (onAddEffect) {
|
||||
onAddEffect(effectType);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user