Commit Graph

158 Commits

Author SHA1 Message Date
3dtours 437980ea9f feat(generator): post data to parent preset form 2026-07-31 06:43:01 +07:00
3dtours bc36e40967 feat(generator): apply md/50 transfer spec 2026-07-31 06:36:37 +07:00
3dtours 6ce77c4f20 fix(generator): anchor preview bottom to modal edge 2026-07-31 06:16:36 +07:00
3dtours bc951e75af feat(preset-manager): category dropdown + generator modal 2026-07-31 05:50:55 +07:00
3dtours 5e8664af1c FIX: sửa lỗi tải lại audioclip item bị mất tiếng 2026-07-30 22:33:26 +07:00
3dtours 323be6a6f4 fix: piano roll draw notes snapped to grid via getSnapBeat
note.start_beat + duration_beats snapped before rendering.
Applies to active, ghost, and recording notes.
2026-07-30 21:15:38 +07:00
3dtours 5ed6acd4f5 fix: piano roll snap values inverted in getSnapBeat/getSnapDuration/grid
snap='1' gave q=4.0 (4-beat snap). Fix all 3 mappings:
grid lines, note snap, default duration.
2026-07-30 21:08:56 +07:00
3dtours 6c227fe6af fix: draw clip rect/label always, skip only waveform when buffer null
- clip rect + label + markers drawn even without buffer
- shows '(audio chưa được tải)' for unloaded clips
- deserialize restores clip duration from duration_bars
2026-07-30 21:05:33 +07:00
3dtours 7b8e10419f fix: snap default '1' + Power button reads masterConnected directly
- snapValue default '1' (was 'free'), piano roll snapVal default '1' (was '1/16')
- Power button: remove shared isFxActive, use masteringSettings.masterConnected
2026-07-30 20:59:29 +07:00
3dtours 4005088e89 fix: audio clip items lost after reload — missing serverFileId on clip/track
- set serverFileId on clip + track when upload succeeds
- serialize/deserialize server_file_id in source_data
- guard clip.buffer null in WaveformLane canvas draw
2026-07-30 20:54:23 +07:00
3dtours 9c487614f1 feat: auto-save 5min + backup 30min + backup management UI
- project_backups table + DB migration
- Backup CRUD API endpoints with auto cleanup (5-20 retention)
- setInterval 5min save + 30min backup in browser
- ProfileModal: backup list, delete, retention slider, cleanup button
2026-07-30 20:48:45 +07:00
3dtours 313d1be5af fix: loadAudioBuffersForTracks scoped in ProfileModal crashes project load
Move fn to App component scope, pass as prop to ProfileModal.
restoreLastSessionProject now has access on startup.
2026-07-30 20:40:25 +07:00
3dtours 3386a2b4c2 feat: add structured preset button in AI Preset Manager
Add handleNewStructured fn + emerald button left of Quay lại
pre-fills form with comprehensive Vietnamese template sections
2026-07-30 20:33:22 +07:00
3dtours b67c0264fb feat(mixer): Master + Track Strip Console per specs 47/48 2026-07-30 12:55:35 +07:00
3dtours 74597cfe8b feat(mixer): install Master Strip Console per spec 47 2026-07-30 12:47:10 +07:00
3dtours d4ad3bc1f7 feat: add comprehensive Ctrl-Z/Ctrl-Y undo/redo engine for MAIN SESSION and SECTION-TAB 2026-07-29 16:05:43 +07:00
3dtours a1767e338a fix: Select Instrument stays open after picking instrument
Remove setInstrumentSelectorTrackId(null) from
setTrackInstrumentWithProgram. Modal stays open so user can
switch tracks and assign instruments without reopening.
2026-07-29 11:56:26 +07:00
3dtours 8051cf3edb fix: add missing aiTypeaheadRef definition 2026-07-29 11:52:49 +07:00
3dtours 35e767795a fix: Synth button opens modal with inline track selector
Remove external track dropdown. Add select dropdown inside the
instrument selector modal between title and search box. Users
can switch tracks without closing the modal.
2026-07-29 11:52:12 +07:00
3dtours 7bfdd72850 feat: Synth button shows track dropdown for quick instrument assign
Synth button opens a dropdown listing all tracks instead of opening
the modal directly. Selecting a track opens the instrument selector
for that track. No need to close modal and click each track's Synth.
2026-07-29 11:49:34 +07:00
3dtours 41b5a70a60 fix: AI SUGGEST auto-updates after saving preset in manager
Add aiPresetVersion counter. Increment on modal close. AI panel
compares version and calls loadPresets() to sync from localStorage.
2026-07-29 11:45:31 +07:00
3dtours a3e681afc0 fix: re-fetch instrument data after login for new machines
Auth success handler now eagerly loads instrumentSelectorData
via listPlugins + getSoundfontCatalog. The mount-time useEffect
runs before auth token is set, so it silently fails on new machines.
2026-07-29 11:34:50 +07:00
3dtours 8775c960e3 fix: seed_admin() no longer resets admin password on restart
Remove hash verification + password reset logic. seed_admin() now
only creates the admin account if it does not exist. Prevents
password being reset to default + must_change_password flag
being set on every server restart.
2026-07-29 11:28:49 +07:00
3dtours d4262acb9f fix: rewrite drag handler with stable crossOffset + outTracks merge 2026-07-29 11:13:31 +07:00
3dtours e40fdf15ad fix: use original baseTrackId for crossOffset, never update drag.trackId 2026-07-29 11:10:59 +07:00
3dtours 0d763c5a0b fix: targetTrackId undefined outside updateActiveTracks closure
Move track Y-position computation before updateActiveTracks so
targetTrackId is accessible for setDraggedSectionItem update.
2026-07-29 11:09:05 +07:00
3dtours ad6fa1feb9 fix: auto-add tracks when drag exceeds track count
Compute maxTargetIdx across all multiIds items. Prepend new
tracks to prev array before mapping if needed.
2026-07-29 11:08:11 +07:00
3dtours 9abb0e6a50 fix: cross-track drag computes target from mouse Y position
Replace hoveredTrackIdRef with Y-position calculation through
track heights from prev state. Works reliably during drag.
2026-07-29 11:03:30 +07:00
3dtours 6c6a326b7d fix: single-item cross-track drag
Each track filters the item independently. Only target track
receives the inserted item. Removes duplicate state update.
2026-07-29 11:02:03 +07:00
3dtours 8e8fc58082 fix: group drag uses original trackId for offset math
Store trackId in multiIds at drag start. Each item computes
target from original track + crossOffset, immune to stale state
from previous drag events. Track 1 item drags n tracks -> track
1+n, track 2 item -> track 2+n, etc.
2026-07-29 11:00:51 +07:00
3dtours ec355da58d fix: group drag cross-track uses live prev state for index mapping
Build trkIds from prev (updateActiveTracks callback) instead of
stale activeTracksRef. Fix srcItem lookup with proper for loop.
2026-07-29 10:55:39 +07:00
3dtours 9c3a435f26 fix: group drag cross-track maintains relative track offsets
Each item computes its own target track as srcIdx + crossOffset.
Items from different source tracks land on different target tracks,
preserving the group's vertical layout shape.
2026-07-29 10:52:50 +07:00
3dtours 12d2639455 fix: group drag keeps items on their original tracks
Remove all cross-track logic in multiIds path. Each item only
updates its time position (delta) on its current track. No
merging or track reassignment.
2026-07-29 10:50:37 +07:00
3dtours e99bc8624f fix: group drag moves all items, clamp to track 0, auto-add track
Restore multiIds cross-track move for all selected items.
Clamp targetTrackId to first track. Auto-add new track via
addNewTrack() when dragging below the last track.
2026-07-29 10:47:53 +07:00
3dtours 9869566d3e fix: multi-item drag no longer merges all items into target track
Only the dragged item (drag.itemId) crosses tracks. Other selected
items stay on their original tracks and only move horizontally.
2026-07-29 10:42:42 +07:00
3dtours e544d5e694 fix: show all presets always, no filter by selection
Remove selection-based filter entirely. Suggestions list stays
stable across select/deselect — no preset appears at top when
deselecting.
2026-07-29 10:18:47 +07:00
3dtours 614d83b971 fix: filter excludes non-rearrange presets in AI suggestion list
Remove || p.is_favorite from filter when MIDI item selected.
Only presets with category === 'Rearrange / Variation' appear.
2026-07-29 10:17:36 +07:00
3dtours 895ad0b7d9 fix: restore AI suggestion filter by selection, cache PromptTemplateManager
Cache PromptTemplateManager in ref to prevent new instance per
render. Filter: show only Rearrange/favorites when MIDI item
selected, all presets otherwise. Root cause of 'suggestion added
at top' was stale array reference from new instance every render.
2026-07-29 10:11:10 +07:00
3dtours 98ca21bd9a fix: AI Suggestion list changing on item select/deselect
Always show full preset list instead of filtering to rearrange/
favorites when item selected. Prevents suggestion list from
visually changing during selection/deselection.
2026-07-29 10:08:05 +07:00
3dtours 5ed943b3d6 fix: stuck MIDI notes when ARM toggled off mid-note
Remove !st.isArmed guard in note-off handler. Stop note on ALL
tracks regardless of ARM state — FluidSynth stopNote on inactive
channel/pitch is a no-op, so this is safe.
2026-07-29 10:02:30 +07:00
3dtours b00f0cff95 feat: mixer VU meter, fader scaling, track name color
- Master strip: add fader placeholder + VU meter bar
- MixerStrip: items-end -> items-stretch so fader + VU fill height
- VU meter: bar height maps volumeDb, color green/amber/red
- Track name uses track.color instead of fixed text-zinc-400
2026-07-29 09:54:18 +07:00
3dtours 2187440681 feat: Mixer Panel display-only with F7 toggle
Add MixerStrip component for display-only track strips (no audio
routing). Mixer panel at bottom with drag resize handle (80-400px).
F7 keyboard shortcut, status bar toggle button, View menu item.
onUpdateTrack handles mute/solo/volume changes directly on tracks.
2026-07-29 09:49:47 +07:00
3dtours bb49035bee fix: sửa lỗi xóa track khi nhấn phím Del, đúng là phải xóa items được chọn 2026-07-28 19:34:47 +07:00
3dtours cff3950670 feat: AI Copilot suggestion chips + typeahead dropdown
- Suggestion chips bar: context-aware (amber for rearrange, indigo for creation)
- Typeahead dropdown: keyword matching on ≥2 chars, Tab to select
- getSelectedMidiItemInfo helper for context detection
- Backend: 4 rearrange presets in ai_presets.py
- PromptTemplateManager: getContextualSuggestions(hasSelectedItem)
2026-07-28 11:20:26 +07:00
3dtours 3f7abe0c95 feat: AI Rearrange Scenario Detection from spec 45_SCENARIAO_AI
- 9 rearrange scenarios with keyword matching (arpeggio, harmonies,
  syncopation, walking bass, jazz, synthwave, cinematic, simplify, chromatic)
