fix: play from the playhead, not currentTime (iOS deep-link seek)

On iOS the element doesn't load (so a deep-linked pre-seek doesn't stick) until
the user's first tap, so engage-play! read currentTime=0 and played from the
top. Seek to the playhead inside the play gesture and drive from there; for
normal pause/resume the playhead already equals currentTime, so it's a no-op.
Drops now-unused seg-at-src.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-30 10:54:53 -04:00
parent 28aa2622f6
commit 5c58af9036

View file

@ -105,16 +105,6 @@
segs)) segs))
(max 0 (dec (count segs))))) (max 0 (dec (count segs)))))
(defn- seg-at-src
"Index of the segment whose SOURCE range contains source frame `sf` (0 if none)."
[segs sf]
(or (first (keep-indexed (fn [i {[a b] :src}]
(when (or (and (<= a sf) (< sf b))
(< sf a))
i))
segs))
(max 0 (dec (count segs)))))
;; The <video> element is the source of truth for play/pause. Its :on-play / ;; The <video> element is the source of truth for play/pause. Its :on-play /
;; :on-pause (below) engage/disengage this segment-aware tick, so the native ;; :on-pause (below) engage/disengage this segment-aware tick, so the native
;; controls and the toolbar button behave identically. `play` holds the frozen ;; controls and the toolbar button behave identically. `play` holds the frozen
@ -164,7 +154,15 @@
(rf/dispatch [::events/set-playhead ctx 0]) (rf/dispatch [::events/set-playhead ctx 0])
(seek-video! fps s0) (seek-video! fps s0)
(reset! play {:ctx ctx :segs segs :fps fps :idx 0 :pending-ns s0})) (reset! play {:ctx ctx :segs segs :fps fps :idx 0 :pending-ns s0}))
(reset! play {:ctx ctx :segs segs :fps fps :idx (seg-at-src segs (* (.-currentTime v) fps))})) ;; Start from the PLAYHEAD, not currentTime: on iOS a deep-linked pre-seek
;; often hasn't stuck (the element doesn't load until this very tap), so
;; currentTime is still 0 and playback would start from the top. Re-seek
;; here — inside the user gesture, where it's reliable — and drive from the
;; playhead. For ordinary pause/resume the playhead already equals
;; currentTime, so this seeks to the same spot (a no-op).
(let [src (scene/local->source segs ph)]
(seek-video! fps src)
(reset! play {:ctx ctx :segs segs :fps fps :idx (seg-at segs ph) :pending-ns src})))
(rf/dispatch [::events/set-playing true]) (rf/dispatch [::events/set-playing true])
(reset! raf (js/requestAnimationFrame play-tick))))) (reset! raf (js/requestAnimationFrame play-tick)))))