From 0ea8d7ce3342f2819f4a48b303336cfbc0ffe34a Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Tue, 19 May 2026 00:02:34 -0400 Subject: [PATCH] fix(timeline): cap right-trim at source asset boundary When duration_ms is known, dragging the right-trim handle past the end of the source clip could push timeline_out_frames beyond what the source material covers. Cap the delta so neither timeline_out_frames nor source_out_frames can extend past the available source frames. Also changed assetFrames fallback from origSrcOut (prevents any extension when duration is unknown) to null, so the guard is simply skipped when we don't have duration metadata. --- services/web-ui/public/js/timeline.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/services/web-ui/public/js/timeline.js b/services/web-ui/public/js/timeline.js index 61d30f1..4d0bcf8 100644 --- a/services/web-ui/public/js/timeline.js +++ b/services/web-ui/public/js/timeline.js @@ -337,14 +337,14 @@ var origTlOut = clip.timeline_out_frames; var origSrcIn = clip.source_in_frames; var origSrcOut = clip.source_out_frames; - // Maximum source out is the asset's full duration in frames + // Full asset duration in frames (null when unknown) var assetFrames = clip.duration_ms ? Math.round((clip.duration_ms / 1000) * s.fps) - : origSrcOut; + : null; function onMove(ev) { - var dx = ev.clientX - startX; - var dFr = pxToFrames(dx); + var dx = ev.clientX - startX; + var dFr = pxToFrames(dx); if (side === 'left') { var newTlIn = Math.max(0, Math.min(origTlIn + dFr, origTlOut - 1)); var dIn = newTlIn - origTlIn; @@ -353,8 +353,15 @@ } else { var newTlOut = Math.max(origTlIn + 1, origTlOut + dFr); var dOut = newTlOut - origTlOut; - clip.timeline_out_frames = newTlOut; - clip.source_out_frames = Math.min(assetFrames, origSrcOut + dOut); + // When we know the asset duration, don't extend past the source boundary + if (assetFrames !== null) { + var maxOut = assetFrames - origSrcOut; + if (dOut > maxOut) dOut = maxOut; + } + clip.timeline_out_frames = origTlOut + dOut; + clip.source_out_frames = assetFrames !== null + ? Math.min(assetFrames, origSrcOut + dOut) + : origSrcOut + dOut; } _renderClips(); }