- detectRearrangeScenario() maps user prompt to specific technique rules
- buildRearrangeMessage auto-injects scenario-specific technique guidance
- 9 rearrange presets added to PromptTemplateManager (Rearrange / Variation)
2026-07-28 11:03:26 +07:00
3dtours 2eb327056d fix: MIDI Rearrange — selected item triggers dedicated tool flow
- midiExtractor.js: extractSelectedMIDIContext with note name conversion
- aiGateway.js: REARRANGE_TOOL_SPEC + buildRearrangeMessage
- dawCommandDispatcher.js: register REARRANGE_MIDI_MELODY command
- app.jsx: handleAISend detects selected MIDI item → rearrange flow
- rearrangeMidiMelody handler places A/B track below source track
2026-07-28 10:54:35 +07:00
3dtours 421535ca0e feat: AI MIDI Prompt Template & Preset Engine
- promptTemplateManager.js: standalone service with keyword scoring, CRUD, fav toggle
- ai_presets.py: backend CRUD router (JSON file, auth isolation)
- AIPresetModal: PromptTemplateManager, star/fav column, backend API sync
- Piano Roll AI: preset matching support
- 7 tests: matching, CRUD, anonymous auth, user isolation
2026-07-28 10:42:30 +07:00
3dtours 10c0a743c6 feat: CC lane dropdown with Velocity, Sustain, Modulation, Pitch Bend, Pan
Replaced flex div with velocity/pan buttons with a
<select> dropdown containing 5 CC type options.
Default: Velocity. Button toggle shows short label.
2026-07-28 10:20:52 +07:00
3dtours b5f3f987b7 fix: Ctrl+click empty space starts sweep select with yellow cursor
Line 1163 called onSweepSelectStart which set up sweep
state (yellow selection rectangle). Mousemove then
selected all items in the sweep range. Changed to
onClearSelection = () => setSelectedItemIds(new Set())
which only clears selection without starting sweep.
2026-07-28 10:10:05 +07:00
3dtours 5ec329933a fix: Ctrl+S in SECTION-TAB exports SF instead of saving section
First Ctrl+S handler (line 8066, handleExportSFS) catches
ALL Ctrl+S before second handler (line 8157, save section)
ever runs. Moved section-tab check into first handler:
activeTab.startsWith('session_') -> handleSaveSectionTab.
Main session Ctrl+S still exports SF (same as before).
2026-07-28 10:07:02 +07:00