ENGLISH·COURSE API
    Preparing search index...
    • Reports whether the learner is pressing and holding the video.

      Parameters

      • player: { player: ElementOwner | null; enabled: boolean; onKeyTap?: () => void }

        The player whose element every pointer event on the chrome bubbles to. Its element is read when the listeners are attached, not while rendering, and the player itself must keep its identity between renders — a fresh object each render re-attaches the listeners and drops a hold in flight

      Returns boolean

      true while a hold is armed

      The hold is timed here because the library has no event for it. Vidstack's Gesture knows pointerup, dblpointerup and the provider's media events; the nearest it offers is an action on the release, which would speed the video up at the moment the finger lifts — the opposite of the gesture. So the press is timed against the player element, the same node PlaybackGestures already listens on for a seek run's taps.

      The hook says when, not what. It reports a boolean and changes no playback rate: the rate to apply, and the rate to put back, belong to the caller that holds the player and the remote. That keeps everything here testable without a media provider.

      A press that drifts is a swipe, not a hold. Enlarged, the player deliberately never locks the page's scroll, because on an iPhone only a real swipe travelling through the pinned player hides Safari's toolbar. A finger resting there on its way to that swipe is a frequent, ordinary event, so a press that moves past HOLD_MOVE_TOLERANCE_PX before the delay arms nothing. Once armed, movement is ignored — the finger is deliberately down — and the browser's own pointercancel ends the hold when it claims the touch for the scroll.

      Releases are heard on the document rather than on the player: a finger that wandered off the player before lifting would otherwise leave a hold armed with nothing left to end it.

      The play/pause key is taken from the library in the capture phase. Vidstack binds Space and K to togglePaused and acts on keydown, so a learner who held the key would have the lesson paused half a second before the hold could arm. Its listener is on the player element and it stops the event there, so the only place left to intercept is the document, capturing — which also means the library never sees the key at all and cannot toggle twice. The tap it used to handle is reported back through onKeyTap.

      The library does offer a shortcut table that can carry a handler, and it was tried first. It cannot be relied on: the chrome's play button registers the same shortcut through aria-keyshortcuts, and that registration is a plain key list that overrides whatever the table holds — so the handler is skipped and the library toggles anyway.

      A release is reported one frame late, on purpose. The browser delivers a touch release as pointerup and then touchend, and Vidstack's tap gesture listens for the second of those on a coarse pointer. Ending the hold between the two would re-enable that gesture in time for it to read the release as a tap — which is exactly how releasing a hold used to pause the lesson on an iPhone while leaving a mouse unaffected. Waiting for the next animation frame puts the whole release behind us before the caller is told.

      contextmenu is suppressed while a press is in flight, so a desktop press does not raise a menu over the indicator it just drew. Its touch counterpart — iOS Safari's callout — is not an event and is turned off in the player's stylesheet instead.

      const isHolding = useSpeedHold({ player: useMediaPlayer(), enabled: isPlaying });