From 867c41b19a296366f6e506f5947af4f762ae7999 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 30 Apr 2026 05:24:28 -0700 Subject: [PATCH] fix: clamp drag selection to 1s minimum Sub-second drag selections produced inconsistent state: zoom/loop held millisecond-precision bounds while the URL collapsed \`Math.floor(start/1000) === Math.floor(end/1000)\` and dropped the range entirely. Round drag offsets to whole seconds (URL precision) at dispatch time and ensure end > start, so any drag becomes at least a 1-second section. No separate ms-precision internal state to keep in sync. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/Timeline/index.jsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/Timeline/index.jsx b/src/components/Timeline/index.jsx index a3b7c66d..f5f37e6d 100644 --- a/src/components/Timeline/index.jsx +++ b/src/components/Timeline/index.jsx @@ -251,8 +251,14 @@ class Timeline extends Component { const rulerBounds = this.rulerRef.current.getBoundingClientRect(); const startPercent = (Math.min(dragging[0], dragging[1]) - rulerBounds.x) / rulerBounds.width; const endPercent = (Math.max(dragging[0], dragging[1]) - rulerBounds.x) / rulerBounds.width; - const startOffset = Math.round(this.percentToOffset(startPercent)); - const endOffset = Math.round(this.percentToOffset(endPercent)); + // Round to whole seconds (URL precision) so the section bounds match what we + // serialize, and so any drag is at least 1s wide. No separate sub-second + // internal state to keep in sync. + const startOffset = Math.round(this.percentToOffset(startPercent) / 1000) * 1000; + let endOffset = Math.round(this.percentToOffset(endPercent) / 1000) * 1000; + if (endOffset <= startOffset) { + endOffset = startOffset + 1000; + } if (Math.abs(dragging[1] - dragging[0]) > 3) { const offset = currentOffset();