From 183e7767278e723e36ed2a35da70ecbffe0a29bc Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 3 Jul 2026 11:14:01 -0400 Subject: [PATCH] fix: pane scroll picks the most-recently-entered annotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior "first active in anns" pick was masked by a full-timeline annotation (bars [[0 N]]) that always won, so primary never changed and the scroll never re-fired. Pick the active bar with the greatest lo (ties → tighter bar) instead, so entering a nested/later annotation changes the pick and scrolls to it. Co-Authored-By: Claude Opus 4.8 --- tl/src/tl/views.cljs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tl/src/tl/views.cljs b/tl/src/tl/views.cljs index e0288e2..2fa9ab6 100644 --- a/tl/src/tl/views.cljs +++ b/tl/src/tl/views.cljs @@ -488,13 +488,19 @@ (scroll-to-seg-track! segs playhead))))) (do (reset! played-bar nil) (reset! scrolled-on-load? nil))) - ;; scroll the commentary pane to the annotation the playhead is inside — ONE - ;; deterministic pick (first active in the sorted anns), so overlapping - ;; annotations don't race. Fires on any playhead move (playback or scrub). - (let [primary (some (fn [a] - (when (some (fn [[lo hi]] (and (<= lo playhead) (< playhead hi))) (:bars a)) - (:id a))) - anns)] + ;; scroll the commentary pane to the annotation the playhead is inside. ONE + ;; deterministic pick, so overlapping annotations don't race: the MOST + ;; RECENTLY ENTERED one — the active bar with the greatest lo (ties → the + ;; tighter bar). A full-timeline annotation (lo 0) thus only wins when nothing + ;; more specific contains the playhead. Fires on any playhead move. + (let [primary (->> anns + (keep (fn [a] + (some (fn [[lo hi]] + (when (and (<= lo playhead) (< playhead hi)) [lo hi (:id a)])) + (:bars a)))) + (sort-by (fn [[lo hi _]] [lo (- hi)])) + last + (#(nth % 2 nil)))] (when (not= primary @scrolled-ann) (reset! scrolled-ann primary) (when primary