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.
This commit is contained in:
2026-07-29 11:00:51 +07:00
parent ec355da58d
commit 8e8fc58082
3 changed files with 31 additions and 29 deletions
+21 -27
View File
@@ -11937,16 +11937,16 @@ const App = () => {
var selArr = Array.from(selIds);
var originals = {};
curTracks.forEach(function(t) {
(t.sections || []).forEach(function(s) {
if (selArr.indexOf(s.id) >= 0) originals[s.id] = { type: 'section', start: s.start };
});
(t.midiItems || []).forEach(function(m) {
if (selArr.indexOf(m.id) >= 0) originals[m.id] = { type: 'midiItem', start: m.startTime };
});
(t.clips || []).forEach(function(c) {
var cid = c.id === 'default' ? 'default_' + t.id : c.id;
if (selArr.indexOf(cid) >= 0) originals[cid] = { type: 'clip', start: c.startTime };
});
(t.sections || []).forEach(function(s) {
if (selArr.indexOf(s.id) >= 0) originals[s.id] = { type: 'section', start: s.start, trackId: t.id };
});
(t.midiItems || []).forEach(function(m) {
if (selArr.indexOf(m.id) >= 0) originals[m.id] = { type: 'midiItem', start: m.startTime, trackId: t.id };
});
(t.clips || []).forEach(function(c) {
var cid = c.id === 'default' ? 'default_' + t.id : c.id;
if (selArr.indexOf(cid) >= 0) originals[cid] = { type: 'clip', start: c.startTime, trackId: t.id };
});
});
if (Object.keys(originals).length > 0) multiIds = originals;
}
@@ -12066,18 +12066,6 @@ const App = () => {
if (sec || mid) { movedItem = sec || mid; break; }
}
if (drag.multiIds) {
var currentTrackMap = {};
Object.keys(drag.multiIds).forEach(function(mid) {
for (var pi = 0; pi < prev.length; pi++) {
var pt = prev[pi];
var f = false;
var inf = drag.multiIds[mid];
if (inf.type === 'section') f = (pt.sections || []).some(function(s) { return s.id === mid; });
else if (inf.type === 'midiItem') f = (pt.midiItems || []).some(function(mx) { return mx.id === mid; });
else if (inf.type === 'clip') f = (pt.clips || []).some(function(cx) { return cx.id === mid || 'default_' + pt.id === mid; });
if (f) { currentTrackMap[mid] = pt.id; break; }
}
});
var dragOrigStart = drag.multiIds[drag.itemId] ? drag.multiIds[drag.itemId].start : 0;
var delta = newStart - dragOrigStart;
return prev.map(function(t) {
@@ -12087,13 +12075,19 @@ const App = () => {
Object.keys(drag.multiIds).forEach(function(mid) {
var inf = drag.multiIds[mid];
var newVal = inf.start + delta;
var srcTid = currentTrackMap[mid];
var srcIdx = trkIds.indexOf(srcTid);
if (srcIdx < 0) srcIdx = baseIdx;
var itemTrgIdx = Math.max(0, srcIdx + crossOffset);
// Use ORIGINAL trackId stored at drag start for track offset math
var origTid = inf.trackId;
var origIdx = trkIds.indexOf(origTid);
if (origIdx < 0) origIdx = baseIdx;
var itemTrgIdx = Math.max(0, origIdx + crossOffset);
var itemTid = itemTrgIdx < prev.length ? prev[itemTrgIdx].id : null;
if (!itemTid) return;
if (srcTid === t.id && t.id !== itemTid) {
// Remove from source if leaving for another track
var isOnThisTrack = false;
if (inf.type === 'section') isOnThisTrack = (t.sections || []).some(function(s) { return s.id === mid; });
else if (inf.type === 'midiItem') isOnThisTrack = (t.midiItems || []).some(function(mx) { return mx.id === mid; });
else if (inf.type === 'clip') isOnThisTrack = (t.clips || []).some(function(cx) { return cx.id === mid || 'default_' + t.id === mid; });
if (isOnThisTrack && t.id !== itemTid) {
if (inf.type === 'section') resS = resS.filter(function(s) { return s.id !== mid; });
else if (inf.type === 'midiItem') resM = resM.filter(function(mx) { return mx.id !== mid; });
else if (inf.type === 'clip') { var c3 = 'default_' + t.id; resC = resC.filter(function(cx) { return cx.id !== mid && cx.id !== c3; }); }