From 820f0716c86058f11b66786718dbf7ad8969e4b7 Mon Sep 17 00:00:00 2001 From: Artur Finger Date: Mon, 9 Sep 2024 18:28:40 +0300 Subject: [PATCH] DE-7265: Add option to disable focus-based interactivity (#46) --- CHANGELOG.md | 9 +++++---- app/src/InterstitialPage.tsx | 13 ++++++++----- package.json | 2 +- src/components/PlayerSurface.tsx | 9 +++++++++ src/interstitial/InterstitialPlayer.tsx | 9 +++++++++ src/utils.ts | 9 +++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc820b..06ef4f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,14 @@ ## New Features +* Add option to disable focus-based keyboard interactivity. * Add option to keep player controls hidden. * Make `BaseThemeOverlay` more configurable: - * Add option to hide buttons (audio, full screen, track options) - * Add option to hide the top bar of player controls + * Add option to hide buttons (audio, full screen, track options). + * Add option to hide the top bar of player controls. * Add option to render a companion component above the bottom bar - of player controls -* Add option to display cues on the seek bar + of player controls. +* Add option to display cues on the seek bar. ## Fixes diff --git a/app/src/InterstitialPage.tsx b/app/src/InterstitialPage.tsx index 5efc2b8..70878e2 100644 --- a/app/src/InterstitialPage.tsx +++ b/app/src/InterstitialPage.tsx @@ -22,11 +22,11 @@ export const InterstitialPage = () => { {mounted ? (
{ patchIgnoreStateEnded={true} hasTopControlsBar={false} interstitialOptions={{ - // Start resolving X-ASSET-LIST 15 seconds or less before - // the cue is scheduled + config: { + // license: '', + }, + // Start resolving X-ASSET-LIST 15 seconds or less before + // the cue is scheduled resolutionOffsetSec: 15, interstitialAssetConverter: (asset: clpp.interstitial.PlayerItem) => { asset.config.htmlcue = { diff --git a/package.json b/package.json index e09a28e..969f4d8 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "typescript": "^4.8.4" }, "peerDependencies": { - "@castlabs/prestoplay": "^6.11.1-beta.4", + "@castlabs/prestoplay": "^6.16.1-beta.4", "react": "^18.0.0", "react-dom": "^18.0.0" }, diff --git a/src/components/PlayerSurface.tsx b/src/components/PlayerSurface.tsx index febd37f..0143082 100644 --- a/src/components/PlayerSurface.tsx +++ b/src/components/PlayerSurface.tsx @@ -5,6 +5,7 @@ import { PrestoContext, PrestoContextType } from '../context/PrestoContext' import { Player } from '../Player' import { usePrestoUiEvent } from '../react' import { + enableFocus, focusElement, focusNextElement, focusPreviousElement, getFocusableElements, isIpadOS, @@ -43,6 +44,10 @@ export interface PlayerProps extends BaseComponentProps { * player will go to full-screen mode and no overlay will be possible. */ playsInline?: boolean + /** + * Enable focus-based keyboard interactivity. Default: true. + */ + enableFocus?: boolean children?: React.ReactNode /** * @private @@ -81,6 +86,10 @@ export const PlayerSurface = (props: PlayerProps) => { }) const context = getContext(nullableContext) + useEffect(() => { + enableFocus(props.enableFocus ?? true) + }, [props.enableFocus]) + useEffect(() => { context && props.onContext?.(context) // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/interstitial/InterstitialPlayer.tsx b/src/interstitial/InterstitialPlayer.tsx index b6c925c..501d6bb 100644 --- a/src/interstitial/InterstitialPlayer.tsx +++ b/src/interstitial/InterstitialPlayer.tsx @@ -4,6 +4,7 @@ import '@castlabs/prestoplay/cl.hls' import React, { useEffect, useRef } from 'react' import { ControlsVisibilityMode } from '../services/controls' +import { enableFocus } from '../utils' import { InterstitialOverlay } from './components/OverlayHlsi' import { PlayerSurfaceHlsi } from './components/PlayerSurfaceHlsi' @@ -114,6 +115,10 @@ export type InterstitialPlayerProps = { * Callback to get the instance of the HLS interstitial player */ onHlsiPlayerReady?: (player: clpp.interstitial.Player) => void + /** + * Enable focus-based keyboard interactivity. Default: true. + */ + enableFocus?: boolean } /** @@ -125,6 +130,10 @@ export type InterstitialPlayerProps = { export const InterstitialPlayer = React.memo((props: InterstitialPlayerProps) => { const playerRef = useRef(new PlayerHlsi(props.onHlsiPlayerReady)) + useEffect(() => { + enableFocus(props.enableFocus ?? true) + }, [props.enableFocus]) + useEffect(() => { if (props.patchIgnoreStateEnded) { playerRef.current.ignoreStateEnded = true diff --git a/src/utils.ts b/src/utils.ts index 880e3e9..fadef00 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -120,8 +120,17 @@ export function focusPreviousElement(items: HTMLElement[]) { } let focusElementTimerId_: ReturnType | null = null +let focusEnabled = true + +export function enableFocus(enabled: boolean) { + focusEnabled = enabled +} export function focusElement(item: HTMLElement) { + if (!focusEnabled) { + return + } + if (focusElementTimerId_) { clearTimeout(focusElementTimerId_) focusElementTimerId_= null