refactor: move solo/mute to header as icon buttons and fix waveform height
Changes: - Solo and Mute buttons now appear as icon buttons in the track header (next to trash) - Removed redundant solo/mute button row from the expanded controls - Cleaner, more compact layout - Canvas now uses parent container's size for proper full-height rendering - Added track.height to canvas effect dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -84,8 +84,12 @@ export function Track({
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
// Use parent container's size since canvas is absolute positioned
|
||||
const parent = canvas.parentElement;
|
||||
if (!parent) return;
|
||||
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const rect = parent.getBoundingClientRect();
|
||||
|
||||
canvas.width = rect.width * dpr;
|
||||
canvas.height = rect.height * dpr;
|
||||
@@ -147,7 +151,7 @@ export function Track({
|
||||
ctx.lineTo(playheadX, height);
|
||||
ctx.stroke();
|
||||
}
|
||||
}, [track.audioBuffer, track.color, track.collapsed, zoom, currentTime, duration]);
|
||||
}, [track.audioBuffer, track.color, track.collapsed, track.height, zoom, currentTime, duration]);
|
||||
|
||||
const handleCanvasClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
|
||||
if (!onSeek || !duration) return;
|
||||
@@ -216,6 +220,33 @@ export function Track({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Solo Button */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={onToggleSolo}
|
||||
title="Solo track"
|
||||
className={cn(track.solo && 'bg-yellow-500/20 hover:bg-yellow-500/30')}
|
||||
>
|
||||
<Headphones className={cn('h-4 w-4', track.solo && 'text-yellow-500')} />
|
||||
</Button>
|
||||
|
||||
{/* Mute Button */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
onClick={onToggleMute}
|
||||
title="Mute track"
|
||||
className={cn(track.mute && 'bg-red-500/20 hover:bg-red-500/30')}
|
||||
>
|
||||
{track.mute ? (
|
||||
<VolumeX className="h-4 w-4 text-red-500" />
|
||||
) : (
|
||||
<Volume2 className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
|
||||
{/* Remove Button */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
@@ -270,38 +301,6 @@ export function Track({
|
||||
step={0.01}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Solo / Mute Buttons */}
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant={track.solo ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onClick={onToggleSolo}
|
||||
className={cn(
|
||||
'flex-1 text-xs',
|
||||
track.solo && 'bg-yellow-500/20 hover:bg-yellow-500/30 text-yellow-500'
|
||||
)}
|
||||
>
|
||||
<Headphones className="h-3.5 w-3.5 mr-1.5" />
|
||||
Solo
|
||||
</Button>
|
||||
<Button
|
||||
variant={track.mute ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onClick={onToggleMute}
|
||||
className={cn(
|
||||
'flex-1 text-xs',
|
||||
track.mute && 'bg-red-500/20 hover:bg-red-500/30 text-red-500'
|
||||
)}
|
||||
>
|
||||
{track.mute ? (
|
||||
<VolumeX className="h-3.5 w-3.5 mr-1.5" />
|
||||
) : (
|
||||
<Volume2 className="h-3.5 w-3.5 mr-1.5" />
|
||||
)}
|
||||
Mute
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user