From e1550c8ffe8de0ad3ddc7ef03956543d4e43d249 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Fri, 31 Jul 2026 08:15:56 +0700 Subject: [PATCH] fix: insert noteB after noteA in split, not at end of array --- app/static/js/app.jsx | 9 ++++++++- app/static/js/app.precompiled.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 3556243..4c15961 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -6522,7 +6522,14 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos start_beat: splitBeat, duration_beats: target.start_beat + target.duration_beats - splitBeat }; - setNotes(prev => prev.map(n => n.id === target.id ? noteA : n).concat([noteB])); + setNotes(prev => { + const idx = prev.findIndex(n => n.id === target.id); + if (idx === -1) return prev; + const result = [...prev]; + result.splice(idx, 1, noteA); + result.splice(idx + 1, 0, noteB); + return result; + }); setSelectedNoteIds([noteA.id, noteB.id]); showToast('Đã tách nốt!', 'info'); } diff --git a/app/static/js/app.precompiled.js b/app/static/js/app.precompiled.js index 28812da..1a7f407 100644 --- a/app/static/js/app.precompiled.js +++ b/app/static/js/app.precompiled.js @@ -194,7 +194,7 @@ const clickedNoteIdx=notes.findIndex(n=>{return pitch===n.pitch&&beat>=n.start_b if(clickedNoteIdx!==-1&&!e.ctrlKey&&!e.shiftKey&&!e.altKey){if(window.SonicSF){const ctx=getAudioContext();var clTrk=activeTracks.find(function(t){return t.id===st.trackId;});var clCh=window.SonicPianoRoll?window.SonicPianoRoll.getTrackMidiChannel(clTrk,activeTracks):clTrk?clTrk.midiChannel:0;window.SonicSF.playNote(notes[clickedNoteIdx].pitch,100,300,ctx.currentTime,st.instrumentProgram,null,clCh,clTrk?clTrk.synth_engine:undefined);}}// Ctrl+click: toggle selection (multi-select) if(e.ctrlKey&&!e.altKey&&!e.shiftKey){if(clickedNoteIdx!==-1){const clickedNote=notes[clickedNoteIdx];if(selectedNoteIds.includes(clickedNote.id)){setSelectedNoteIds(prev=>prev.filter(id=>id!==clickedNote.id));}else{setSelectedNoteIds(prev=>[...prev,clickedNote.id]);}return;}else{// Ctrl+click on empty space: start selection marquee setSelectedNoteIds([]);const snapStart=getSnapBeat(beat,snapValue);setSelectionMarquee({startBeat:snapStart,startPitch:pitch,currentBeat:snapStart,currentPitch:pitch});return;}}// Ctrl+Shift+click on note → split at click position -if(e.ctrlKey&&e.shiftKey){if(clickedNoteIdx!==-1){const target=notes[clickedNoteIdx];const splitBeat=getSnapBeat(beat,snapValue);if(splitBeat>target.start_beat+0.03125&&splitBeatprev.map(n=>n.id===target.id?noteA:n).concat([noteB]));setSelectedNoteIds([noteA.id,noteB.id]);showToast('Đã tách nốt!','info');}}else{// Ctrl+Shift+click on empty space → duplicate selected notes +if(e.ctrlKey&&e.shiftKey){if(clickedNoteIdx!==-1){const target=notes[clickedNoteIdx];const splitBeat=getSnapBeat(beat,snapValue);if(splitBeat>target.start_beat+0.03125&&splitBeat{const idx=prev.findIndex(n=>n.id===target.id);if(idx===-1)return prev;const result=[...prev];result.splice(idx,1,noteA);result.splice(idx+1,0,noteB);return result;});setSelectedNoteIds([noteA.id,noteB.id]);showToast('Đã tách nốt!','info');}}else{// Ctrl+Shift+click on empty space → duplicate selected + clicked notes pushToUndo(notes);const clones=notes.filter(n=>selectedNoteIds.includes(n.id)).map(n=>({...JSON.parse(JSON.stringify(n)),id:'note_'+Date.now()+Math.random().toString(36).substr(2,8)}));if(clones.length>0){setNotes(prev=>[...prev,...clones]);const cloneIds=clones.map(c=>c.id);setSelectedNoteIds(cloneIds);notesBeforeDragRef.current=JSON.parse(JSON.stringify(notes));const cloneOffsets=clones.map(n=>({id:n.id,originalStartBeat:n.start_beat,originalPitch:n.pitch}));setDraggedNote({mode:'move',idx:-1,startOffsetBeat:beat,startOffsetPitch:pitch,selectedNotesOffset:cloneOffsets});showToast('Đã nhân bản '+clones.length+' nốt!','info');}}return;}// Hovered resize edge (Alt+resize for scaling) if(hoveredResizeIdx!==-1&&e.altKey){pushToUndo(notes);notesBeforeDragRef.current=JSON.parse(JSON.stringify(notes));const allSelected=[...new Set(selectedNoteIds.length>0?selectedNoteIds:[notes[hoveredResizeIdx].id])];const selectedNotes=notes.filter(n=>allSelected.includes(n.id));const firstStart=Math.min(...selectedNotes.map(n=>n.start_beat));const draggedNote=notes[hoveredResizeIdx];setDraggedNote({mode:'scale',idx:hoveredResizeIdx,originalEnd:draggedNote.start_beat+draggedNote.duration_beats,firstStart:firstStart,selectedNoteIds:allSelected});return;}// Hovered resize edge (normal resize) if(hoveredResizeIdx!==-1){pushToUndo(notes);notesBeforeDragRef.current=JSON.parse(JSON.stringify(notes));setDraggedNote({mode:'resize',idx:hoveredResizeIdx,originalStart:notes[hoveredResizeIdx].start_beat});return;}if(clickedNoteIdx!==-1){// Click on existing note: drag-move