**useMultiTrack.ts:**
- Removed localStorage persistence (tracks, effects, automation)
- Now relies entirely on IndexedDB via project management system
- Simpler state management without dual persistence
**AudioEditor.tsx:**
- Store last project ID in localStorage when saving
- Auto-load last project on page mount
- Only runs once per session with hasAutoLoaded flag
- Falls back to empty state if project can't be loaded
**Benefits:**
- No more conflicts between localStorage and IndexedDB
- Effects and automation properly persisted
- Seamless experience - reload page and your project is ready
- Single source of truth (IndexedDB)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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 <noreply@anthropic.com>
- Added showEffects property to Track type
- Added "E" button with Sparkles icon to toggle per-track effects
- Effects panel now appears below each track when toggled
- Removed global EffectsPanel from AudioEditor
- Updated useMultiTrack to persist showEffects state
- Streamlined workflow: both automation and effects are now per-track
This aligns the UX with professional DAWs like Ableton Live, where
effects and automation are track-scoped rather than global.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added migration logic to useMultiTrack hook:
- When loading tracks from localStorage, check if height < DEFAULT_TRACK_HEIGHT
- Automatically upgrade old heights (120px, 150px) to new default (180px)
- Preserves custom heights that are already >= 180px
This fixes the inline style issue where existing tracks had
style="height: 120px" that was cutting off the level meter.
After this update, refreshing the page will automatically upgrade
all existing tracks to the new height without losing any data.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive selection and editing capabilities to multi-track editor:
- Visual selection overlay with Shift+drag interaction on waveforms
- Multi-track edit commands (cut, copy, paste, delete, duplicate)
- Full keyboard shortcut support (Ctrl+X/C/V/D, Delete, Ctrl+Z/Y)
- Complete undo/redo integration via command pattern
- Per-track selection state with localStorage persistence
- Audio buffer manipulation utilities (extract, insert, delete, duplicate segments)
- Toast notifications for all edit operations
- Red playhead to distinguish from blue selection overlay
All edit operations are fully undoable and integrated with the existing
history manager system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Architecture:
- Each track now has its own effect chain stored in track.effectChain
- Separate master effect chain for the final mix output
- SidePanel has 3 tabs: Tracks, Track FX, Master FX
Changes:
- types/track.ts: Add effectChain field to Track interface
- lib/audio/track-utils.ts: Initialize effect chain when creating tracks
- lib/hooks/useMultiTrack.ts: Exclude effectChain from localStorage, recreate on load
- components/editor/AudioEditor.tsx:
- Add master effect chain state using useEffectChain hook
- Add handlers for per-track effect chain manipulation
- Pass both track and master effect chains to SidePanel
- components/layout/SidePanel.tsx:
- Update to 3-tab interface (Tracks | Track FX | Master FX)
- Track FX tab shows effects for currently selected track
- Master FX tab shows master bus effects with preset management
- Different icons for track vs master effects tabs
Note: Effect processing in Web Audio API not yet implemented.
This commit sets up the data structures and UI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed [object Object] display in Effect Chain section of SidePanel
by adding String() conversion to selectedTrack.name.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Explicitly whitelist track fields when saving to localStorage to prevent
DOM element references (HTMLButtonElement with React fiber) from being
serialized. This fixes the circular structure JSON error.
Changes:
- Changed from spread operator exclusion to explicit field whitelisting
- Ensured track.name is always converted to string
- Only serialize Track interface fields that should be persisted
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added string conversion and error handling when loading tracks from localStorage to prevent corrupted data from causing React rendering errors. If localStorage data is corrupted, it will be cleared automatically.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the "Converting circular structure to JSON" error in useMultiTrack by properly destructuring audioBuffer from track objects before serializing to localStorage.
Changed from spreading the entire track object (which could have circular refs) to explicitly excluding audioBuffer using destructuring.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>