fix: clip being deselected after dragging it
This commit is contained in:
@ -936,6 +936,16 @@ export function Timeline() {
|
|||||||
y: e.clientY,
|
y: e.clientY,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
// If clicking empty area (not on a clip), deselect all clips
|
||||||
|
if (
|
||||||
|
!(e.target as HTMLElement).closest(".timeline-clip")
|
||||||
|
) {
|
||||||
|
const { clearSelectedClips } =
|
||||||
|
useTimelineStore.getState();
|
||||||
|
clearSelectedClips();
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<TimelineTrackContent
|
<TimelineTrackContent
|
||||||
track={track}
|
track={track}
|
||||||
@ -1162,8 +1172,10 @@ function TimelineTrackContent({
|
|||||||
const [dropPosition, setDropPosition] = useState<number | null>(null);
|
const [dropPosition, setDropPosition] = useState<number | null>(null);
|
||||||
const [wouldOverlap, setWouldOverlap] = useState(false);
|
const [wouldOverlap, setWouldOverlap] = useState(false);
|
||||||
const dragCounterRef = useRef(0);
|
const dragCounterRef = useRef(0);
|
||||||
|
const [mouseDownLocation, setMouseDownLocation] = useState<{
|
||||||
const [justFinishedDrag, setJustFinishedDrag] = useState(false);
|
x: number;
|
||||||
|
y: number;
|
||||||
|
} | null>(null);
|
||||||
|
|
||||||
// Set up mouse event listeners for drag
|
// Set up mouse event listeners for drag
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -1252,20 +1264,10 @@ function TimelineTrackContent({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const handleClipMouseDown = (e: React.MouseEvent, clip: TypeTimelineClip) => {
|
const handleClipMouseDown = (e: React.MouseEvent, clip: TypeTimelineClip) => {
|
||||||
// Handle selection first
|
setMouseDownLocation({ x: e.clientX, y: e.clientY });
|
||||||
if (!justFinishedDrag) {
|
// Handle multi-selection only in mousedown
|
||||||
const isSelected = selectedClips.some(
|
|
||||||
(c) => c.trackId === track.id && c.clipId === clip.id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||||
// Multi-selection mode: toggle the clip
|
|
||||||
selectClip(track.id, clip.id, true);
|
selectClip(track.id, clip.id, true);
|
||||||
} else if (!isSelected) {
|
|
||||||
// If clip is not selected, select it (replacing other selections)
|
|
||||||
selectClip(track.id, clip.id, false);
|
|
||||||
}
|
|
||||||
// Note: Don't deselect if already selected, as user might want to drag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the offset from the left edge of the clip to where the user clicked
|
// Calculate the offset from the left edge of the clip to where the user clicked
|
||||||
@ -1286,35 +1288,39 @@ function TimelineTrackContent({
|
|||||||
const handleClipClick = (e: React.MouseEvent, clip: TypeTimelineClip) => {
|
const handleClipClick = (e: React.MouseEvent, clip: TypeTimelineClip) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
console.log(
|
// Check if mouse moved significantly
|
||||||
"handleClipClick called, contextMenu:",
|
if (mouseDownLocation) {
|
||||||
JSON.stringify(contextMenu)
|
const deltaX = Math.abs(e.clientX - mouseDownLocation.x);
|
||||||
);
|
const deltaY = Math.abs(e.clientY - mouseDownLocation.y);
|
||||||
console.log("Boolean check:", !!contextMenu, "Type:", typeof contextMenu);
|
// If it moved more than a few pixels, consider it a drag and not a click.
|
||||||
|
if (deltaX > 5 || deltaY > 5) {
|
||||||
// Don't handle click if we just finished dragging
|
setMouseDownLocation(null); // Reset for next interaction
|
||||||
if (justFinishedDrag) {
|
|
||||||
console.log("Skipping because justFinishedDrag");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Close context menu if it's open
|
// Close context menu if it's open
|
||||||
if (contextMenu) {
|
if (contextMenu) {
|
||||||
console.log("Closing context menu");
|
|
||||||
setContextMenu(null);
|
setContextMenu(null);
|
||||||
return; // Don't handle selection when closing context menu
|
return; // Don't handle selection when closing context menu
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Proceeding to selection logic");
|
// Skip selection logic for multi-selection (handled in mousedown)
|
||||||
|
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Only handle deselection here (selection is handled in mouseDown)
|
// Handle single selection/deselection
|
||||||
const isSelected = selectedClips.some(
|
const isSelected = selectedClips.some(
|
||||||
(c) => c.trackId === track.id && c.clipId === clip.id
|
(c) => c.trackId === track.id && c.clipId === clip.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isSelected && !e.metaKey && !e.ctrlKey && !e.shiftKey) {
|
if (isSelected) {
|
||||||
// If clip is already selected and no modifier keys, deselect it
|
// If clip is selected, deselect it
|
||||||
deselectClip(track.id, clip.id);
|
deselectClip(track.id, clip.id);
|
||||||
|
} else {
|
||||||
|
// If clip is not selected, select it (replacing other selections)
|
||||||
|
selectClip(track.id, clip.id, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1330,17 +1336,6 @@ function TimelineTrackContent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reset drag flag when drag ends
|
|
||||||
useEffect(() => {
|
|
||||||
if (!dragState.isDragging && justFinishedDrag) {
|
|
||||||
const timer = setTimeout(() => setJustFinishedDrag(false), 50);
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
} else if (!dragState.isDragging && dragState.clipId && !justFinishedDrag) {
|
|
||||||
// Only set justFinishedDrag when a drag actually ends (not when it starts)
|
|
||||||
setJustFinishedDrag(true);
|
|
||||||
}
|
|
||||||
}, [dragState.isDragging, justFinishedDrag, dragState.clipId]);
|
|
||||||
|
|
||||||
const handleTrackDragOver = (e: React.DragEvent) => {
|
const handleTrackDragOver = (e: React.DragEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@ -1685,6 +1680,13 @@ function TimelineTrackContent({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
// If clicking empty area (not on a clip), deselect all clips
|
||||||
|
if (!(e.target as HTMLElement).closest(".timeline-clip")) {
|
||||||
|
const { clearSelectedClips } = useTimelineStore.getState();
|
||||||
|
clearSelectedClips();
|
||||||
|
}
|
||||||
|
}}
|
||||||
onDragOver={handleTrackDragOver}
|
onDragOver={handleTrackDragOver}
|
||||||
onDragEnter={handleTrackDragEnter}
|
onDragEnter={handleTrackDragEnter}
|
||||||
onDragLeave={handleTrackDragLeave}
|
onDragLeave={handleTrackDragLeave}
|
||||||
|
Reference in New Issue
Block a user