mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
refactor: improve timeline elements, fix few bugs
This commit is contained in:
@@ -75,11 +75,10 @@ export function Timeline() {
|
|||||||
splitAndKeepRight,
|
splitAndKeepRight,
|
||||||
toggleTrackMute,
|
toggleTrackMute,
|
||||||
separateAudio,
|
separateAudio,
|
||||||
undo,
|
|
||||||
redo,
|
|
||||||
snappingEnabled,
|
snappingEnabled,
|
||||||
toggleSnapping,
|
toggleSnapping,
|
||||||
dragState,
|
dragState,
|
||||||
|
justFinishedDragging,
|
||||||
} = useTimelineStore();
|
} = useTimelineStore();
|
||||||
const { mediaItems, addMediaItem } = useMediaStore();
|
const { mediaItems, addMediaItem } = useMediaStore();
|
||||||
const { activeProject } = useProjectStore();
|
const { activeProject } = useProjectStore();
|
||||||
@@ -162,21 +161,16 @@ export function Timeline() {
|
|||||||
// Timeline content click to seek handler
|
// Timeline content click to seek handler
|
||||||
const handleTimelineContentClick = useCallback(
|
const handleTimelineContentClick = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
console.log(
|
|
||||||
JSON.stringify({
|
|
||||||
timelineClick: {
|
|
||||||
isSelecting,
|
|
||||||
justFinishedSelecting,
|
|
||||||
willReturn: isSelecting || justFinishedSelecting,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Don't seek if this was a selection box operation
|
// Don't seek if this was a selection box operation
|
||||||
if (isSelecting || justFinishedSelecting) {
|
if (isSelecting || justFinishedSelecting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't seek if we just finished dragging an element
|
||||||
|
if (justFinishedDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't seek if clicking on timeline elements, but still deselect
|
// Don't seek if clicking on timeline elements, but still deselect
|
||||||
if ((e.target as HTMLElement).closest(".timeline-element")) {
|
if ((e.target as HTMLElement).closest(".timeline-element")) {
|
||||||
return;
|
return;
|
||||||
@@ -193,6 +187,19 @@ export function Timeline() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MAIN FIX: Only seek on direct clicks to timeline background areas
|
||||||
|
// Check if the click is on the actual timeline background, not on any interactive elements
|
||||||
|
const target = e.target as HTMLElement;
|
||||||
|
const isTimelineBackground =
|
||||||
|
target.classList.contains("track-elements-container") ||
|
||||||
|
target.closest("[data-ruler-area]") ||
|
||||||
|
target.classList.contains("timeline-track-background");
|
||||||
|
|
||||||
|
if (!isTimelineBackground) {
|
||||||
|
clearSelectedElements();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear selected elements when clicking empty timeline area
|
// Clear selected elements when clicking empty timeline area
|
||||||
console.log(JSON.stringify({ clearingSelectedElements: true }));
|
console.log(JSON.stringify({ clearingSelectedElements: true }));
|
||||||
clearSelectedElements();
|
clearSelectedElements();
|
||||||
@@ -249,6 +256,7 @@ export function Timeline() {
|
|||||||
clearSelectedElements,
|
clearSelectedElements,
|
||||||
isSelecting,
|
isSelecting,
|
||||||
justFinishedSelecting,
|
justFinishedSelecting,
|
||||||
|
justFinishedDragging,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,12 @@ export function useTimelineElementResize({
|
|||||||
const trimDelta = newTrimStart - resizing.initialTrimStart;
|
const trimDelta = newTrimStart - resizing.initialTrimStart;
|
||||||
const newStartTime = element.startTime + trimDelta;
|
const newStartTime = element.startTime + trimDelta;
|
||||||
|
|
||||||
onUpdateTrim(track.id, element.id, newTrimStart, resizing.initialTrimEnd);
|
onUpdateTrim(
|
||||||
|
track.id,
|
||||||
|
element.id,
|
||||||
|
newTrimStart,
|
||||||
|
resizing.initialTrimEnd
|
||||||
|
);
|
||||||
updateElementStartTime(track.id, element.id, newStartTime);
|
updateElementStartTime(track.id, element.id, newStartTime);
|
||||||
} else {
|
} else {
|
||||||
// Trying to extend beyond trimStart = 0
|
// Trying to extend beyond trimStart = 0
|
||||||
@@ -132,7 +137,12 @@ export function useTimelineElementResize({
|
|||||||
const trimDelta = newTrimStart - resizing.initialTrimStart;
|
const trimDelta = newTrimStart - resizing.initialTrimStart;
|
||||||
const newStartTime = element.startTime + trimDelta;
|
const newStartTime = element.startTime + trimDelta;
|
||||||
|
|
||||||
onUpdateTrim(track.id, element.id, newTrimStart, resizing.initialTrimEnd);
|
onUpdateTrim(
|
||||||
|
track.id,
|
||||||
|
element.id,
|
||||||
|
newTrimStart,
|
||||||
|
resizing.initialTrimEnd
|
||||||
|
);
|
||||||
updateElementStartTime(track.id, element.id, newStartTime);
|
updateElementStartTime(track.id, element.id, newStartTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,11 +185,13 @@ export function useTimelineElementResize({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleResizeMove = (e: React.MouseEvent) => {
|
|
||||||
updateTrimFromMouseMove(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleResizeEnd = () => {
|
const handleResizeEnd = () => {
|
||||||
|
console.log(
|
||||||
|
JSON.stringify({
|
||||||
|
resizeEnd: true,
|
||||||
|
timeStamp: Date.now(),
|
||||||
|
})
|
||||||
|
);
|
||||||
setResizing(null);
|
setResizing(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ interface TimelineStore {
|
|||||||
clickOffsetTime: number;
|
clickOffsetTime: number;
|
||||||
currentTime: number;
|
currentTime: number;
|
||||||
};
|
};
|
||||||
|
justFinishedDragging: boolean;
|
||||||
setDragState: (dragState: Partial<TimelineStore["dragState"]>) => void;
|
setDragState: (dragState: Partial<TimelineStore["dragState"]>) => void;
|
||||||
startDrag: (
|
startDrag: (
|
||||||
elementId: string,
|
elementId: string,
|
||||||
@@ -230,6 +231,8 @@ export const useTimelineStore = create<TimelineStore>((set, get) => {
|
|||||||
// Snapping settings defaults
|
// Snapping settings defaults
|
||||||
snappingEnabled: true,
|
snappingEnabled: true,
|
||||||
|
|
||||||
|
justFinishedDragging: false,
|
||||||
|
|
||||||
getSortedTracks: () => {
|
getSortedTracks: () => {
|
||||||
const { _tracks } = get();
|
const { _tracks } = get();
|
||||||
const tracksWithMain = ensureMainTrack(_tracks);
|
const tracksWithMain = ensureMainTrack(_tracks);
|
||||||
@@ -938,7 +941,12 @@ export const useTimelineStore = create<TimelineStore>((set, get) => {
|
|||||||
clickOffsetTime: 0,
|
clickOffsetTime: 0,
|
||||||
currentTime: 0,
|
currentTime: 0,
|
||||||
},
|
},
|
||||||
|
justFinishedDragging: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
set({ justFinishedDragging: false });
|
||||||
|
}, 50);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Persistence methods
|
// Persistence methods
|
||||||
|
|||||||
Reference in New Issue
Block a user