From b743f972768f53dd030f2642f115ea3863104152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Wed, 19 Nov 2025 09:32:34 +0100 Subject: [PATCH] fix: project loading and add editable project name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed project loading to restore all track properties and added inline project name editing in header. **AudioEditor.tsx:** - Added `loadTracks` from useMultiTrack hook - Fixed `handleLoadProject` to use `loadTracks()` instead of recreating tracks - Now properly restores all track properties (effects, automation, volume, pan, etc.) - Shows track count in success toast message - Added editable project name input in header - Positioned between logo and track actions - Auto-sizes based on text length - Saves on blur (triggers auto-save) - Smooth hover/focus transitions - Muted color that brightens on interaction **useMultiTrack.ts:** - Added `loadTracks()` method to replace all tracks at once - Enables proper project loading with full state restoration - Maintains all track properties during load **Fixes:** - Projects now load correctly with all tracks and their audio buffers - Track properties (effects, automation, volume, pan, etc.) fully restored - Project name can be edited inline in header - Auto-save triggers when project name changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/editor/AudioEditor.tsx | 29 ++++++++++++++++++----------- lib/hooks/useMultiTrack.ts | 5 +++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/components/editor/AudioEditor.tsx b/components/editor/AudioEditor.tsx index bdb017b..7e05266 100644 --- a/components/editor/AudioEditor.tsx +++ b/components/editor/AudioEditor.tsx @@ -95,6 +95,7 @@ export function AudioEditor() { removeTrack, updateTrack, clearTracks, + loadTracks, } = useMultiTrack(); // Track whether we should auto-select on next add (when project is empty) @@ -955,15 +956,8 @@ export function AudioEditor() { throw new Error('Project not found'); } - // Clear current state - clearTracks(); - - // Load tracks - for (const track of projectData.tracks) { - if (track.audioBuffer) { - addTrackFromBufferOriginal(track.audioBuffer, track.name); - } - } + // Load tracks with all their properties restored + loadTracks(projectData.tracks); // Restore settings setZoom(projectData.settings.zoom); @@ -976,7 +970,7 @@ export function AudioEditor() { addToast({ title: 'Project Loaded', - description: `"${projectData.metadata.name}" loaded successfully`, + description: `"${projectData.metadata.name}" loaded successfully (${projectData.tracks.length} track${projectData.tracks.length !== 1 ? 's' : ''})`, variant: 'success', duration: 2000, }); @@ -989,7 +983,7 @@ export function AudioEditor() { duration: 3000, }); } - }, [clearTracks, addTrackFromBufferOriginal, addToast]); + }, [loadTracks, addToast]); // Delete project const handleDeleteProject = React.useCallback(async (projectId: string) => { @@ -1252,6 +1246,19 @@ export function AudioEditor() {

Audio UI

+ {/* Project Name */} +
+ setCurrentProjectName(e.target.value)} + onBlur={handleSaveProject} + className="bg-transparent border-none outline-none text-sm font-medium text-muted-foreground hover:text-foreground focus:text-foreground transition-colors px-2 py-1 rounded hover:bg-accent/50 focus:bg-accent" + placeholder="Untitled Project" + style={{ width: `${Math.max(12, currentProjectName.length)}ch` }} + /> +
+ {/* Track Actions */}