From 68999b1605e22de31dc91f5b8bee4f21caf79c2e Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Thu, 9 Apr 2026 23:25:00 +1000 Subject: [PATCH] fix(timeline): prevent clip regions from overlapping during drag/resize The hasOverlap function in TimelineEditor checked zoom, trim, speed, and audio regions for overlap but was missing clip regions entirely. This caused clips to freely overlap each other when dragged or resized, leading to playback bugs when trimmed clips intersected. Add clip region overlap detection so the existing clampToNeighbours logic in TimelineWrapper correctly constrains clip boundaries. Closes #166 --- src/components/video-editor/timeline/TimelineEditor.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/video-editor/timeline/TimelineEditor.tsx b/src/components/video-editor/timeline/TimelineEditor.tsx index 3d09a0dd..55fdaf59 100644 --- a/src/components/video-editor/timeline/TimelineEditor.tsx +++ b/src/components/video-editor/timeline/TimelineEditor.tsx @@ -967,6 +967,7 @@ export default function TimelineEditor({ // Determine which row the item belongs to const isZoomItem = zoomRegions.some(r => r.id === excludeId); const isTrimItem = trimRegions.some(r => r.id === excludeId); + const isClipItem = clipRegions.some(r => r.id === excludeId); const isAnnotationItem = annotationRegions.some(r => r.id === excludeId); const isSpeedItem = speedRegions.some(r => r.id === excludeId); const isAudioItem = audioRegions.some(r => r.id === excludeId); @@ -976,7 +977,7 @@ export default function TimelineEditor({ } // Helper to check overlap against a specific set of regions - const checkOverlap = (regions: (ZoomRegion | TrimRegion | SpeedRegion | AudioRegion)[]) => { + const checkOverlap = (regions: (ZoomRegion | TrimRegion | ClipRegion | SpeedRegion | AudioRegion)[]) => { return regions.some((region) => { if (region.id === excludeId) return false; // True overlap: regions actually intersect (not just adjacent) @@ -992,6 +993,10 @@ export default function TimelineEditor({ return checkOverlap(trimRegions); } + if (isClipItem) { + return checkOverlap(clipRegions); + } + if (isSpeedItem) { return checkOverlap(speedRegions); } @@ -1001,7 +1006,7 @@ export default function TimelineEditor({ } return false; - }, [zoomRegions, trimRegions, annotationRegions, speedRegions, audioRegions]); + }, [zoomRegions, trimRegions, clipRegions, annotationRegions, speedRegions, audioRegions]); // Keep newly added timeline regions at the original short default instead of // scaling them with the full recording length.