diff --git a/apps/web/src/hooks/use-timeline-element-resize.ts b/apps/web/src/hooks/use-timeline-element-resize.ts index f16ca8e2..3afa637b 100644 --- a/apps/web/src/hooks/use-timeline-element-resize.ts +++ b/apps/web/src/hooks/use-timeline-element-resize.ts @@ -29,7 +29,12 @@ export function useTimelineElementResize({ }: UseTimelineElementResizeProps) { const [resizing, setResizing] = useState(null); const { mediaItems } = useMediaStore(); - const { updateElementStartTime } = useTimelineStore(); + const { + updateElementStartTime, + updateElementTrim, + updateElementDuration, + pushHistory, + } = useTimelineStore(); // Set up document-level mouse listeners during resize (like proper drag behavior) useEffect(() => { @@ -61,6 +66,9 @@ export function useTimelineElementResize({ e.stopPropagation(); e.preventDefault(); + // Push history once at the start of the resize operation + pushHistory(); + setResizing({ elementId, side, @@ -112,13 +120,14 @@ export function useTimelineElementResize({ const trimDelta = newTrimStart - resizing.initialTrimStart; const newStartTime = element.startTime + trimDelta; - onUpdateTrim( + updateElementTrim( track.id, element.id, newTrimStart, - resizing.initialTrimEnd + resizing.initialTrimEnd, + false ); - updateElementStartTime(track.id, element.id, newStartTime); + updateElementStartTime(track.id, element.id, newStartTime, false); } else { // Trying to extend beyond trimStart = 0 if (canExtendElementDuration()) { @@ -128,22 +137,29 @@ export function useTimelineElementResize({ const newDuration = element.duration + extensionAmount; // Keep trimStart at 0 and extend the element - onUpdateTrim(track.id, element.id, 0, resizing.initialTrimEnd); - onUpdateDuration(track.id, element.id, newDuration); - updateElementStartTime(track.id, element.id, newStartTime); + updateElementTrim( + track.id, + element.id, + 0, + resizing.initialTrimEnd, + false + ); + updateElementDuration(track.id, element.id, newDuration, false); + updateElementStartTime(track.id, element.id, newStartTime, false); } else { // Video/Audio: can't extend beyond original content - limit to trimStart = 0 const newTrimStart = 0; const trimDelta = newTrimStart - resizing.initialTrimStart; const newStartTime = element.startTime + trimDelta; - onUpdateTrim( + updateElementTrim( track.id, element.id, newTrimStart, - resizing.initialTrimEnd + resizing.initialTrimEnd, + false ); - updateElementStartTime(track.id, element.id, newStartTime); + updateElementStartTime(track.id, element.id, newStartTime, false); } } } else { @@ -159,27 +175,35 @@ export function useTimelineElementResize({ const newTrimEnd = 0; // Reset trimEnd to 0 since we're extending // Update duration first, then trim - onUpdateDuration(track.id, element.id, newDuration); - onUpdateTrim( + updateElementDuration(track.id, element.id, newDuration, false); + updateElementTrim( track.id, element.id, resizing.initialTrimStart, - newTrimEnd + newTrimEnd, + false ); } else { // Can't extend - just set trimEnd to 0 (maximum possible extension) - onUpdateTrim(track.id, element.id, resizing.initialTrimStart, 0); + updateElementTrim( + track.id, + element.id, + resizing.initialTrimStart, + 0, + false + ); } } else { // Normal trimming within original duration const maxTrimEnd = element.duration - resizing.initialTrimStart - 0.1; // Leave at least 0.1s visible const newTrimEnd = Math.max(0, Math.min(maxTrimEnd, calculated)); - onUpdateTrim( + updateElementTrim( track.id, element.id, resizing.initialTrimStart, - newTrimEnd + newTrimEnd, + false ); } } diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts index 1fcfc60e..01ad1635 100644 --- a/apps/web/src/stores/timeline-store.ts +++ b/apps/web/src/stores/timeline-store.ts @@ -106,17 +106,20 @@ interface TimelineStore { trackId: string, elementId: string, trimStart: number, - trimEnd: number + trimEnd: number, + pushHistory?: boolean ) => void; updateElementDuration: ( trackId: string, elementId: string, - duration: number + duration: number, + pushHistory?: boolean ) => void; updateElementStartTime: ( trackId: string, elementId: string, - startTime: number + startTime: number, + pushHistory?: boolean ) => void; toggleTrackMute: (trackId: string) => void; @@ -687,8 +690,14 @@ export const useTimelineStore = create((set, get) => { updateTracksAndSave(newTracks); }, - updateElementTrim: (trackId, elementId, trimStart, trimEnd) => { - get().pushHistory(); + updateElementTrim: ( + trackId, + elementId, + trimStart, + trimEnd, + pushHistory = true + ) => { + if (pushHistory) get().pushHistory(); updateTracksAndSave( get()._tracks.map((track) => track.id === trackId @@ -705,8 +714,13 @@ export const useTimelineStore = create((set, get) => { ); }, - updateElementDuration: (trackId, elementId, duration) => { - get().pushHistory(); + updateElementDuration: ( + trackId, + elementId, + duration, + pushHistory = true + ) => { + if (pushHistory) get().pushHistory(); updateTracksAndSave( get()._tracks.map((track) => track.id === trackId @@ -721,8 +735,13 @@ export const useTimelineStore = create((set, get) => { ); }, - updateElementStartTime: (trackId, elementId, startTime) => { - get().pushHistory(); + updateElementStartTime: ( + trackId, + elementId, + startTime, + pushHistory = true + ) => { + if (pushHistory) get().pushHistory(); updateTracksAndSave( get()._tracks.map((track) => track.id === trackId