fix: dedupe scroll-to-clip by bar boundary instead of track

When an annotation with scroll-to enabled spans multiple bars (discontinuities),
only scroll when the playhead enters a new bar, not for every mark. Track
[ann-id bar-idx] pairs instead of just the current track to avoid excessive
scrolling as the playhead moves within a bar.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-30 14:05:58 -04:00
parent 6a02b0665b
commit d91ea6c78a

View file

@ -14,7 +14,7 @@
(defonce scroll-el (atom nil))
(defonce body-scroll-el (atom nil)) ; the vertical (tracks) scroll container
(defonce playhead-el (atom nil)) ; the single full-height playhead overlay
(defonce played-track (atom nil)) ; last track auto-scrolled into view during playback
(defonce played-bar (atom nil)) ; [ann-id bar-idx] last auto-scrolled to during playback
(defonce play (atom nil)) ; {:ctx :segs :fps :idx} while playing, else nil
(defonce active-insert! (atom nil)) ; the live content-editor's (insert! link) fn
(declare commit-link!)
@ -344,17 +344,19 @@
(follow! fps zoom playhead)
;; clip-following: only while the playhead is actually inside a bar of
;; an annotation that opts in (:meta :scroll-to) — scroll each of its
;; clips into view as the playhead crosses onto a new track. (Strict
;; containment, NOT ::active-annotation, which falls back to the
;; nearest annotation and would fire on every clip.)
(when (some (fn [a] (and (ann-scroll-to? (get-in scene [:groups (:id a)]))
(some (fn [[lo hi]] (<= lo playhead hi)) (:bars a))))
anns)
(let [track (:track (nth segs (seg-at segs playhead) nil))]
(when (not= track @played-track)
(reset! played-track track)
(scroll-to-seg-track! segs playhead))))))
(reset! played-track nil))
;; clips into view as the playhead crosses onto a new bar (discontinuity).
;; Track [ann-id bar-idx] to avoid scrolling within the same bar.
(when-let [current-bar (some (fn [a]
(when (and (ann-scroll-to? (get-in scene [:groups (:id a)]))
(some (fn [[lo hi]] (<= lo playhead hi)) (:bars a)))
[(:id a) (first (keep-indexed (fn [j [lo hi]]
(when (<= lo playhead hi) j))
(:bars a)))]))
anns)]
(when (not= current-bar @played-bar)
(reset! played-bar current-bar)
(scroll-to-seg-track! segs playhead)))))
(reset! played-bar nil))
(r/after-render #(position-playhead! fps zoom playhead))
[:div.timeline {:class (when-not @tracks-open? "tracks-collapsed")}
[:div.playhead.timeline-playhead {:ref (fn [n] (reset! playhead-el n))}