From 82126cf4a3940af72718028587c05fed8655bfc7 Mon Sep 17 00:00:00 2001 From: Artur Finger Date: Mon, 18 Sep 2023 16:19:48 +0300 Subject: [PATCH 1/8] Copy over TS typings from `@castlabs/prestoplay` --- src/Player.ts | 43 +- src/components/MuteButton.tsx | 4 +- src/components/PlayerSurface.tsx | 2 +- src/components/Thumbnail.tsx | 2 +- src/components/VolumeBar.tsx | 4 +- src/react.ts | 4 +- types/presto.d.ts | 7455 +++++++++++++++++++++++++++++- 7 files changed, 7329 insertions(+), 185 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 59c3327..b1f84bc 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -29,6 +29,11 @@ export type PlayerInitializer = (presto: clpp.Player) => void */ type Action = () => Promise +type Range = { + start: number + end: number +} + /** * Player states */ @@ -334,7 +339,7 @@ export class Player { * * @private */ - private _config: clpp.LoadConfig | null = null + private _config: clpp.PlayerConfiguration | null = null /** * Indicate that the config was loaded @@ -395,15 +400,20 @@ export class Player { this.pp_.on(clpp.events.VIDEO_TRACK_CHANGED, handlePlayerTracksChanged('video')) this.pp_.on(clpp.events.TEXT_TRACK_CHANGED, handlePlayerTracksChanged('text')) - this.pp_.on(clpp.events.STATE_CHANGED, (event: clpp.Event) => { - const e = event as clpp.StateChangeEvent + this.pp_.on(clpp.events.STATE_CHANGED, (event: any) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const e = event + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const currentState = toState(e.detail.currentState) + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const previousState = toState(e.detail.previousState) - + this.emitUIEvent('statechanged', { currentState, previousState, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment reason: e.detail.reason, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment timeSinceLastStateChangeMS: e.detail.timeSinceLastStateChangeMS, }) @@ -448,9 +458,9 @@ export class Player { }) }) - this.pp_.on(clpp.events.BITRATE_CHANGED, (e: clpp.Event) => { + this.pp_.on(clpp.events.BITRATE_CHANGED, (e: any) => { const tm = this.trackManager - + if (tm) { this.playingVideoTrack = fromPrestoTrack(tm, e.detail.rendition as clpp.Rendition, 'video') } else { @@ -530,12 +540,12 @@ export class Player { return this.pp_ ? this.pp_.isLive() : false } - get seekRange(): { start: number; end: number } { - return this.pp_ ? this.pp_.getSeekRange() : { start: 0, end: 0 } + get seekRange(): Range { + return this.pp_ ? this.pp_.getSeekRange() as Range : { start: 0, end: 0 } } get volume(): number { - return this.pp_ ? this.pp_.getVolume() : 1 + return this.pp_ ? this.pp_.getVolume() ?? 0 : 1 } set volume(volume: number) { @@ -548,7 +558,7 @@ export class Player { } get muted() { - return this.pp_ ? this.pp_.isMuted() : false + return this.pp_ ? this.pp_.isMuted() ?? false : false } set muted(muted: boolean) { @@ -596,7 +606,7 @@ export class Player { } } - load(config?: clpp.LoadConfig, autoload = false) { + load(config?: clpp.PlayerConfiguration, autoload = false) { if (config) { this._config = config return this.action(async () => { @@ -705,9 +715,8 @@ export class Player { async presto(): Promise { await this._actionQueuePromise - // @ts-ignore I am not sure if this.pp_ is - // always defined here or if it can possibly be null... - return this.pp_ + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + return (this.pp_ as clpp.Player) } /** @@ -788,7 +797,8 @@ export class Player { set videoTracks(value: Track[]) { value = value.filter(v => { - // @ts-ignore type conflicet between Track and Rendition + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore type conflict between Track and Rendition return v.ppTrack && v.ppTrack.height && v.ppTrack.width }) if (value.length > 0 && !value.find(t => t.id === 'abr')) { @@ -828,18 +838,21 @@ export class Player { } else { track.selected = true if (track.type === 'audio') { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Rendition is not assignable to Track // there is a type conflict tm.setAudioTrack(track.ppTrack) this.audioTrack = getActiveTrack(tm, 'audio') this.audioTracks = getTracks(tm, 'audio') } else if (track.type === 'text') { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Rendition is not assignable to Track // there is a type conflict tm.setTextTrack(track.ppTrack) this.textTrack = getActiveTrack(tm, 'text') this.textTracks = getTracks(tm, 'text') } else if (track.type === 'video') { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Track is not assignable to Rendition // there is a miss match between the types tm.setVideoRendition(track.ppTrack, true) diff --git a/src/components/MuteButton.tsx b/src/components/MuteButton.tsx index b32d4e9..9d5a463 100644 --- a/src/components/MuteButton.tsx +++ b/src/components/MuteButton.tsx @@ -29,10 +29,10 @@ export const MuteButton = (props: MuteButtonProps) => { const enabled = usePrestoEnabledState() usePrestoCoreEvent('volumechange', (e, presto) => { - setMuted(presto.isMuted()) + setMuted(presto.isMuted() ?? false) }) usePrestoCoreEvent('loadedmetadata', (e, presto) => { - setMuted(presto.isMuted()) + setMuted(presto.isMuted() ?? false) }) function toggle(e: React.MouseEvent) { diff --git a/src/components/PlayerSurface.tsx b/src/components/PlayerSurface.tsx index 8a4228f..3590b7f 100644 --- a/src/components/PlayerSurface.tsx +++ b/src/components/PlayerSurface.tsx @@ -25,7 +25,7 @@ export interface PlayerProps extends BaseComponentProps { * The PRESTOplay player configuration to load and play a video * https://demo.castlabs.com/#/docs?q=clpp#PlayerConfiguration */ - config?: clpp.LoadConfig + config?: clpp.PlayerConfiguration /** * The PRESTOplay player configuration to initialize the player * https://demo.castlabs.com/#/docs?q=clpp#PlayerConfiguration diff --git a/src/components/Thumbnail.tsx b/src/components/Thumbnail.tsx index 15e9556..503804a 100644 --- a/src/components/Thumbnail.tsx +++ b/src/components/Thumbnail.tsx @@ -28,7 +28,7 @@ export interface ThumbnailProps extends BaseComponentProps { */ const usePlugin = () => { const { presto } = useContext(PrestoContext) - return presto.getPlugin(clpp.thumbnails.ThumbnailsPlugin.Id) as clpp.ThumbnailsPlugin | null + return presto.getPlugin(clpp.thumbnails.ThumbnailsPlugin.Id) as clpp.thumbnails.ThumbnailsPlugin | null } const DEFAULT_STYLE = { height: 130 } diff --git a/src/components/VolumeBar.tsx b/src/components/VolumeBar.tsx index da32aca..ceafbe2 100644 --- a/src/components/VolumeBar.tsx +++ b/src/components/VolumeBar.tsx @@ -50,7 +50,9 @@ export const VolumeBar = (props: VolumeBarProps) => { const presto = await player.presto() const current = presto.isMuted() ? 0 : presto.getVolume() let targetPosition = current - + + if (targetPosition == null || current == null) {return} + if (e.key === 'ArrowLeft') { targetPosition = Math.max(0, current + (-0.1)) e.preventDefault() diff --git a/src/react.ts b/src/react.ts index 9c43dc8..cbd699d 100644 --- a/src/react.ts +++ b/src/react.ts @@ -6,7 +6,7 @@ import { PrestoContext } from './context/PrestoContext' import { EventListener, EventType } from './EventEmitter' import { Player, State, UIEvents } from './Player' -export type ClppEventHandler = (e: clpp.Event, presto: clpp.Player) => void +export type ClppEventHandler = (e: any, presto: clpp.Player) => void /** * This is a React hook that can be used to listen to presto play events. @@ -28,7 +28,7 @@ export function usePrestoCoreEvent( const presto = useContext(PrestoContext).presto ?? presto_ useEffect(() => { - const handleEvent = (event: clpp.Event) => { + const handleEvent = (event: any) => { handler(event, presto) } diff --git a/types/presto.d.ts b/types/presto.d.ts index 2982e59..ab93cad 100644 --- a/types/presto.d.ts +++ b/types/presto.d.ts @@ -1,205 +1,7334 @@ /** - * Taken from @see {@link https://demo.castlabs.com/#/docs?q=clpp.Player} + * These typings will shortly become available on NPM as part of `@castlabs/prestoplay`. + * When they are, delete this file! */ declare module '@castlabs/prestoplay' { + export namespace clpp { - type Event = { - detail: Record + export interface IPlayerSurface { + /** + * Adds the given element to the container. + * Throws an error if no container is available. + * + * @param element The element to add + * @param opt_fill If true, the css fill class will be applied + * @param opt_prepend If true, appends the element at the beginning + */ + addElementToContainer(element: Element, opt_fill?: boolean, opt_prepend?: boolean): void + /** + * Returns the cast media player element on Chromecast Web Receiver. + * Note that this will return an element only when using + * `` instead of `