fix: pane scroll on NEWLY-active annotation (set diff)
Track the full set of annotations the playhead is inside and diff against last tick; scroll only for newly-entered ones, so a permanently-active annotation (e.g. a full-timeline one) counts as new just once and stops hijacking the scroll. Pick one deterministically among the newly active (greatest lo, then tightest bar). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
183e776727
commit
23154ac284
1 changed files with 23 additions and 20 deletions
|
|
@ -15,7 +15,7 @@
|
||||||
(defonce body-scroll-el (atom nil)) ; the vertical (tracks) scroll container
|
(defonce body-scroll-el (atom nil)) ; the vertical (tracks) scroll container
|
||||||
(defonce playhead-el (atom nil)) ; the single full-height playhead overlay
|
(defonce playhead-el (atom nil)) ; the single full-height playhead overlay
|
||||||
(defonce played-bar (atom nil)) ; [ann-id bar-idx] last auto-scrolled to during playback
|
(defonce played-bar (atom nil)) ; [ann-id bar-idx] last auto-scrolled to during playback
|
||||||
(defonce scrolled-ann (atom nil)) ; ann-id the commentary pane last auto-scrolled to
|
(defonce active-ann-set (atom #{})) ; ann-ids whose bar the playhead was inside last tick
|
||||||
(defonce scrolled-on-load? (atom nil)) ; did we scroll to deep-linked playhead on load
|
(defonce scrolled-on-load? (atom nil)) ; did we scroll to deep-linked playhead on load
|
||||||
(defonce play (atom nil)) ; {:ctx :segs :fps :idx} while playing, else nil
|
(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
|
(defonce active-insert! (atom nil)) ; the live content-editor's (insert! link) fn
|
||||||
|
|
@ -488,25 +488,28 @@
|
||||||
(scroll-to-seg-track! segs playhead)))))
|
(scroll-to-seg-track! segs playhead)))))
|
||||||
(do (reset! played-bar nil)
|
(do (reset! played-bar nil)
|
||||||
(reset! scrolled-on-load? nil)))
|
(reset! scrolled-on-load? nil)))
|
||||||
;; scroll the commentary pane to the annotation the playhead is inside. ONE
|
;; scroll the commentary pane when the playhead ENTERS an annotation. Track the
|
||||||
;; deterministic pick, so overlapping annotations don't race: the MOST
|
;; full set of active annotations and diff against last tick: scroll only for
|
||||||
;; RECENTLY ENTERED one — the active bar with the greatest lo (ties → the
|
;; NEWLY active ones, so a permanently-active annotation (e.g. one spanning the
|
||||||
;; tighter bar). A full-timeline annotation (lo 0) thus only wins when nothing
|
;; whole timeline) is "new" just once and never hijacks the scroll. Among the
|
||||||
;; more specific contains the playhead. Fires on any playhead move.
|
;; newly active, pick one deterministically: greatest lo (tightest entry), then
|
||||||
(let [primary (->> anns
|
;; smallest bar. Fires on any playhead move (playback or scrub).
|
||||||
(keep (fn [a]
|
(let [active-bars (keep (fn [a]
|
||||||
(some (fn [[lo hi]]
|
(when-let [[lo hi] (some (fn [[lo hi]]
|
||||||
(when (and (<= lo playhead) (< playhead hi)) [lo hi (:id a)]))
|
(when (and (<= lo playhead) (< playhead hi)) [lo hi]))
|
||||||
(:bars a))))
|
(:bars a))]
|
||||||
(sort-by (fn [[lo hi _]] [lo (- hi)]))
|
{:id (:id a) :lo lo :hi hi}))
|
||||||
last
|
anns)
|
||||||
(#(nth % 2 nil)))]
|
active (into #{} (map :id) active-bars)
|
||||||
(when (not= primary @scrolled-ann)
|
newly (into #{} (remove @active-ann-set) active)]
|
||||||
(reset! scrolled-ann primary)
|
(reset! active-ann-set active)
|
||||||
(when primary
|
(when-let [pick (->> active-bars
|
||||||
|
(filter (comp newly :id))
|
||||||
|
(sort-by (juxt (comp - :lo) :hi))
|
||||||
|
first :id)]
|
||||||
(r/after-render
|
(r/after-render
|
||||||
#(when-let [node (js/document.getElementById (str "ann-" (name primary)))]
|
#(when-let [node (js/document.getElementById (str "ann-" (name pick)))]
|
||||||
(.scrollIntoView node #js {:block "center" :behavior "smooth"}))))))
|
(.scrollIntoView node #js {:block "center" :behavior "smooth"})))))
|
||||||
(r/after-render #(position-playhead! fps zoom playhead))
|
(r/after-render #(position-playhead! fps zoom playhead))
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue