diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx
index 18e1338..210a943 100644
--- a/apps/web/src/components/editor/timeline.tsx
+++ b/apps/web/src/components/editor/timeline.tsx
@@ -1254,8 +1254,24 @@ function TimelineTrackContent({
const [justFinishedDrag, setJustFinishedDrag] = useState(false);
const handleClipMouseDown = (e: React.MouseEvent, clip: any) => {
+ // Handle selection first
+ if (!justFinishedDrag) {
+ const isSelected = selectedClips.some(
+ (c) => c.trackId === track.id && c.clipId === clip.id
+ );
+
+ if (e.metaKey || e.ctrlKey || e.shiftKey) {
+ // Multi-selection mode: toggle the clip
+ 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
- const clipElement = e.currentTarget.parentElement as HTMLElement;
+ const clipElement = e.currentTarget as HTMLElement;
const clipRect = clipElement.getBoundingClientRect();
const clickOffsetX = e.clientX - clipRect.left;
const clickOffsetTime = clickOffsetX / (50 * zoomLevel);
@@ -1773,8 +1789,9 @@ function TimelineTrackContent({
return (
handleClipMouseDown(e, clip)}
onClick={(e) => {
e.stopPropagation();
@@ -1789,19 +1806,14 @@ function TimelineTrackContent({
return; // Don't handle selection when closing context menu
}
+ // Only handle deselection here (selection is handled in mouseDown)
const isSelected = selectedClips.some(
(c) => c.trackId === track.id && c.clipId === clip.id
);
- if (e.metaKey || e.ctrlKey || e.shiftKey) {
- // Multi-selection mode: toggle the clip
- selectClip(track.id, clip.id, true);
- } else if (isSelected) {
- // If clip is already selected, deselect it
+ if (isSelected && !e.metaKey && !e.ctrlKey && !e.shiftKey) {
+ // If clip is already selected and no modifier keys, deselect it
deselectClip(track.id, clip.id);
- } else {
- // If clip is not selected, select it (replacing other selections)
- selectClip(track.id, clip.id, false);
}
}}
tabIndex={0}
@@ -1820,13 +1832,13 @@ function TimelineTrackContent({
{/* Left trim handle */}
handleResizeStart(e, clip.id, "left")}
+ onMouseDown={(e) => {
+ e.stopPropagation(); // Prevent triggering clip drag
+ handleResizeStart(e, clip.id, "left");
+ }}
/>
{/* Clip content */}
-
handleClipMouseDown(e, clip)}
- >
+
{renderClipContent(clip)}
{/* Clip options menu */}
@@ -1835,11 +1847,15 @@ function TimelineTrackContent({
size="icon"
className="opacity-0 group-hover:opacity-100 transition-opacity"
onClick={() => setClipMenuOpen(clip.id)}
+ onMouseDown={(e) => e.stopPropagation()}
>
{clipMenuOpen === clip.id && (
-
+
e.stopPropagation()}
+ >