diff --git a/tl/src/tl/views.cljs b/tl/src/tl/views.cljs index 9a0abe6..ca4c975 100644 --- a/tl/src/tl/views.cljs +++ b/tl/src/tl/views.cljs @@ -66,6 +66,11 @@ (when (and @video-el source-frame) (set! (.-currentTime @video-el) (/ source-frame fps)))) +(defn- follow! [fps zoom playhead] + (when-let [el @scroll-el] + (let [x (px playhead fps zoom)] + (set! (.-scrollLeft el) (max 0 (- x (/ (.-clientWidth el) 2))))))) + (defn- seg-at "Index of the segment whose LOCAL range contains `local` (0 if none)." [segs local] @@ -151,14 +156,19 @@ (rf/reg-fx :player/pause (fn [_] (when-let [v @video-el] (.pause v)))) (rf/reg-fx :player/seek (fn [secs] (when (and @video-el secs) (set! (.-currentTime @video-el) secs)))) -(defn- goto! [local] +(defn- goto! "Move the playhead to local frame `local` and seek the video to match." - (let [ctx @(rf/subscribe [::subs/context]) - segs @(rf/subscribe [::subs/segments]) - fps @(rf/subscribe [::subs/fps])] - (rf/dispatch [::events/set-playhead ctx local]) - (seek-video! fps (scene/local->source segs local)) - (when @play (swap! play assoc :idx (seg-at segs local))))) ; keep playback in sync + ([local] (goto! local false)) + ([local follow?] + (let [ctx @(rf/subscribe [::subs/context]) + segs @(rf/subscribe [::subs/segments]) + fps @(rf/subscribe [::subs/fps]) + zoom @(rf/subscribe [::subs/zoom])] + (rf/dispatch [::events/set-playhead ctx local]) + (seek-video! fps (scene/local->source segs local)) + (when @play (swap! play assoc :idx (seg-at segs local))) ; keep playback in sync + (when follow? + (r/after-render #(follow! fps zoom local)))))) (defn video-monitor [] [:video {:src @(rf/subscribe [::subs/clip-url]) :controls true :preload "auto" @@ -238,11 +248,6 @@ (.addEventListener js/document "mousemove" move) (.addEventListener js/document "mouseup" up))) -(defn- follow! [fps zoom playhead] - (when-let [el @scroll-el] - (let [x (px playhead fps zoom)] - (set! (.-scrollLeft el) (max 0 (- x (/ (.-clientWidth el) 2))))))) - (defn timeline [] (let [content (atom nil) lanes-scroll (atom nil) @@ -343,6 +348,10 @@ (scene/link-local @(rf/subscribe [::subs/scene]) @(rf/subscribe [::subs/context]) {:ref (keyword ref) :at (js/parseInt at 10)})) +(defn- goto-link! [local] + (when local + (goto! local true))) + (defn content-display "Read-only render of annotation `content`: markdown blocks (headings, lists, paragraphs) with inline formatting plus clickable link chips." @@ -358,7 +367,7 @@ (let [lf (scene/link-local scene ctx {:ref ref :at at})] [:span.link-chip {:class (when-not lf "broken") :title (when-not lf "linked clip no longer in this timeline") - :on-click #(when lf (goto! lf))} + :on-click #(goto-link! lf)} (when-not lf "△ ") label (when lf [:span.link-f (str " " (js/Math.round lf) "f")])]))))) @@ -431,7 +440,7 @@ :on-input emit :on-key-up save! :on-mouse-up save! :on-blur save! :on-click (fn [e] (when-let [chip (.closest (.-target e) ".link-chip")] (when-let [lf (link-frame (.. chip -dataset -ref) (.. chip -dataset -at))] - (goto! lf))))}])) + (goto-link! lf))))}])) (defn- point-candidates [scene ctx q timelines?] (let [needle (str/lower-case q) @@ -599,7 +608,7 @@ [open a scene segs] (let [bars (:bars a)] (if (< (count bars) 2) - [:button.jump-btn {:on-click #(goto! (:start a))} "↪ jump"] + [:button.jump-btn {:on-click #(goto! (:start a) true)} "↪ jump"] [:span {:style {:position "relative"}} [:button.jump-btn {:on-click #(swap! open (fn [x] (when (not= x (:id a)) (:id a))))} (str "↪ jump (" (count bars) ") ▾")] @@ -607,7 +616,7 @@ [:div.jump-pop (for [[i [lo _]] (map-indexed vector bars)] ^{:key i} - [:button {:on-click #(do (goto! lo) (reset! open nil))} + [:button {:on-click #(do (goto! lo true) (reset! open nil))} (str "▸ " (clip-at scene segs lo))])])]))) (defn commentary [] @@ -853,7 +862,7 @@ (let [[x0 y0 x1 y1] rect] [:div.script-hl {:title (:name a) :data-ann (name (:id a)) :on-mouse-down #(.stopPropagation %) - :on-click #(goto! (:start a)) ; jump the timeline to this annotation + :on-click #(goto! (:start a) true) ; jump the timeline to this annotation :style {:left (* x0 w) :top (* y0 h) :width (* (- x1 x0) w) :height (* (- y1 y0) h) :background (str (:color a) "44") :border (str "1.5px solid " (:color a))}}]))