From b9ffbf28eff570ea53bfd4579185566a2c706e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Tue, 18 Nov 2025 08:14:13 +0100 Subject: [PATCH] feat: move effects section to collapsible area below track waveform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major UX improvement inspired by Ableton Live's device view: - Effects section now appears below the waveform in the track lane - Toggle button in control panel shows/hides the effects area - Gives much more horizontal space for device rack - Effects section spans full width of track (control panel + waveform) - Clean separation between track controls and effects - Header with device count, add button, and close button Layout changes: - Track structure changed from horizontal to vertical flex - Top row contains control panel + waveform (fixed height) - Bottom section contains collapsible effects area (when shown) - Effects hidden by default, toggled via "Devices" button - When collapsed, track doesn't show effects section This provides a cleaner workflow where users can focus on mixing when effects are hidden, then expand to full device view when needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/tracks/Track.tsx | 118 ++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 40 deletions(-) diff --git a/components/tracks/Track.tsx b/components/tracks/Track.tsx index 65f3469..e49c009 100644 --- a/components/tracks/Track.tsx +++ b/components/tracks/Track.tsx @@ -57,6 +57,7 @@ export function Track({ const [isEditingName, setIsEditingName] = React.useState(false); const [nameInput, setNameInput] = React.useState(String(track.name || 'Untitled Track')); const [effectBrowserOpen, setEffectBrowserOpen] = React.useState(false); + const [showEffects, setShowEffects] = React.useState(false); const inputRef = React.useRef(null); const handleNameClick = () => { @@ -252,16 +253,17 @@ export function Track({
- {/* Left: Track Control Panel (Fixed Width) */} -
e.stopPropagation()} - > + {/* Top: Track Row (Control Panel + Waveform) */} +
+ {/* Left: Track Control Panel (Fixed Width) */} +
e.stopPropagation()} + > {/* Track Name & Collapse Toggle */}
- {/* Devices/Effects Section */} -
-
- - Devices ({track.effectChain.effects.length}) - + {/* Devices Toggle Button */} + {!track.collapsed && ( +
- - {/* Horizontal scrolling device rack */} -
-
- {track.effectChain.effects.length === 0 ? ( -
- No devices. Click + to add an effect. -
- ) : ( - track.effectChain.effects.map((effect) => ( - onToggleEffect?.(effect.id)} - onRemove={() => onRemoveEffect?.(effect.id)} - /> - )) - )} -
-
-
+ )} )}
@@ -472,6 +457,59 @@ export function Track({ ) )}
+
+ + {/* Bottom: Effects Section (Collapsible, Full Width) */} + {showEffects && !track.collapsed && ( +
+ {/* Effects Header */} +
+ + Devices ({track.effectChain.effects.length}) + +
+ + +
+
+ + {/* Horizontal scrolling device rack */} +
+
+ {track.effectChain.effects.length === 0 ? ( +
+ No devices. Click + to add an effect. +
+ ) : ( + track.effectChain.effects.map((effect) => ( + onToggleEffect?.(effect.id)} + onRemove={() => onRemoveEffect?.(effect.id)} + /> + )) + )} +
+
+
+ )} {/* Effect Browser Dialog */}