fix: selectedItemIds snapshot includes toggled item for drag
React batches setSelectedItemIds, so when handleSetPendingDrag snapshots selectedItemIds, the just-toggled item isn't included yet. Fix: pass wasAlreadySelected boolean from TimelineTrack mousedown; handleSetPendingDrag manually applies the toggle (add/delete) to the snapshot so drag uses correct selection.
This commit is contained in:
+17
-10
@@ -1084,13 +1084,14 @@ const WaveformLane = ({
|
||||
e.stopPropagation();
|
||||
if (e.ctrlKey) {
|
||||
// Ctrl+Click: toggle selection only, never start drag immediately
|
||||
if (selectedItemIds && selectedItemIds.has(hitItem.id)) {
|
||||
var ctrlWasSelected = selectedItemIds && selectedItemIds.has(hitItem.id);
|
||||
if (ctrlWasSelected) {
|
||||
if (onDeselectItem) onDeselectItem(hitItem.id);
|
||||
} else if (onAddToSelection) {
|
||||
onAddToSelection(hitItem.id);
|
||||
}
|
||||
// Store pending drag so mousemove can start copy-drag
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, hitItem.type, hitItem.id, time - hitItem.start, e.nativeEvent || e);
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, hitItem.type, hitItem.id, time - hitItem.start, e.nativeEvent || e, ctrlWasSelected);
|
||||
} else {
|
||||
// No modifier: start drag immediately (single or multi move)
|
||||
if (onSectionItemDragStart) onSectionItemDragStart(track.id, hitItem.type, hitItem.id, time - hitItem.start, false);
|
||||
@@ -1152,12 +1153,13 @@ const WaveformLane = ({
|
||||
if (e.ctrlKey) {
|
||||
// Ctrl+Click: toggle selection, store pending drag
|
||||
var clipCanonicalId = clickedClip.id === 'default' ? 'default_' + track.id : clickedClip.id;
|
||||
if (selectedItemIds && selectedItemIds.has(clipCanonicalId)) {
|
||||
var ctrlClipSelected = selectedItemIds && selectedItemIds.has(clipCanonicalId);
|
||||
if (ctrlClipSelected) {
|
||||
if (onDeselectItem) onDeselectItem(clipCanonicalId);
|
||||
} else if (onAddToSelection) {
|
||||
onAddToSelection(clipCanonicalId);
|
||||
}
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, 'clip', clipCanonicalId, time - clickedClip.startTime, e.nativeEvent || e);
|
||||
if (onSetPendingDrag) onSetPendingDrag(track.id, 'clip', clipCanonicalId, time - clickedClip.startTime, e.nativeEvent || e, ctrlClipSelected);
|
||||
} else {
|
||||
// Alt+Click: move immediately
|
||||
if (onClipDragStart) onClipDragStart(track.id, clickedClip.id, time - clickedClip.startTime, false);
|
||||
@@ -11664,8 +11666,11 @@ const App = () => {
|
||||
return next;
|
||||
});
|
||||
};
|
||||
const handleSetPendingDrag = (trackId, itemType, itemId, clickOffset, e) => {
|
||||
pendingDragRef.current = { trackId, itemType, itemId, clickOffset, startX: e.clientX, startY: e.clientY };
|
||||
const handleSetPendingDrag = (trackId, itemType, itemId, clickOffset, e, wasAlreadySelected) => {
|
||||
var snap = new Set(selectedItemIds);
|
||||
if (wasAlreadySelected) snap.delete(itemId);
|
||||
else snap.add(itemId);
|
||||
pendingDragRef.current = { trackId, itemType, itemId, clickOffset, startX: e.clientX, startY: e.clientY, selectedIds: snap };
|
||||
};
|
||||
|
||||
// ── Sweep Select ──
|
||||
@@ -11680,11 +11685,12 @@ const App = () => {
|
||||
};
|
||||
|
||||
// ── Section / MIDI Item Drag Start ──
|
||||
const handleSectionItemDragStart = (trackId, itemType, itemId, clickOffset, isDuplicate) => {
|
||||
const handleSectionItemDragStart = (trackId, itemType, itemId, clickOffset, isDuplicate, pendingSelectedIds) => {
|
||||
var curTracks = activeTracksRef.current || activeTracks;
|
||||
var multiIds = null;
|
||||
if (selectedItemIds && selectedItemIds.size > 0 && selectedItemIds.has(itemId)) {
|
||||
var selArr = Array.from(selectedItemIds);
|
||||
var selIds = pendingSelectedIds || selectedItemIds;
|
||||
if (selIds && selIds.size > 0 && selIds.has(itemId)) {
|
||||
var selArr = Array.from(selIds);
|
||||
var originals = {};
|
||||
curTracks.forEach(function(t) {
|
||||
(t.sections || []).forEach(function(s) {
|
||||
@@ -11876,8 +11882,9 @@ const App = () => {
|
||||
if (!pd) return;
|
||||
var dx = e.clientX - pd.startX;
|
||||
if (Math.abs(dx) > 5) {
|
||||
var pdSnap = pendingDragRef.current;
|
||||
pendingDragRef.current = null;
|
||||
if (handleSectionItemDragStartRef.current) handleSectionItemDragStartRef.current(pd.trackId, pd.itemType, pd.itemId, pd.clickOffset, true);
|
||||
if (handleSectionItemDragStartRef.current) handleSectionItemDragStartRef.current(pdSnap.trackId, pdSnap.itemType, pdSnap.itemId, pdSnap.clickOffset, true, pdSnap.selectedIds);
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
|
||||
Reference in New Issue
Block a user