From 14042282396f079f18c796f3979911f3c2ad566b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Tue, 18 Nov 2025 07:08:04 +0100 Subject: [PATCH] feat: implement drag & drop for audio loading and decrease upload icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Reduced upload icon size from h-8 w-8 to h-6 w-6 (smaller, cleaner) - Implemented full drag & drop functionality for audio files - Shows visual feedback when dragging: blue border, primary color highlight - Changes text to "Drop audio file here" when dragging over - Validates dropped file is audio type before processing - Updated message from "coming soon" to active "or drag & drop" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/tracks/Track.tsx | 58 ++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/components/tracks/Track.tsx b/components/tracks/Track.tsx index 476fa80..8e2a3b4 100644 --- a/components/tracks/Track.tsx +++ b/components/tracks/Track.tsx @@ -192,6 +192,50 @@ export function Track({ fileInputRef.current?.click(); }; + const [isDragging, setIsDragging] = React.useState(false); + + const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(true); + }; + + const handleDragLeave = (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(false); + }; + + const handleDrop = async (e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(false); + + const file = e.dataTransfer.files?.[0]; + if (!file || !onLoadAudio) return; + + // Check if it's an audio file + if (!file.type.startsWith('audio/')) { + console.warn('Dropped file is not an audio file'); + return; + } + + try { + const arrayBuffer = await file.arrayBuffer(); + const audioContext = new AudioContext(); + const audioBuffer = await audioContext.decodeAudioData(arrayBuffer); + onLoadAudio(audioBuffer); + + // Update track name to filename if it's still default + if (track.name === 'New Track' || track.name === 'Untitled Track') { + const fileName = file.name.replace(/\.[^/.]+$/, ''); + onNameChange(fileName); + } + } catch (error) { + console.error('Failed to load audio file:', error); + } + }; + const trackHeight = track.collapsed ? 48 : track.height; return ( @@ -354,15 +398,21 @@ export function Track({ ) : ( <>
{ e.stopPropagation(); handleLoadAudioClick(); }} + onDragOver={handleDragOver} + onDragLeave={handleDragLeave} + onDrop={handleDrop} > - -

Click to load audio file

-

or drag & drop (coming soon)

+ +

{isDragging ? 'Drop audio file here' : 'Click to load audio file'}

+

or drag & drop