fix: scroll pane to annotation from the card's own active? (highlight path)

Drop the separate commentary-scroll/active-annotation component and trigger the
scroll where the highlight already fires: when a card's ::annotation-active?
flips true (playhead entered), scrollIntoView it — the same call the lane click
uses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-07-02 20:58:43 -04:00
parent f6e887c14d
commit 0022c6bedd

View file

@ -1032,8 +1032,15 @@
(rf/dispatch [::events/reparent (keyword src) (:id a)]))))})) (rf/dispatch [::events/reparent (keyword src) (:id a)]))))}))
(defn- annotation-card [a scene ctx segs nmap authed? open by-parent] (defn- annotation-card [a scene ctx segs nmap authed? open by-parent]
(r/with-let [over? (r/atom false) hov? (r/atom false)] (r/with-let [over? (r/atom false) hov? (r/atom false) was-active? (atom false)]
(let [active? @(rf/subscribe [::subs/annotation-active? (:id a)]) (let [active? @(rf/subscribe [::subs/annotation-active? (:id a)])
;; playhead just ENTERED this annotation (same active? that drives the
;; highlight) → scroll the pane to it, exactly like clicking its lane bar.
_ (when (and active? (not @was-active?))
(r/after-render
#(when-let [node (js/document.getElementById (str "ann-" (name (:id a))))]
(.scrollIntoView node #js {:block "center" :behavior "smooth"}))))
_ (reset! was-active? active?)
dragging @(rf/subscribe [::subs/dragging-ann]) dragging @(rf/subscribe [::subs/dragging-ann])
drop-ok? (and dragging (not= dragging (:id a))) drop-ok? (and dragging (not= dragging (:id a)))
drag-props (merge (ann-drag-props a authed? over?) drag-props (merge (ann-drag-props a authed? over?)
@ -1092,25 +1099,8 @@
(for [k kids] (for [k kids]
^{:key (:id k)} [annotation-card k scene ctx segs nmap authed? open by-parent])))])))) ^{:key (:id k)} [annotation-card k scene ctx segs nmap authed? open by-parent])))]))))
;; Renders nothing: owns the active-annotation subscription and scrolls the active
;; card into view, so `commentary` itself no longer re-renders on every crossing.
(defn- commentary-scroll [el]
;; Form-3 so the scroll runs in component-did-update — reliably after the DOM is
;; committed on every active-annotation change — and via scrollIntoView, which
;; (unlike offsetTop math) is correct even when the active card is nested.
(letfn [(scroll! [& _]
(let [active @(rf/subscribe [::subs/active-annotation])]
(when-let [c @el]
(when-let [node (and active (.querySelector c (str "#ann-" (name active))))]
(.scrollIntoView node #js {:block "center" :behavior "smooth"})))))]
(r/create-class
{:display-name "commentary-scroll"
:component-did-mount scroll!
:component-did-update scroll!
:reagent-render (fn [_] @(rf/subscribe [::subs/active-annotation]) nil)})))
(defn commentary [] (defn commentary []
(let [el (atom nil) open (r/atom nil)] (let [open (r/atom nil)]
(fn [] (fn []
(let [anns @(rf/subscribe [::subs/annotations]) (let [anns @(rf/subscribe [::subs/annotations])
authed? @(rf/subscribe [::subs/authed?]) authed? @(rf/subscribe [::subs/authed?])
@ -1118,8 +1108,7 @@
ctx @(rf/subscribe [::subs/context]) ctx @(rf/subscribe [::subs/context])
segs @(rf/subscribe [::subs/segments]) segs @(rf/subscribe [::subs/segments])
nmap (into {} (map (juxt :id identity)) @(rf/subscribe [::subs/notes]))] nmap (into {} (map (juxt :id identity)) @(rf/subscribe [::subs/notes]))]
[:div.commentary {:ref (fn [n] (reset! el n))} [:div.commentary
[commentary-scroll el]
;; this context's own description (links resolve in its parent), with an ;; this context's own description (links resolve in its parent), with an
;; edit button — Edit drops into the parent timeline so marks are editable. ;; edit button — Edit drops into the parent timeline so marks are editable.
(let [cg (get-in scene [:groups ctx])] (let [cg (get-in scene [:groups ctx])]