From a99485ff48191d9ba48e3d3fb075cc406e73b104 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 30 Jun 2026 10:28:00 -0400 Subject: [PATCH] refactor: scroll-to-clip via scrollIntoView on the gutter label MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the manual lane-h/row-h/clientHeight math (fragile, clamped oddly for top rows) with scrollIntoView on the target track's gutter label. The label lives in the fixed track-name column, so the browser scrolls the vertical axis only — clean, no geometry, and structurally can't fight the horizontal follow. Co-Authored-By: Claude Opus 4.8 --- tl/src/tl/views.cljs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/tl/src/tl/views.cljs b/tl/src/tl/views.cljs index 66a0b17..b425c18 100644 --- a/tl/src/tl/views.cljs +++ b/tl/src/tl/views.cljs @@ -180,21 +180,18 @@ (rf/reg-fx :player/seek (fn [secs] (when (and @video-el secs) (set! (.-currentTime @video-el) secs)))) (defn- scroll-to-seg-track! - "Scroll the tracks vertically so the clip under local frame `local` is visible. - No-op when there's no vertical overflow. The annotation lanes are a pinned - header of height `lane-h`, so the clip rows live below that in scroll space." + "Vertically scroll the tracks so the clip under local frame `local` is centred. + We scroll the clip's *gutter label* into view rather than the clip itself: the + label lives in the fixed track-name column (no horizontal scroller), so the + browser only moves the vertical axis — no fight with the horizontal follow, + and no manual geometry. A no-op when the row is already on screen." [segs local] (when-let [el @body-scroll-el] (let [tracks @(rf/subscribe [::subs/tracks]) - row-h @(rf/subscribe [::subs/row-h]) - anns @(rf/subscribe [::subs/annotations]) - lane-h (max 18 (* 18 (count anns))) track (:track (nth segs (seg-at segs local) nil)) i (first (keep-indexed (fn [idx t] (when (= (:id t) track) idx)) tracks))] - (when i - (let [target (+ lane-h (* i row-h) (/ row-h 2))] - (.scrollTo el #js {:top (max 0 (- target (/ (.-clientHeight el) 2))) - :behavior "smooth"})))))) + (when-let [row (and i (aget (.querySelectorAll el ".gutter-label") i))] + (.scrollIntoView row #js {:block "center" :behavior "smooth"}))))) (defn- goto! "Move the playhead to local frame `local` and seek the video to match.