@aigamo/nostalgic-diva 0.0.1-alpha.68 → 0.0.1-alpha.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PlayerContainer-COjwHOhq.cjs.map +1 -1
- package/dist/PlayerContainer-VQ3YPGU_.js.map +1 -1
- package/dist/SpotifyPlayer-DUKJP7Jz.cjs +2 -0
- package/dist/SpotifyPlayer-DUKJP7Jz.cjs.map +1 -0
- package/dist/SpotifyPlayer-DbZNyvp-.js +38 -0
- package/dist/SpotifyPlayer-DbZNyvp-.js.map +1 -0
- package/dist/{TwitchPlayer-BeQUOIE3.js → TwitchPlayer-Bn8o_9f5.js} +1 -1
- package/dist/{TwitchPlayer-BeQUOIE3.js.map → TwitchPlayer-Bn8o_9f5.js.map} +1 -1
- package/dist/{TwitchPlayer-Doh6zF0n.cjs → TwitchPlayer-SK7o8pMq.cjs} +1 -1
- package/dist/{TwitchPlayer-Doh6zF0n.cjs.map → TwitchPlayer-SK7o8pMq.cjs.map} +1 -1
- package/dist/{VimeoPlayer-7MjNmmgs.cjs → VimeoPlayer-BySLiRru.cjs} +1 -1
- package/dist/{VimeoPlayer-7MjNmmgs.cjs.map → VimeoPlayer-BySLiRru.cjs.map} +1 -1
- package/dist/{VimeoPlayer-CgWujBXW.js → VimeoPlayer-Cz5hB9JG.js} +1 -1
- package/dist/{VimeoPlayer-CgWujBXW.js.map → VimeoPlayer-Cz5hB9JG.js.map} +1 -1
- package/dist/{YouTubePlayer-CkaOKK_g.js → YouTubePlayer-C_fmW0IS.js} +1 -1
- package/dist/{YouTubePlayer-CkaOKK_g.js.map → YouTubePlayer-C_fmW0IS.js.map} +1 -1
- package/dist/{YouTubePlayer-Clpmqsmv.cjs → YouTubePlayer-vLFVWfOz.cjs} +1 -1
- package/dist/{YouTubePlayer-Clpmqsmv.cjs.map → YouTubePlayer-vLFVWfOz.cjs.map} +1 -1
- package/dist/components/SpotifyPlayer.d.ts +4 -0
- package/dist/controllers/PlayerController.d.ts +1 -1
- package/dist/controllers/SpotifyPlayerController.d.ts +23 -0
- package/dist/controllers/index.d.ts +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +102 -45
- package/dist/index.es.js.map +1 -1
- package/dist/services/SpotifyVideoService.d.ts +6 -0
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayerContainer-COjwHOhq.cjs","names":[],"sources":["../src/controllers/Logger.ts","../src/controllers/NullPlayerController.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/controllers/PlayerControllerImpl.ts","../src/controllers/PlayerController.ts","../src/components/PlayerContainer.tsx"],"sourcesContent":["// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/LogLevel.cs,d07793e8b722b77e,references\nexport enum LogLevel {\n\t/**\n\t * Logs that contain the most detailed messages. These messages may contain sensitive application data.\n\t * These messages are disabled by default and should never be enabled in a production environment.\n\t */\n\tTrace = 0,\n\t/**\n\t * Logs that are used for interactive investigation during development. These logs should primarily contain\n\t * information useful for debugging and have no long-term value.\n\t */\n\tDebug = 1,\n\t/**\n\t * Logs that track the general flow of the application. These logs should have long-term value.\n\t */\n\tInformation = 2,\n\t/**\n\t * Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the\n\t * application execution to stop.\n\t */\n\tWarning = 3,\n\t/**\n\t * Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a\n\t * failure in the current activity, not an application-wide failure.\n\t */\n\tError = 4,\n\t/**\n\t * Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires\n\t * immediate attention.\n\t */\n\tCritical = 5,\n\t/**\n\t * Not used for writing log messages. Specifies that a logging category should not write any messages.\n\t */\n\tNone = 6,\n}\n\n// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/ILogger.cs,0976525f5d1b9e54,references\nexport interface ILogger {\n\tisEnabled(logLevel: LogLevel): boolean;\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void;\n}\n\nclass Logger implements ILogger {\n\tprivate readonly title = 'nostalgic-diva';\n\n\tprivate createMessage(message: any): string {\n\t\treturn `[${this.title}] ${message}`;\n\t}\n\n\tprivate debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(this.createMessage(message), ...optionalParams);\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void {\n\t\tswitch (logLevel) {\n\t\t\tcase LogLevel.Debug:\n\t\t\t\tthis.debug(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Warning:\n\t\t\t\tthis.warn(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Error:\n\t\t\t\tthis.error(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport const defaultLogger = new Logger();\n","import type {\n\tIPlayerCommands,\n\tIPlayerController,\n} from '@/controllers/PlayerController';\n\nclass NullPlayerController implements IPlayerController {\n\tasync attach(): Promise<void> {}\n\n\tasync detach(): Promise<void> {}\n\n\tasync loadVideo(_id: string): Promise<void> {}\n\n\tasync play(): Promise<void> {}\n\n\tasync pause(): Promise<void> {}\n\n\tasync setCurrentTime(_seconds: number): Promise<void> {}\n\n\tasync setVolume(_volume: number): Promise<void> {}\n\n\tasync setMuted(_muted: boolean): Promise<void> {}\n\n\tasync setPlaybackRate(_playbackRate: number): Promise<void> {}\n\n\tasync getDuration(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getCurrentTime(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getVolume(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getMuted(): Promise<boolean> {\n\t\treturn false;\n\t}\n\n\tasync getPlaybackRate(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tsupports(_command: keyof IPlayerCommands): boolean {\n\t\treturn false;\n\t}\n}\n\nexport const nullPlayerController = new NullPlayerController();\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useFirstMountState } from '@/components/useFirstMountState';\nimport { useRef } from 'react';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport type {\n\tIPlayerCommands,\n\tPlayerOptions,\n} from '@/controllers/PlayerController';\n\nexport abstract class PlayerControllerImpl<\n\tTPlayer,\n> implements Partial<IPlayerCommands> {\n\tconstructor(\n\t\tprotected readonly logger: ILogger,\n\t\tprotected readonly player: TPlayer,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.log(LogLevel.Debug, 'ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo?(id: string): Promise<void>;\n\tabstract play?(): Promise<void>;\n\tabstract pause?(): Promise<void>;\n\tabstract setCurrentTime?(seconds: number): Promise<void>;\n\tabstract setVolume?(volume: number): Promise<void>;\n\tabstract setMuted?(muted: boolean): Promise<void>;\n\tabstract setPlaybackRate?(playbackRate: number): Promise<void>;\n\tabstract getDuration?(): Promise<number>;\n\tabstract getCurrentTime?(): Promise<number>;\n\tabstract getVolume?(): Promise<number>;\n\tabstract getMuted?(): Promise<boolean>;\n\tabstract getPlaybackRate?(): Promise<number>;\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\treturn this[command] !== undefined;\n\t}\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Dailymotion'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Twitch'\n\t| 'Vimeo'\n\t| 'YouTube'\n\t| (string & {});\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number;\n\tpercent: number;\n\tseconds: number;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerCommands {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tsetPlaybackRate(playbackRate: number): Promise<void>;\n\tgetDuration(): Promise<number>;\n\tgetCurrentTime(): Promise<number>;\n\tgetVolume(): Promise<number>;\n\tgetMuted(): Promise<boolean>;\n\tgetPlaybackRate(): Promise<number>;\n}\n\nexport interface IPlayerController extends IPlayerCommands {\n\tsupports(command: keyof IPlayerCommands): boolean;\n}\n\nexport class PlayerController<\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> implements IPlayerController {\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TController;\n\n\tconstructor(\n\t\tprivate readonly logger: ILogger,\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly player: TPlayer,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly controllerFactory: new (\n\t\t\tlogger: ILogger,\n\t\t\tplayer: TPlayer,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TController,\n\t) {\n\t\tthis.id = PlayerController.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Error,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.controllerFactory(\n\t\t\tthis.logger,\n\t\t\tthis.player,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate createPlayerNotAttachedError(): Error {\n\t\tthis.error('player is not attached');\n\n\t\treturn new Error('player is not attached');\n\t}\n\n\tprivate createCommandNotSupportedError(\n\t\tcommand: keyof IPlayerCommands,\n\t): Error {\n\t\treturn new Error(`${command} is not supported`);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tawait this.impl.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.loadVideo === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('loadVideo');\n\t\t}\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tplay(): Promise<void> {\n\t\tthis.debug('play');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.play === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('play');\n\t\t}\n\n\t\treturn this.impl.play();\n\t}\n\n\tpause(): Promise<void> {\n\t\tthis.debug('pause');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.pause === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('pause');\n\t\t}\n\n\t\treturn this.impl.pause();\n\t}\n\n\tsetCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setCurrentTime');\n\t\t}\n\n\t\treturn this.impl.setCurrentTime(seconds);\n\t}\n\n\tsetVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setVolume');\n\t\t}\n\n\t\treturn this.impl.setVolume(volume);\n\t}\n\n\tsetMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setMuted');\n\t\t}\n\n\t\treturn this.impl.setMuted(muted);\n\t}\n\n\tsetPlaybackRate(playbackRate: number): Promise<void> {\n\t\tthis.debug('setPlaybackRate', playbackRate);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.setPlaybackRate(playbackRate);\n\t}\n\n\tgetDuration(): Promise<number> {\n\t\tthis.debug('getDuration');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getDuration === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getDuration');\n\t\t}\n\n\t\treturn this.impl.getDuration();\n\t}\n\n\tgetCurrentTime(): Promise<number> {\n\t\tthis.debug('getCurrentTime');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getCurrentTime');\n\t\t}\n\n\t\treturn this.impl.getCurrentTime();\n\t}\n\n\tgetVolume(): Promise<number> {\n\t\tthis.debug('getVolume');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getVolume');\n\t\t}\n\n\t\treturn this.impl.getVolume();\n\t}\n\n\tgetMuted(): Promise<boolean> {\n\t\tthis.debug('getMuted');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getMuted');\n\t\t}\n\n\t\treturn this.impl.getMuted();\n\t}\n\n\tgetPlaybackRate(): Promise<number> {\n\t\tthis.debug('getPlaybackRate');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.getPlaybackRate();\n\t}\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.supports(command);\n\t}\n}\n","import usePreviousDistinct from '@/components/usePreviousDistinct';\nimport { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { nullPlayerController } from '@/controllers/NullPlayerController';\nimport {\n\ttype IPlayerController,\n\tPlayerController,\n\ttype PlayerOptions,\n\ttype PlayerType,\n} from '@/controllers/PlayerController';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\nimport {\n\ttype MutableRefObject,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\nexport interface PlayerProps {\n\tlogger: ILogger;\n\ttype: PlayerType;\n\tonControllerChange: ((value: IPlayerController) => void) | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerFactory: (element: TElement, videoId: string) => Promise<TPlayer>;\n\tcontrollerFactory: new (\n\t\tlogger: ILogger,\n\t\tplayer: TPlayer,\n\t\toptions: PlayerOptions | undefined,\n\t) => TController;\n\tchildren: (\n\t\telementRef: MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n>({\n\tlogger,\n\ttype,\n\tloadScript,\n\tplayerFactory,\n\tonControllerChange,\n\tvideoId,\n\toptions,\n\tcontrollerFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer, TController>): ReactElement<\n\tPlayerContainerProps<TElement, TPlayer, TController>\n> => {\n\tlogger.log(LogLevel.Debug, 'PlayerContainer');\n\n\tconst videoIdRef = useRef(videoId);\n\n\tconst elementRef = useRef<TElement>(undefined!);\n\n\tconst [player, setPlayer] = useState<TPlayer>();\n\n\tconst [controller, _setController] =\n\t\tuseState<IPlayerController>(nullPlayerController);\n\n\tconst setController = useCallback(\n\t\t(value: IPlayerController): void => {\n\t\t\t_setController(value);\n\n\t\t\tonControllerChange?.(value);\n\t\t},\n\t\t[onControllerChange],\n\t);\n\n\tuseEffect(() => {\n\t\tvoid (loadScript?.() ?? Promise.resolve())\n\t\t\t.then(() => playerFactory(elementRef.current, videoIdRef.current))\n\t\t\t.then((player) => setPlayer(player));\n\t}, [loadScript, playerFactory]);\n\n\t// Make sure that `options` do not change between re-rendering.\n\tuseEffect(() => {\n\t\tif (player === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst controller = new PlayerController(\n\t\t\tlogger,\n\t\t\ttype,\n\t\t\tplayer,\n\t\t\toptions,\n\t\t\tcontrollerFactory,\n\t\t);\n\n\t\tvoid controller\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setController(controller));\n\n\t\treturn (): void => {\n\t\t\tvoid controller\n\t\t\t\t.detach()\n\t\t\t\t.finally(() => setController(nullPlayerController));\n\t\t};\n\t}, [\n\t\tlogger,\n\t\ttype,\n\t\tloadScript,\n\t\tplayer,\n\t\toptions,\n\t\tcontrollerFactory,\n\t\tsetController,\n\t]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tuseEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer`).\n\t\tif (previousVideoId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid controller.loadVideo(videoId);\n\t}, [previousVideoId, videoId, controller]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(elementRef, videoIdRef.current)}</>;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlayerContainer-COjwHOhq.cjs","names":[],"sources":["../src/controllers/Logger.ts","../src/controllers/NullPlayerController.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/controllers/PlayerControllerImpl.ts","../src/controllers/PlayerController.ts","../src/components/PlayerContainer.tsx"],"sourcesContent":["// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/LogLevel.cs,d07793e8b722b77e,references\nexport enum LogLevel {\n\t/**\n\t * Logs that contain the most detailed messages. These messages may contain sensitive application data.\n\t * These messages are disabled by default and should never be enabled in a production environment.\n\t */\n\tTrace = 0,\n\t/**\n\t * Logs that are used for interactive investigation during development. These logs should primarily contain\n\t * information useful for debugging and have no long-term value.\n\t */\n\tDebug = 1,\n\t/**\n\t * Logs that track the general flow of the application. These logs should have long-term value.\n\t */\n\tInformation = 2,\n\t/**\n\t * Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the\n\t * application execution to stop.\n\t */\n\tWarning = 3,\n\t/**\n\t * Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a\n\t * failure in the current activity, not an application-wide failure.\n\t */\n\tError = 4,\n\t/**\n\t * Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires\n\t * immediate attention.\n\t */\n\tCritical = 5,\n\t/**\n\t * Not used for writing log messages. Specifies that a logging category should not write any messages.\n\t */\n\tNone = 6,\n}\n\n// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/ILogger.cs,0976525f5d1b9e54,references\nexport interface ILogger {\n\tisEnabled(logLevel: LogLevel): boolean;\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void;\n}\n\nclass Logger implements ILogger {\n\tprivate readonly title = 'nostalgic-diva';\n\n\tprivate createMessage(message: any): string {\n\t\treturn `[${this.title}] ${message}`;\n\t}\n\n\tprivate debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(this.createMessage(message), ...optionalParams);\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void {\n\t\tswitch (logLevel) {\n\t\t\tcase LogLevel.Debug:\n\t\t\t\tthis.debug(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Warning:\n\t\t\t\tthis.warn(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Error:\n\t\t\t\tthis.error(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport const defaultLogger = new Logger();\n","import type {\n\tIPlayerCommands,\n\tIPlayerController,\n} from '@/controllers/PlayerController';\n\nclass NullPlayerController implements IPlayerController {\n\tasync attach(): Promise<void> {}\n\n\tasync detach(): Promise<void> {}\n\n\tasync loadVideo(_id: string): Promise<void> {}\n\n\tasync play(): Promise<void> {}\n\n\tasync pause(): Promise<void> {}\n\n\tasync setCurrentTime(_seconds: number): Promise<void> {}\n\n\tasync setVolume(_volume: number): Promise<void> {}\n\n\tasync setMuted(_muted: boolean): Promise<void> {}\n\n\tasync setPlaybackRate(_playbackRate: number): Promise<void> {}\n\n\tasync getDuration(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getCurrentTime(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getVolume(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getMuted(): Promise<boolean> {\n\t\treturn false;\n\t}\n\n\tasync getPlaybackRate(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tsupports(_command: keyof IPlayerCommands): boolean {\n\t\treturn false;\n\t}\n}\n\nexport const nullPlayerController = new NullPlayerController();\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useFirstMountState } from '@/components/useFirstMountState';\nimport { useRef } from 'react';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport type {\n\tIPlayerCommands,\n\tPlayerOptions,\n} from '@/controllers/PlayerController';\n\nexport abstract class PlayerControllerImpl<\n\tTPlayer,\n> implements Partial<IPlayerCommands> {\n\tconstructor(\n\t\tprotected readonly logger: ILogger,\n\t\tprotected readonly player: TPlayer,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.log(LogLevel.Debug, 'ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo?(id: string): Promise<void>;\n\tabstract play?(): Promise<void>;\n\tabstract pause?(): Promise<void>;\n\tabstract setCurrentTime?(seconds: number): Promise<void>;\n\tabstract setVolume?(volume: number): Promise<void>;\n\tabstract setMuted?(muted: boolean): Promise<void>;\n\tabstract setPlaybackRate?(playbackRate: number): Promise<void>;\n\tabstract getDuration?(): Promise<number>;\n\tabstract getCurrentTime?(): Promise<number>;\n\tabstract getVolume?(): Promise<number>;\n\tabstract getMuted?(): Promise<boolean>;\n\tabstract getPlaybackRate?(): Promise<number>;\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\treturn this[command] !== undefined;\n\t}\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Dailymotion'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Spotify'\n\t| 'Twitch'\n\t| 'Vimeo'\n\t| 'YouTube'\n\t| (string & {});\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number;\n\tpercent: number;\n\tseconds: number;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerCommands {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tsetPlaybackRate(playbackRate: number): Promise<void>;\n\tgetDuration(): Promise<number>;\n\tgetCurrentTime(): Promise<number>;\n\tgetVolume(): Promise<number>;\n\tgetMuted(): Promise<boolean>;\n\tgetPlaybackRate(): Promise<number>;\n}\n\nexport interface IPlayerController extends IPlayerCommands {\n\tsupports(command: keyof IPlayerCommands): boolean;\n}\n\nexport class PlayerController<\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> implements IPlayerController {\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TController;\n\n\tconstructor(\n\t\tprivate readonly logger: ILogger,\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly player: TPlayer,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly controllerFactory: new (\n\t\t\tlogger: ILogger,\n\t\t\tplayer: TPlayer,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TController,\n\t) {\n\t\tthis.id = PlayerController.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Error,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.controllerFactory(\n\t\t\tthis.logger,\n\t\t\tthis.player,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate createPlayerNotAttachedError(): Error {\n\t\tthis.error('player is not attached');\n\n\t\treturn new Error('player is not attached');\n\t}\n\n\tprivate createCommandNotSupportedError(\n\t\tcommand: keyof IPlayerCommands,\n\t): Error {\n\t\treturn new Error(`${command} is not supported`);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tawait this.impl.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.loadVideo === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('loadVideo');\n\t\t}\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tplay(): Promise<void> {\n\t\tthis.debug('play');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.play === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('play');\n\t\t}\n\n\t\treturn this.impl.play();\n\t}\n\n\tpause(): Promise<void> {\n\t\tthis.debug('pause');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.pause === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('pause');\n\t\t}\n\n\t\treturn this.impl.pause();\n\t}\n\n\tsetCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setCurrentTime');\n\t\t}\n\n\t\treturn this.impl.setCurrentTime(seconds);\n\t}\n\n\tsetVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setVolume');\n\t\t}\n\n\t\treturn this.impl.setVolume(volume);\n\t}\n\n\tsetMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setMuted');\n\t\t}\n\n\t\treturn this.impl.setMuted(muted);\n\t}\n\n\tsetPlaybackRate(playbackRate: number): Promise<void> {\n\t\tthis.debug('setPlaybackRate', playbackRate);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.setPlaybackRate(playbackRate);\n\t}\n\n\tgetDuration(): Promise<number> {\n\t\tthis.debug('getDuration');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getDuration === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getDuration');\n\t\t}\n\n\t\treturn this.impl.getDuration();\n\t}\n\n\tgetCurrentTime(): Promise<number> {\n\t\tthis.debug('getCurrentTime');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getCurrentTime');\n\t\t}\n\n\t\treturn this.impl.getCurrentTime();\n\t}\n\n\tgetVolume(): Promise<number> {\n\t\tthis.debug('getVolume');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getVolume');\n\t\t}\n\n\t\treturn this.impl.getVolume();\n\t}\n\n\tgetMuted(): Promise<boolean> {\n\t\tthis.debug('getMuted');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getMuted');\n\t\t}\n\n\t\treturn this.impl.getMuted();\n\t}\n\n\tgetPlaybackRate(): Promise<number> {\n\t\tthis.debug('getPlaybackRate');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.getPlaybackRate();\n\t}\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.supports(command);\n\t}\n}\n","import usePreviousDistinct from '@/components/usePreviousDistinct';\nimport { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { nullPlayerController } from '@/controllers/NullPlayerController';\nimport {\n\ttype IPlayerController,\n\tPlayerController,\n\ttype PlayerOptions,\n\ttype PlayerType,\n} from '@/controllers/PlayerController';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\nimport {\n\ttype MutableRefObject,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\nexport interface PlayerProps {\n\tlogger: ILogger;\n\ttype: PlayerType;\n\tonControllerChange: ((value: IPlayerController) => void) | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerFactory: (element: TElement, videoId: string) => Promise<TPlayer>;\n\tcontrollerFactory: new (\n\t\tlogger: ILogger,\n\t\tplayer: TPlayer,\n\t\toptions: PlayerOptions | undefined,\n\t) => TController;\n\tchildren: (\n\t\telementRef: MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n>({\n\tlogger,\n\ttype,\n\tloadScript,\n\tplayerFactory,\n\tonControllerChange,\n\tvideoId,\n\toptions,\n\tcontrollerFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer, TController>): ReactElement<\n\tPlayerContainerProps<TElement, TPlayer, TController>\n> => {\n\tlogger.log(LogLevel.Debug, 'PlayerContainer');\n\n\tconst videoIdRef = useRef(videoId);\n\n\tconst elementRef = useRef<TElement>(undefined!);\n\n\tconst [player, setPlayer] = useState<TPlayer>();\n\n\tconst [controller, _setController] =\n\t\tuseState<IPlayerController>(nullPlayerController);\n\n\tconst setController = useCallback(\n\t\t(value: IPlayerController): void => {\n\t\t\t_setController(value);\n\n\t\t\tonControllerChange?.(value);\n\t\t},\n\t\t[onControllerChange],\n\t);\n\n\tuseEffect(() => {\n\t\tvoid (loadScript?.() ?? Promise.resolve())\n\t\t\t.then(() => playerFactory(elementRef.current, videoIdRef.current))\n\t\t\t.then((player) => setPlayer(player));\n\t}, [loadScript, playerFactory]);\n\n\t// Make sure that `options` do not change between re-rendering.\n\tuseEffect(() => {\n\t\tif (player === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst controller = new PlayerController(\n\t\t\tlogger,\n\t\t\ttype,\n\t\t\tplayer,\n\t\t\toptions,\n\t\t\tcontrollerFactory,\n\t\t);\n\n\t\tvoid controller\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setController(controller));\n\n\t\treturn (): void => {\n\t\t\tvoid controller\n\t\t\t\t.detach()\n\t\t\t\t.finally(() => setController(nullPlayerController));\n\t\t};\n\t}, [\n\t\tlogger,\n\t\ttype,\n\t\tloadScript,\n\t\tplayer,\n\t\toptions,\n\t\tcontrollerFactory,\n\t\tsetController,\n\t]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tuseEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer` and `SpotifyPlayer`).\n\t\tif (previousVideoId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid controller.loadVideo(videoId);\n\t}, [previousVideoId, videoId, controller]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(elementRef, videoIdRef.current)}</>;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayerContainer-VQ3YPGU_.js","names":[],"sources":["../src/controllers/Logger.ts","../src/controllers/NullPlayerController.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/controllers/PlayerControllerImpl.ts","../src/controllers/PlayerController.ts","../src/components/PlayerContainer.tsx"],"sourcesContent":["// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/LogLevel.cs,d07793e8b722b77e,references\nexport enum LogLevel {\n\t/**\n\t * Logs that contain the most detailed messages. These messages may contain sensitive application data.\n\t * These messages are disabled by default and should never be enabled in a production environment.\n\t */\n\tTrace = 0,\n\t/**\n\t * Logs that are used for interactive investigation during development. These logs should primarily contain\n\t * information useful for debugging and have no long-term value.\n\t */\n\tDebug = 1,\n\t/**\n\t * Logs that track the general flow of the application. These logs should have long-term value.\n\t */\n\tInformation = 2,\n\t/**\n\t * Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the\n\t * application execution to stop.\n\t */\n\tWarning = 3,\n\t/**\n\t * Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a\n\t * failure in the current activity, not an application-wide failure.\n\t */\n\tError = 4,\n\t/**\n\t * Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires\n\t * immediate attention.\n\t */\n\tCritical = 5,\n\t/**\n\t * Not used for writing log messages. Specifies that a logging category should not write any messages.\n\t */\n\tNone = 6,\n}\n\n// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/ILogger.cs,0976525f5d1b9e54,references\nexport interface ILogger {\n\tisEnabled(logLevel: LogLevel): boolean;\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void;\n}\n\nclass Logger implements ILogger {\n\tprivate readonly title = 'nostalgic-diva';\n\n\tprivate createMessage(message: any): string {\n\t\treturn `[${this.title}] ${message}`;\n\t}\n\n\tprivate debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(this.createMessage(message), ...optionalParams);\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void {\n\t\tswitch (logLevel) {\n\t\t\tcase LogLevel.Debug:\n\t\t\t\tthis.debug(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Warning:\n\t\t\t\tthis.warn(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Error:\n\t\t\t\tthis.error(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport const defaultLogger = new Logger();\n","import type {\n\tIPlayerCommands,\n\tIPlayerController,\n} from '@/controllers/PlayerController';\n\nclass NullPlayerController implements IPlayerController {\n\tasync attach(): Promise<void> {}\n\n\tasync detach(): Promise<void> {}\n\n\tasync loadVideo(_id: string): Promise<void> {}\n\n\tasync play(): Promise<void> {}\n\n\tasync pause(): Promise<void> {}\n\n\tasync setCurrentTime(_seconds: number): Promise<void> {}\n\n\tasync setVolume(_volume: number): Promise<void> {}\n\n\tasync setMuted(_muted: boolean): Promise<void> {}\n\n\tasync setPlaybackRate(_playbackRate: number): Promise<void> {}\n\n\tasync getDuration(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getCurrentTime(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getVolume(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getMuted(): Promise<boolean> {\n\t\treturn false;\n\t}\n\n\tasync getPlaybackRate(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tsupports(_command: keyof IPlayerCommands): boolean {\n\t\treturn false;\n\t}\n}\n\nexport const nullPlayerController = new NullPlayerController();\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useFirstMountState } from '@/components/useFirstMountState';\nimport { useRef } from 'react';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport type {\n\tIPlayerCommands,\n\tPlayerOptions,\n} from '@/controllers/PlayerController';\n\nexport abstract class PlayerControllerImpl<\n\tTPlayer,\n> implements Partial<IPlayerCommands> {\n\tconstructor(\n\t\tprotected readonly logger: ILogger,\n\t\tprotected readonly player: TPlayer,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.log(LogLevel.Debug, 'ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo?(id: string): Promise<void>;\n\tabstract play?(): Promise<void>;\n\tabstract pause?(): Promise<void>;\n\tabstract setCurrentTime?(seconds: number): Promise<void>;\n\tabstract setVolume?(volume: number): Promise<void>;\n\tabstract setMuted?(muted: boolean): Promise<void>;\n\tabstract setPlaybackRate?(playbackRate: number): Promise<void>;\n\tabstract getDuration?(): Promise<number>;\n\tabstract getCurrentTime?(): Promise<number>;\n\tabstract getVolume?(): Promise<number>;\n\tabstract getMuted?(): Promise<boolean>;\n\tabstract getPlaybackRate?(): Promise<number>;\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\treturn this[command] !== undefined;\n\t}\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Dailymotion'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Twitch'\n\t| 'Vimeo'\n\t| 'YouTube'\n\t| (string & {});\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number;\n\tpercent: number;\n\tseconds: number;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerCommands {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tsetPlaybackRate(playbackRate: number): Promise<void>;\n\tgetDuration(): Promise<number>;\n\tgetCurrentTime(): Promise<number>;\n\tgetVolume(): Promise<number>;\n\tgetMuted(): Promise<boolean>;\n\tgetPlaybackRate(): Promise<number>;\n}\n\nexport interface IPlayerController extends IPlayerCommands {\n\tsupports(command: keyof IPlayerCommands): boolean;\n}\n\nexport class PlayerController<\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> implements IPlayerController {\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TController;\n\n\tconstructor(\n\t\tprivate readonly logger: ILogger,\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly player: TPlayer,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly controllerFactory: new (\n\t\t\tlogger: ILogger,\n\t\t\tplayer: TPlayer,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TController,\n\t) {\n\t\tthis.id = PlayerController.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Error,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.controllerFactory(\n\t\t\tthis.logger,\n\t\t\tthis.player,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate createPlayerNotAttachedError(): Error {\n\t\tthis.error('player is not attached');\n\n\t\treturn new Error('player is not attached');\n\t}\n\n\tprivate createCommandNotSupportedError(\n\t\tcommand: keyof IPlayerCommands,\n\t): Error {\n\t\treturn new Error(`${command} is not supported`);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tawait this.impl.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.loadVideo === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('loadVideo');\n\t\t}\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tplay(): Promise<void> {\n\t\tthis.debug('play');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.play === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('play');\n\t\t}\n\n\t\treturn this.impl.play();\n\t}\n\n\tpause(): Promise<void> {\n\t\tthis.debug('pause');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.pause === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('pause');\n\t\t}\n\n\t\treturn this.impl.pause();\n\t}\n\n\tsetCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setCurrentTime');\n\t\t}\n\n\t\treturn this.impl.setCurrentTime(seconds);\n\t}\n\n\tsetVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setVolume');\n\t\t}\n\n\t\treturn this.impl.setVolume(volume);\n\t}\n\n\tsetMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setMuted');\n\t\t}\n\n\t\treturn this.impl.setMuted(muted);\n\t}\n\n\tsetPlaybackRate(playbackRate: number): Promise<void> {\n\t\tthis.debug('setPlaybackRate', playbackRate);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.setPlaybackRate(playbackRate);\n\t}\n\n\tgetDuration(): Promise<number> {\n\t\tthis.debug('getDuration');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getDuration === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getDuration');\n\t\t}\n\n\t\treturn this.impl.getDuration();\n\t}\n\n\tgetCurrentTime(): Promise<number> {\n\t\tthis.debug('getCurrentTime');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getCurrentTime');\n\t\t}\n\n\t\treturn this.impl.getCurrentTime();\n\t}\n\n\tgetVolume(): Promise<number> {\n\t\tthis.debug('getVolume');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getVolume');\n\t\t}\n\n\t\treturn this.impl.getVolume();\n\t}\n\n\tgetMuted(): Promise<boolean> {\n\t\tthis.debug('getMuted');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getMuted');\n\t\t}\n\n\t\treturn this.impl.getMuted();\n\t}\n\n\tgetPlaybackRate(): Promise<number> {\n\t\tthis.debug('getPlaybackRate');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.getPlaybackRate();\n\t}\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.supports(command);\n\t}\n}\n","import usePreviousDistinct from '@/components/usePreviousDistinct';\nimport { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { nullPlayerController } from '@/controllers/NullPlayerController';\nimport {\n\ttype IPlayerController,\n\tPlayerController,\n\ttype PlayerOptions,\n\ttype PlayerType,\n} from '@/controllers/PlayerController';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\nimport {\n\ttype MutableRefObject,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\nexport interface PlayerProps {\n\tlogger: ILogger;\n\ttype: PlayerType;\n\tonControllerChange: ((value: IPlayerController) => void) | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerFactory: (element: TElement, videoId: string) => Promise<TPlayer>;\n\tcontrollerFactory: new (\n\t\tlogger: ILogger,\n\t\tplayer: TPlayer,\n\t\toptions: PlayerOptions | undefined,\n\t) => TController;\n\tchildren: (\n\t\telementRef: MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n>({\n\tlogger,\n\ttype,\n\tloadScript,\n\tplayerFactory,\n\tonControllerChange,\n\tvideoId,\n\toptions,\n\tcontrollerFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer, TController>): ReactElement<\n\tPlayerContainerProps<TElement, TPlayer, TController>\n> => {\n\tlogger.log(LogLevel.Debug, 'PlayerContainer');\n\n\tconst videoIdRef = useRef(videoId);\n\n\tconst elementRef = useRef<TElement>(undefined!);\n\n\tconst [player, setPlayer] = useState<TPlayer>();\n\n\tconst [controller, _setController] =\n\t\tuseState<IPlayerController>(nullPlayerController);\n\n\tconst setController = useCallback(\n\t\t(value: IPlayerController): void => {\n\t\t\t_setController(value);\n\n\t\t\tonControllerChange?.(value);\n\t\t},\n\t\t[onControllerChange],\n\t);\n\n\tuseEffect(() => {\n\t\tvoid (loadScript?.() ?? Promise.resolve())\n\t\t\t.then(() => playerFactory(elementRef.current, videoIdRef.current))\n\t\t\t.then((player) => setPlayer(player));\n\t}, [loadScript, playerFactory]);\n\n\t// Make sure that `options` do not change between re-rendering.\n\tuseEffect(() => {\n\t\tif (player === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst controller = new PlayerController(\n\t\t\tlogger,\n\t\t\ttype,\n\t\t\tplayer,\n\t\t\toptions,\n\t\t\tcontrollerFactory,\n\t\t);\n\n\t\tvoid controller\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setController(controller));\n\n\t\treturn (): void => {\n\t\t\tvoid controller\n\t\t\t\t.detach()\n\t\t\t\t.finally(() => setController(nullPlayerController));\n\t\t};\n\t}, [\n\t\tlogger,\n\t\ttype,\n\t\tloadScript,\n\t\tplayer,\n\t\toptions,\n\t\tcontrollerFactory,\n\t\tsetController,\n\t]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tuseEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer`).\n\t\tif (previousVideoId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid controller.loadVideo(videoId);\n\t}, [previousVideoId, videoId, controller]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(elementRef, videoIdRef.current)}</>;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlayerContainer-VQ3YPGU_.js","names":[],"sources":["../src/controllers/Logger.ts","../src/controllers/NullPlayerController.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/controllers/PlayerControllerImpl.ts","../src/controllers/PlayerController.ts","../src/components/PlayerContainer.tsx"],"sourcesContent":["// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/LogLevel.cs,d07793e8b722b77e,references\nexport enum LogLevel {\n\t/**\n\t * Logs that contain the most detailed messages. These messages may contain sensitive application data.\n\t * These messages are disabled by default and should never be enabled in a production environment.\n\t */\n\tTrace = 0,\n\t/**\n\t * Logs that are used for interactive investigation during development. These logs should primarily contain\n\t * information useful for debugging and have no long-term value.\n\t */\n\tDebug = 1,\n\t/**\n\t * Logs that track the general flow of the application. These logs should have long-term value.\n\t */\n\tInformation = 2,\n\t/**\n\t * Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the\n\t * application execution to stop.\n\t */\n\tWarning = 3,\n\t/**\n\t * Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a\n\t * failure in the current activity, not an application-wide failure.\n\t */\n\tError = 4,\n\t/**\n\t * Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires\n\t * immediate attention.\n\t */\n\tCritical = 5,\n\t/**\n\t * Not used for writing log messages. Specifies that a logging category should not write any messages.\n\t */\n\tNone = 6,\n}\n\n// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/ILogger.cs,0976525f5d1b9e54,references\nexport interface ILogger {\n\tisEnabled(logLevel: LogLevel): boolean;\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void;\n}\n\nclass Logger implements ILogger {\n\tprivate readonly title = 'nostalgic-diva';\n\n\tprivate createMessage(message: any): string {\n\t\treturn `[${this.title}] ${message}`;\n\t}\n\n\tprivate debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(this.createMessage(message), ...optionalParams);\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void {\n\t\tswitch (logLevel) {\n\t\t\tcase LogLevel.Debug:\n\t\t\t\tthis.debug(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Warning:\n\t\t\t\tthis.warn(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Error:\n\t\t\t\tthis.error(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nexport const defaultLogger = new Logger();\n","import type {\n\tIPlayerCommands,\n\tIPlayerController,\n} from '@/controllers/PlayerController';\n\nclass NullPlayerController implements IPlayerController {\n\tasync attach(): Promise<void> {}\n\n\tasync detach(): Promise<void> {}\n\n\tasync loadVideo(_id: string): Promise<void> {}\n\n\tasync play(): Promise<void> {}\n\n\tasync pause(): Promise<void> {}\n\n\tasync setCurrentTime(_seconds: number): Promise<void> {}\n\n\tasync setVolume(_volume: number): Promise<void> {}\n\n\tasync setMuted(_muted: boolean): Promise<void> {}\n\n\tasync setPlaybackRate(_playbackRate: number): Promise<void> {}\n\n\tasync getDuration(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getCurrentTime(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getVolume(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tasync getMuted(): Promise<boolean> {\n\t\treturn false;\n\t}\n\n\tasync getPlaybackRate(): Promise<number> {\n\t\treturn 0;\n\t}\n\n\tsupports(_command: keyof IPlayerCommands): boolean {\n\t\treturn false;\n\t}\n}\n\nexport const nullPlayerController = new NullPlayerController();\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useFirstMountState } from '@/components/useFirstMountState';\nimport { useRef } from 'react';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport type {\n\tIPlayerCommands,\n\tPlayerOptions,\n} from '@/controllers/PlayerController';\n\nexport abstract class PlayerControllerImpl<\n\tTPlayer,\n> implements Partial<IPlayerCommands> {\n\tconstructor(\n\t\tprotected readonly logger: ILogger,\n\t\tprotected readonly player: TPlayer,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.log(LogLevel.Debug, 'ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo?(id: string): Promise<void>;\n\tabstract play?(): Promise<void>;\n\tabstract pause?(): Promise<void>;\n\tabstract setCurrentTime?(seconds: number): Promise<void>;\n\tabstract setVolume?(volume: number): Promise<void>;\n\tabstract setMuted?(muted: boolean): Promise<void>;\n\tabstract setPlaybackRate?(playbackRate: number): Promise<void>;\n\tabstract getDuration?(): Promise<number>;\n\tabstract getCurrentTime?(): Promise<number>;\n\tabstract getVolume?(): Promise<number>;\n\tabstract getMuted?(): Promise<boolean>;\n\tabstract getPlaybackRate?(): Promise<number>;\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\treturn this[command] !== undefined;\n\t}\n}\n","import { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Dailymotion'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Spotify'\n\t| 'Twitch'\n\t| 'Vimeo'\n\t| 'YouTube'\n\t| (string & {});\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number;\n\tpercent: number;\n\tseconds: number;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerCommands {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tsetPlaybackRate(playbackRate: number): Promise<void>;\n\tgetDuration(): Promise<number>;\n\tgetCurrentTime(): Promise<number>;\n\tgetVolume(): Promise<number>;\n\tgetMuted(): Promise<boolean>;\n\tgetPlaybackRate(): Promise<number>;\n}\n\nexport interface IPlayerController extends IPlayerCommands {\n\tsupports(command: keyof IPlayerCommands): boolean;\n}\n\nexport class PlayerController<\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> implements IPlayerController {\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TController;\n\n\tconstructor(\n\t\tprivate readonly logger: ILogger,\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly player: TPlayer,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly controllerFactory: new (\n\t\t\tlogger: ILogger,\n\t\t\tplayer: TPlayer,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TController,\n\t) {\n\t\tthis.id = PlayerController.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Error,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.controllerFactory(\n\t\t\tthis.logger,\n\t\t\tthis.player,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate createPlayerNotAttachedError(): Error {\n\t\tthis.error('player is not attached');\n\n\t\treturn new Error('player is not attached');\n\t}\n\n\tprivate createCommandNotSupportedError(\n\t\tcommand: keyof IPlayerCommands,\n\t): Error {\n\t\treturn new Error(`${command} is not supported`);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tawait this.impl.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.loadVideo === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('loadVideo');\n\t\t}\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tplay(): Promise<void> {\n\t\tthis.debug('play');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.play === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('play');\n\t\t}\n\n\t\treturn this.impl.play();\n\t}\n\n\tpause(): Promise<void> {\n\t\tthis.debug('pause');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.pause === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('pause');\n\t\t}\n\n\t\treturn this.impl.pause();\n\t}\n\n\tsetCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setCurrentTime');\n\t\t}\n\n\t\treturn this.impl.setCurrentTime(seconds);\n\t}\n\n\tsetVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setVolume');\n\t\t}\n\n\t\treturn this.impl.setVolume(volume);\n\t}\n\n\tsetMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setMuted');\n\t\t}\n\n\t\treturn this.impl.setMuted(muted);\n\t}\n\n\tsetPlaybackRate(playbackRate: number): Promise<void> {\n\t\tthis.debug('setPlaybackRate', playbackRate);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.setPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('setPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.setPlaybackRate(playbackRate);\n\t}\n\n\tgetDuration(): Promise<number> {\n\t\tthis.debug('getDuration');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getDuration === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getDuration');\n\t\t}\n\n\t\treturn this.impl.getDuration();\n\t}\n\n\tgetCurrentTime(): Promise<number> {\n\t\tthis.debug('getCurrentTime');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getCurrentTime === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getCurrentTime');\n\t\t}\n\n\t\treturn this.impl.getCurrentTime();\n\t}\n\n\tgetVolume(): Promise<number> {\n\t\tthis.debug('getVolume');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getVolume === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getVolume');\n\t\t}\n\n\t\treturn this.impl.getVolume();\n\t}\n\n\tgetMuted(): Promise<boolean> {\n\t\tthis.debug('getMuted');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getMuted === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getMuted');\n\t\t}\n\n\t\treturn this.impl.getMuted();\n\t}\n\n\tgetPlaybackRate(): Promise<number> {\n\t\tthis.debug('getPlaybackRate');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tif (this.impl.getPlaybackRate === undefined) {\n\t\t\tthrow this.createCommandNotSupportedError('getPlaybackRate');\n\t\t}\n\n\t\treturn this.impl.getPlaybackRate();\n\t}\n\n\tsupports(command: keyof IPlayerCommands): boolean {\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.supports(command);\n\t}\n}\n","import usePreviousDistinct from '@/components/usePreviousDistinct';\nimport { type ILogger, LogLevel } from '@/controllers/Logger';\nimport { nullPlayerController } from '@/controllers/NullPlayerController';\nimport {\n\ttype IPlayerController,\n\tPlayerController,\n\ttype PlayerOptions,\n\ttype PlayerType,\n} from '@/controllers/PlayerController';\nimport { PlayerControllerImpl } from '@/controllers/PlayerControllerImpl';\nimport {\n\ttype MutableRefObject,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\nexport interface PlayerProps {\n\tlogger: ILogger;\n\ttype: PlayerType;\n\tonControllerChange: ((value: IPlayerController) => void) | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerFactory: (element: TElement, videoId: string) => Promise<TPlayer>;\n\tcontrollerFactory: new (\n\t\tlogger: ILogger,\n\t\tplayer: TPlayer,\n\t\toptions: PlayerOptions | undefined,\n\t) => TController;\n\tchildren: (\n\t\telementRef: MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends object,\n\tTController extends PlayerControllerImpl<TPlayer>,\n>({\n\tlogger,\n\ttype,\n\tloadScript,\n\tplayerFactory,\n\tonControllerChange,\n\tvideoId,\n\toptions,\n\tcontrollerFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer, TController>): ReactElement<\n\tPlayerContainerProps<TElement, TPlayer, TController>\n> => {\n\tlogger.log(LogLevel.Debug, 'PlayerContainer');\n\n\tconst videoIdRef = useRef(videoId);\n\n\tconst elementRef = useRef<TElement>(undefined!);\n\n\tconst [player, setPlayer] = useState<TPlayer>();\n\n\tconst [controller, _setController] =\n\t\tuseState<IPlayerController>(nullPlayerController);\n\n\tconst setController = useCallback(\n\t\t(value: IPlayerController): void => {\n\t\t\t_setController(value);\n\n\t\t\tonControllerChange?.(value);\n\t\t},\n\t\t[onControllerChange],\n\t);\n\n\tuseEffect(() => {\n\t\tvoid (loadScript?.() ?? Promise.resolve())\n\t\t\t.then(() => playerFactory(elementRef.current, videoIdRef.current))\n\t\t\t.then((player) => setPlayer(player));\n\t}, [loadScript, playerFactory]);\n\n\t// Make sure that `options` do not change between re-rendering.\n\tuseEffect(() => {\n\t\tif (player === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst controller = new PlayerController(\n\t\t\tlogger,\n\t\t\ttype,\n\t\t\tplayer,\n\t\t\toptions,\n\t\t\tcontrollerFactory,\n\t\t);\n\n\t\tvoid controller\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setController(controller));\n\n\t\treturn (): void => {\n\t\t\tvoid controller\n\t\t\t\t.detach()\n\t\t\t\t.finally(() => setController(nullPlayerController));\n\t\t};\n\t}, [\n\t\tlogger,\n\t\ttype,\n\t\tloadScript,\n\t\tplayer,\n\t\toptions,\n\t\tcontrollerFactory,\n\t\tsetController,\n\t]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tuseEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer` and `SpotifyPlayer`).\n\t\tif (previousVideoId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid controller.loadVideo(videoId);\n\t}, [previousVideoId, videoId, controller]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(elementRef, videoIdRef.current)}</>;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./PlayerContainer-COjwHOhq.cjs`),t=require(`./index.cjs.js`),n=require(`./ensureScriptLoaded-BoubPl5C.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);var a,o=(0,r.memo)(({...o})=>{let{logger:s}=o;s.log(e.a.Debug,`SpotifyPlayer`);let c=(0,r.useCallback)(()=>new Promise(async(t,r)=>{await n.t(`https://open.spotify.com/embed/iframe-api/v1`,s)?window.onSpotifyIframeApiReady=n=>{a=n,s.log(e.a.Debug,`Spotify iframe API ready`),t()}:t()}),[s]),l=(0,r.useCallback)((e,t)=>new Promise(n=>{a.createController(e,{uri:t,width:`100%`,height:`100%`},e=>n(e))}),[]);return(0,i.jsx)(e.t,{...o,loadScript:c,playerFactory:l,controllerFactory:t.SpotifyPlayerController,children:e=>(0,i.jsx)(`div`,{style:{width:`100%`,height:`100%`},children:(0,i.jsx)(`div`,{ref:e})})})});exports.default=o;
|
|
2
|
+
//# sourceMappingURL=SpotifyPlayer-DUKJP7Jz.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpotifyPlayer-DUKJP7Jz.cjs","names":[],"sources":["../src/components/SpotifyPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { SpotifyPlayerController } from '@/controllers/SpotifyPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\n// The Spotify iframe API hands the `IFrameAPI` object to a global callback\n// rather than exposing it on a namespace, so stash it for `playerFactory`.\nlet iFrameAPI: Spotify.IFrameAPI | undefined;\n\nconst SpotifyPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'SpotifyPlayer');\n\n\tconst loadScript = useCallback((): Promise<void> => {\n\t\treturn new Promise(async (resolve, _reject) => {\n\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t'https://open.spotify.com/embed/iframe-api/v1',\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tif (first) {\n\t\t\t\twindow.onSpotifyIframeApiReady = (api): void => {\n\t\t\t\t\tiFrameAPI = api;\n\t\t\t\t\tlogger.log(LogLevel.Debug, 'Spotify iframe API ready');\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(\n\t\t\telement: HTMLDivElement,\n\t\t\tvideoId: string,\n\t\t): Promise<Spotify.EmbedController> => {\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\tiFrameAPI!.createController(\n\t\t\t\t\telement,\n\t\t\t\t\t{ uri: videoId, width: '100%', height: '100%' },\n\t\t\t\t\t(controller) => resolve(controller),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={SpotifyPlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t// Spotify replaces the host element with its iframe, so keep a\n\t\t\t\t// React-owned wrapper around it (as `YouTubePlayer` does).\n\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t<div ref={elementRef} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default SpotifyPlayer;\n"],"mappings":"mLAWA,IAAI,EAEE,GAAA,EAAA,EAAA,OAAsB,CAAE,GAAG,KAAuC,CACvE,GAAM,CAAE,UAAW,EAEnB,EAAO,IAAI,EAAA,EAAS,MAAO,eAAe,EAE1C,IAAM,GAAA,EAAA,EAAA,iBACE,IAAI,QAAQ,MAAO,EAAS,IAAY,CAM1C,MALgB,EAAA,EACnB,+CACA,CACD,EAGC,OAAO,wBAA2B,GAAc,CAC/C,EAAY,EACZ,EAAO,IAAI,EAAA,EAAS,MAAO,0BAA0B,EACrD,EAAQ,CACT,EAEA,EAAQ,CAEV,CAAC,EACC,CAAC,CAAM,CAAC,EAEL,GAAA,EAAA,EAAA,cAEJ,EACA,IAEO,IAAI,QAAS,GAAY,CAC/B,EAAW,iBACV,EACA,CAAE,IAAK,EAAS,MAAO,OAAQ,OAAQ,MAAO,EAC7C,GAAe,EAAQ,CAAU,CACnC,CACD,CAAC,EAEF,CAAC,CACF,EAEA,OACC,EAAA,EAAA,KAAC,EAAA,EAAD,CACC,GAAI,EACQ,aACG,gBACf,kBAAmB,EAAA,iCAEjB,IAGD,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,YAC3C,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,CAAa,CAAA,CACnB,CAAA,CAEU,CAAA,CAEnB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { a as e, t } from "./PlayerContainer-VQ3YPGU_.js";
|
|
2
|
+
import { SpotifyPlayerController as n } from "./index.es.js";
|
|
3
|
+
import { t as r } from "./ensureScriptLoaded-CwERrTru.js";
|
|
4
|
+
import { memo as i, useCallback as a } from "react";
|
|
5
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/SpotifyPlayer.tsx
|
|
7
|
+
var s, c = i(({ ...i }) => {
|
|
8
|
+
let { logger: c } = i;
|
|
9
|
+
c.log(e.Debug, "SpotifyPlayer");
|
|
10
|
+
let l = a(() => new Promise(async (t, n) => {
|
|
11
|
+
await r("https://open.spotify.com/embed/iframe-api/v1", c) ? window.onSpotifyIframeApiReady = (n) => {
|
|
12
|
+
s = n, c.log(e.Debug, "Spotify iframe API ready"), t();
|
|
13
|
+
} : t();
|
|
14
|
+
}), [c]), u = a((e, t) => new Promise((n) => {
|
|
15
|
+
s.createController(e, {
|
|
16
|
+
uri: t,
|
|
17
|
+
width: "100%",
|
|
18
|
+
height: "100%"
|
|
19
|
+
}, (e) => n(e));
|
|
20
|
+
}), []);
|
|
21
|
+
return /* @__PURE__ */ o(t, {
|
|
22
|
+
...i,
|
|
23
|
+
loadScript: l,
|
|
24
|
+
playerFactory: u,
|
|
25
|
+
controllerFactory: n,
|
|
26
|
+
children: (e) => /* @__PURE__ */ o("div", {
|
|
27
|
+
style: {
|
|
28
|
+
width: "100%",
|
|
29
|
+
height: "100%"
|
|
30
|
+
},
|
|
31
|
+
children: /* @__PURE__ */ o("div", { ref: e })
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//#endregion
|
|
36
|
+
export { c as default };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=SpotifyPlayer-DbZNyvp-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpotifyPlayer-DbZNyvp-.js","names":[],"sources":["../src/components/SpotifyPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { SpotifyPlayerController } from '@/controllers/SpotifyPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\n// The Spotify iframe API hands the `IFrameAPI` object to a global callback\n// rather than exposing it on a namespace, so stash it for `playerFactory`.\nlet iFrameAPI: Spotify.IFrameAPI | undefined;\n\nconst SpotifyPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'SpotifyPlayer');\n\n\tconst loadScript = useCallback((): Promise<void> => {\n\t\treturn new Promise(async (resolve, _reject) => {\n\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t'https://open.spotify.com/embed/iframe-api/v1',\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tif (first) {\n\t\t\t\twindow.onSpotifyIframeApiReady = (api): void => {\n\t\t\t\t\tiFrameAPI = api;\n\t\t\t\t\tlogger.log(LogLevel.Debug, 'Spotify iframe API ready');\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(\n\t\t\telement: HTMLDivElement,\n\t\t\tvideoId: string,\n\t\t): Promise<Spotify.EmbedController> => {\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\tiFrameAPI!.createController(\n\t\t\t\t\telement,\n\t\t\t\t\t{ uri: videoId, width: '100%', height: '100%' },\n\t\t\t\t\t(controller) => resolve(controller),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={SpotifyPlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t// Spotify replaces the host element with its iframe, so keep a\n\t\t\t\t// React-owned wrapper around it (as `YouTubePlayer` does).\n\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t<div ref={elementRef} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default SpotifyPlayer;\n"],"mappings":";;;;;;AAWA,IAAI,GAEE,IAAgB,GAAM,EAAE,GAAG,QAAuC;CACvE,IAAM,EAAE,cAAW;CAEnB,EAAO,IAAI,EAAS,OAAO,eAAe;CAE1C,IAAM,IAAa,QACX,IAAI,QAAQ,OAAO,GAAS,MAAY;EAM9C,AAAI,MALgB,EACnB,gDACA,CACD,IAGC,OAAO,2BAA2B,MAAc;GAG/C,AAFA,IAAY,GACZ,EAAO,IAAI,EAAS,OAAO,0BAA0B,GACrD,EAAQ;EACT,IAEA,EAAQ;CAEV,CAAC,GACC,CAAC,CAAM,CAAC,GAEL,IAAgB,GAEpB,GACA,MAEO,IAAI,SAAS,MAAY;EAC/B,EAAW,iBACV,GACA;GAAE,KAAK;GAAS,OAAO;GAAQ,QAAQ;EAAO,IAC7C,MAAe,EAAQ,CAAU,CACnC;CACD,CAAC,GAEF,CAAC,CACF;CAEA,OACC,kBAAC,GAAD;EACC,GAAI;EACQ;EACG;EACf,mBAAmB;aAEjB,MAGD,kBAAC,OAAD;GAAK,OAAO;IAAE,OAAO;IAAQ,QAAQ;GAAO;aAC3C,kBAAC,OAAD,EAAK,KAAK,EAAa,CAAA;EACnB,CAAA;CAEU,CAAA;AAEnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwitchPlayer-
|
|
1
|
+
{"version":3,"file":"TwitchPlayer-Bn8o_9f5.js","names":[],"sources":["../src/components/TwitchPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { TwitchPlayerController } from '@/controllers/TwitchPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst TwitchPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'TwitchPlayer');\n\n\tconst loadScript = useCallback(async () => {\n\t\tawait ensureScriptLoaded('https://embed.twitch.tv/embed/v1.js', logger);\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\tasync (\n\t\t\telement: HTMLDivElement,\n\t\t\tvideoId: string,\n\t\t): Promise<Twitch.Player> => {\n\t\t\treturn Promise.resolve(\n\t\t\t\tnew Twitch.Player(element, {\n\t\t\t\t\tvideo: videoId,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: '100%',\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={TwitchPlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t<div\n\t\t\t\t\tref={elementRef}\n\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default TwitchPlayer;\n"],"mappings":";;;;;;AASA,IAAM,IAAe,GAAM,EAAE,GAAG,QAAuC;CACtE,IAAM,EAAE,cAAW;CAEnB,EAAO,IAAI,EAAS,OAAO,cAAc;CAEzC,IAAM,IAAa,EAAY,YAAY;EAC1C,MAAM,EAAmB,uCAAuC,CAAM;CACvE,GAAG,CAAC,CAAM,CAAC,GAEL,IAAgB,EACrB,OACC,GACA,MAEO,QAAQ,QACd,IAAI,OAAO,OAAO,GAAS;EAC1B,OAAO;EACP,OAAO;EACP,QAAQ;CACT,CAAC,CACF,GAED,CAAC,CACF;CAEA,OACC,kBAAC,GAAD;EACC,GAAI;EACQ;EACG;EACf,mBAAmB;aAEjB,MACD,kBAAC,OAAD;GACC,KAAK;GACL,OAAO;IAAE,OAAO;IAAQ,QAAQ;GAAO;EACvC,CAAA;CAEc,CAAA;AAEnB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
const e=require(`./PlayerContainer-COjwHOhq.cjs`),t=require(`./index.cjs.js`),n=require(`./ensureScriptLoaded-BoubPl5C.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);var a=(0,r.memo)(({...a})=>{let{logger:o}=a;o.log(e.a.Debug,`TwitchPlayer`);let s=(0,r.useCallback)(async()=>{await n.t(`https://embed.twitch.tv/embed/v1.js`,o)},[o]),c=(0,r.useCallback)(async(e,t)=>Promise.resolve(new Twitch.Player(e,{video:t,width:`100%`,height:`100%`})),[]);return(0,i.jsx)(e.t,{...a,loadScript:s,playerFactory:c,controllerFactory:t.TwitchPlayerController,children:e=>(0,i.jsx)(`div`,{ref:e,style:{width:`100%`,height:`100%`}})})});exports.default=a;
|
|
2
|
-
//# sourceMappingURL=TwitchPlayer-
|
|
2
|
+
//# sourceMappingURL=TwitchPlayer-SK7o8pMq.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwitchPlayer-
|
|
1
|
+
{"version":3,"file":"TwitchPlayer-SK7o8pMq.cjs","names":[],"sources":["../src/components/TwitchPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { TwitchPlayerController } from '@/controllers/TwitchPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst TwitchPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'TwitchPlayer');\n\n\tconst loadScript = useCallback(async () => {\n\t\tawait ensureScriptLoaded('https://embed.twitch.tv/embed/v1.js', logger);\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\tasync (\n\t\t\telement: HTMLDivElement,\n\t\t\tvideoId: string,\n\t\t): Promise<Twitch.Player> => {\n\t\t\treturn Promise.resolve(\n\t\t\t\tnew Twitch.Player(element, {\n\t\t\t\t\tvideo: videoId,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: '100%',\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={TwitchPlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t<div\n\t\t\t\t\tref={elementRef}\n\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default TwitchPlayer;\n"],"mappings":"mLASA,IAAM,GAAA,EAAA,EAAA,OAAqB,CAAE,GAAG,KAAuC,CACtE,GAAM,CAAE,UAAW,EAEnB,EAAO,IAAI,EAAA,EAAS,MAAO,cAAc,EAEzC,IAAM,GAAA,EAAA,EAAA,aAAyB,SAAY,CAC1C,MAAM,EAAA,EAAmB,sCAAuC,CAAM,CACvE,EAAG,CAAC,CAAM,CAAC,EAEL,GAAA,EAAA,EAAA,aACL,MACC,EACA,IAEO,QAAQ,QACd,IAAI,OAAO,OAAO,EAAS,CAC1B,MAAO,EACP,MAAO,OACP,OAAQ,MACT,CAAC,CACF,EAED,CAAC,CACF,EAEA,OACC,EAAA,EAAA,KAAC,EAAA,EAAD,CACC,GAAI,EACQ,aACG,gBACf,kBAAmB,EAAA,gCAEjB,IACD,EAAA,EAAA,KAAC,MAAD,CACC,IAAK,EACL,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,CACvC,CAAA,CAEc,CAAA,CAEnB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
const e=require(`./PlayerContainer-COjwHOhq.cjs`),t=require(`./index.cjs.js`),n=require(`./ensureScriptLoaded-BoubPl5C.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);var a=(0,r.memo)(({...a})=>{let{logger:o}=a;o.log(e.a.Debug,`VimeoPlayer`);let s=(0,r.useCallback)(async()=>{await n.t(`https://player.vimeo.com/api/player.js`,o)},[o]),c=(0,r.useCallback)(e=>Promise.resolve(new Vimeo.Player(e)),[]);return(0,i.jsx)(e.t,{...a,loadScript:s,playerFactory:c,controllerFactory:t.VimeoPlayerController,children:(e,t)=>(0,i.jsx)(`iframe`,{ref:e,src:`https://player.vimeo.com/video/${t}`,frameBorder:0,allow:`autoplay`,style:{width:`100%`,height:`100%`}})})});exports.default=a;
|
|
2
|
-
//# sourceMappingURL=VimeoPlayer-
|
|
2
|
+
//# sourceMappingURL=VimeoPlayer-BySLiRru.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VimeoPlayer-
|
|
1
|
+
{"version":3,"file":"VimeoPlayer-BySLiRru.cjs","names":[],"sources":["../src/components/VimeoPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { VimeoPlayerController } from '@/controllers/VimeoPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst VimeoPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'VimeoPlayer');\n\n\tconst loadScript = useCallback(async () => {\n\t\tawait ensureScriptLoaded(\n\t\t\t'https://player.vimeo.com/api/player.js',\n\t\t\tlogger,\n\t\t);\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(element: HTMLIFrameElement): Promise<Vimeo.Player> => {\n\t\t\treturn Promise.resolve(new Vimeo.Player(element));\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={VimeoPlayerController}\n\t\t>\n\t\t\t{(elementRef, videoId): ReactElement => (\n\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t<iframe\n\t\t\t\t\tref={elementRef}\n\t\t\t\t\tsrc={`https://player.vimeo.com/video/${videoId}`}\n\t\t\t\t\tframeBorder={0}\n\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default VimeoPlayer;\n"],"mappings":"mLASA,IAAM,GAAA,EAAA,EAAA,OAAoB,CAAE,GAAG,KAAuC,CACrE,GAAM,CAAE,UAAW,EAEnB,EAAO,IAAI,EAAA,EAAS,MAAO,aAAa,EAExC,IAAM,GAAA,EAAA,EAAA,aAAyB,SAAY,CAC1C,MAAM,EAAA,EACL,yCACA,CACD,CACD,EAAG,CAAC,CAAM,CAAC,EAEL,GAAA,EAAA,EAAA,aACJ,GACO,QAAQ,QAAQ,IAAI,MAAM,OAAO,CAAO,CAAC,EAEjD,CAAC,CACF,EAEA,OACC,EAAA,EAAA,KAAC,EAAA,EAAD,CACC,GAAI,EACQ,aACG,gBACf,kBAAmB,EAAA,gCAEjB,EAAY,KAEb,EAAA,EAAA,KAAC,SAAD,CACC,IAAK,EACL,IAAK,kCAAkC,IACvC,YAAa,EACb,MAAM,WACN,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,CACvC,CAAA,CAEc,CAAA,CAEnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VimeoPlayer-
|
|
1
|
+
{"version":3,"file":"VimeoPlayer-Cz5hB9JG.js","names":[],"sources":["../src/components/VimeoPlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { VimeoPlayerController } from '@/controllers/VimeoPlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst VimeoPlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'VimeoPlayer');\n\n\tconst loadScript = useCallback(async () => {\n\t\tawait ensureScriptLoaded(\n\t\t\t'https://player.vimeo.com/api/player.js',\n\t\t\tlogger,\n\t\t);\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(element: HTMLIFrameElement): Promise<Vimeo.Player> => {\n\t\t\treturn Promise.resolve(new Vimeo.Player(element));\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={VimeoPlayerController}\n\t\t>\n\t\t\t{(elementRef, videoId): ReactElement => (\n\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t<iframe\n\t\t\t\t\tref={elementRef}\n\t\t\t\t\tsrc={`https://player.vimeo.com/video/${videoId}`}\n\t\t\t\t\tframeBorder={0}\n\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default VimeoPlayer;\n"],"mappings":";;;;;;AASA,IAAM,IAAc,GAAM,EAAE,GAAG,QAAuC;CACrE,IAAM,EAAE,cAAW;CAEnB,EAAO,IAAI,EAAS,OAAO,aAAa;CAExC,IAAM,IAAa,EAAY,YAAY;EAC1C,MAAM,EACL,0CACA,CACD;CACD,GAAG,CAAC,CAAM,CAAC,GAEL,IAAgB,GACpB,MACO,QAAQ,QAAQ,IAAI,MAAM,OAAO,CAAO,CAAC,GAEjD,CAAC,CACF;CAEA,OACC,kBAAC,GAAD;EACC,GAAI;EACQ;EACG;EACf,mBAAmB;aAEjB,GAAY,MAEb,kBAAC,UAAD;GACC,KAAK;GACL,KAAK,kCAAkC;GACvC,aAAa;GACb,OAAM;GACN,OAAO;IAAE,OAAO;IAAQ,QAAQ;GAAO;EACvC,CAAA;CAEc,CAAA;AAEnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YouTubePlayer-
|
|
1
|
+
{"version":3,"file":"YouTubePlayer-C_fmW0IS.js","names":[],"sources":["../src/components/YouTubePlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { YouTubePlayerController } from '@/controllers/YouTubePlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst origin = 'https://www.youtube-nocookie.com';\n\nconst YouTubePlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'YouTubePlayer');\n\n\tconst loadScript = useCallback((): Promise<void> => {\n\t\treturn new Promise(async (resolve, _reject) => {\n\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t'https://www.youtube.com/iframe_api',\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tif (first) {\n\t\t\t\t// https://stackoverflow.com/a/18154942.\n\t\t\t\twindow.onYouTubeIframeAPIReady = (): void => {\n\t\t\t\t\tlogger.log(LogLevel.Debug, 'YouTube iframe API ready');\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(element: HTMLDivElement): Promise<YT.Player> => {\n\t\t\treturn Promise.resolve(\n\t\t\t\tnew YT.Player(element, {\n\t\t\t\t\thost: origin,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: '100%',\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={YouTubePlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t<div ref={elementRef} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default YouTubePlayer;\n"],"mappings":";;;;;;AASA,IAAM,IAAS,oCAET,IAAgB,GAAM,EAAE,GAAG,QAAuC;CACvE,IAAM,EAAE,cAAW;CAEnB,EAAO,IAAI,EAAS,OAAO,eAAe;CAE1C,IAAM,IAAa,QACX,IAAI,QAAQ,OAAO,GAAS,MAAY;EAM9C,AAAI,MALgB,EACnB,sCACA,CACD,IAIC,OAAO,gCAAsC;GAE5C,AADA,EAAO,IAAI,EAAS,OAAO,0BAA0B,GACrD,EAAQ;EACT,IAEA,EAAQ;CAEV,CAAC,GACC,CAAC,CAAM,CAAC,GAEL,IAAgB,GACpB,MACO,QAAQ,QACd,IAAI,GAAG,OAAO,GAAS;EACtB,MAAM;EACN,OAAO;EACP,QAAQ;CACT,CAAC,CACF,GAED,CAAC,CACF;CAEA,OACC,kBAAC,GAAD;EACC,GAAI;EACQ;EACG;EACf,mBAAmB;aAEjB,MACD,kBAAC,OAAD;GAAK,OAAO;IAAE,OAAO;IAAQ,QAAQ;GAAO;aAC3C,kBAAC,OAAD,EAAK,KAAK,EAAa,CAAA;EACnB,CAAA;CAEU,CAAA;AAEnB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
const e=require(`./PlayerContainer-COjwHOhq.cjs`),t=require(`./index.cjs.js`),n=require(`./ensureScriptLoaded-BoubPl5C.cjs`);let r=require(`react`),i=require(`react/jsx-runtime`);var a=`https://www.youtube-nocookie.com`,o=(0,r.memo)(({...o})=>{let{logger:s}=o;s.log(e.a.Debug,`YouTubePlayer`);let c=(0,r.useCallback)(()=>new Promise(async(t,r)=>{await n.t(`https://www.youtube.com/iframe_api`,s)?window.onYouTubeIframeAPIReady=()=>{s.log(e.a.Debug,`YouTube iframe API ready`),t()}:t()}),[s]),l=(0,r.useCallback)(e=>Promise.resolve(new YT.Player(e,{host:a,width:`100%`,height:`100%`})),[]);return(0,i.jsx)(e.t,{...o,loadScript:c,playerFactory:l,controllerFactory:t.YouTubePlayerController,children:e=>(0,i.jsx)(`div`,{style:{width:`100%`,height:`100%`},children:(0,i.jsx)(`div`,{ref:e})})})});exports.default=o;
|
|
2
|
-
//# sourceMappingURL=YouTubePlayer-
|
|
2
|
+
//# sourceMappingURL=YouTubePlayer-vLFVWfOz.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YouTubePlayer-
|
|
1
|
+
{"version":3,"file":"YouTubePlayer-vLFVWfOz.cjs","names":[],"sources":["../src/components/YouTubePlayer.tsx"],"sourcesContent":["import {\n\tPlayerContainer,\n\ttype PlayerProps,\n} from '@/components/PlayerContainer';\nimport { LogLevel } from '@/controllers/Logger';\nimport { YouTubePlayerController } from '@/controllers/YouTubePlayerController';\nimport { ensureScriptLoaded } from '@/controllers/ensureScriptLoaded';\nimport { type ReactElement, memo, useCallback } from 'react';\n\nconst origin = 'https://www.youtube-nocookie.com';\n\nconst YouTubePlayer = memo(({ ...props }: PlayerProps): ReactElement => {\n\tconst { logger } = props;\n\n\tlogger.log(LogLevel.Debug, 'YouTubePlayer');\n\n\tconst loadScript = useCallback((): Promise<void> => {\n\t\treturn new Promise(async (resolve, _reject) => {\n\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t'https://www.youtube.com/iframe_api',\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tif (first) {\n\t\t\t\t// https://stackoverflow.com/a/18154942.\n\t\t\t\twindow.onYouTubeIframeAPIReady = (): void => {\n\t\t\t\t\tlogger.log(LogLevel.Debug, 'YouTube iframe API ready');\n\t\t\t\t\tresolve();\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t}, [logger]);\n\n\tconst playerFactory = useCallback(\n\t\t(element: HTMLDivElement): Promise<YT.Player> => {\n\t\t\treturn Promise.resolve(\n\t\t\t\tnew YT.Player(element, {\n\t\t\t\t\thost: origin,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: '100%',\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\t[],\n\t);\n\n\treturn (\n\t\t<PlayerContainer\n\t\t\t{...props}\n\t\t\tloadScript={loadScript}\n\t\t\tplayerFactory={playerFactory}\n\t\t\tcontrollerFactory={YouTubePlayerController}\n\t\t>\n\t\t\t{(elementRef): ReactElement => (\n\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t<div ref={elementRef} />\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</PlayerContainer>\n\t);\n});\n\nexport default YouTubePlayer;\n"],"mappings":"mLASA,IAAM,EAAS,mCAET,GAAA,EAAA,EAAA,OAAsB,CAAE,GAAG,KAAuC,CACvE,GAAM,CAAE,UAAW,EAEnB,EAAO,IAAI,EAAA,EAAS,MAAO,eAAe,EAE1C,IAAM,GAAA,EAAA,EAAA,iBACE,IAAI,QAAQ,MAAO,EAAS,IAAY,CAM1C,MALgB,EAAA,EACnB,qCACA,CACD,EAIC,OAAO,4BAAsC,CAC5C,EAAO,IAAI,EAAA,EAAS,MAAO,0BAA0B,EACrD,EAAQ,CACT,EAEA,EAAQ,CAEV,CAAC,EACC,CAAC,CAAM,CAAC,EAEL,GAAA,EAAA,EAAA,aACJ,GACO,QAAQ,QACd,IAAI,GAAG,OAAO,EAAS,CACtB,KAAM,EACN,MAAO,OACP,OAAQ,MACT,CAAC,CACF,EAED,CAAC,CACF,EAEA,OACC,EAAA,EAAA,KAAC,EAAA,EAAD,CACC,GAAI,EACQ,aACG,gBACf,kBAAmB,EAAA,iCAEjB,IACD,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,YAC3C,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,CAAa,CAAA,CACnB,CAAA,CAEU,CAAA,CAEnB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ILogger } from './Logger';
|
|
2
2
|
import { PlayerControllerImpl } from './PlayerControllerImpl';
|
|
3
|
-
export type PlayerType = 'Audio' | 'Dailymotion' | 'Niconico' | 'SoundCloud' | 'Twitch' | 'Vimeo' | 'YouTube' | (string & {});
|
|
3
|
+
export type PlayerType = 'Audio' | 'Dailymotion' | 'Niconico' | 'SoundCloud' | 'Spotify' | 'Twitch' | 'Vimeo' | 'YouTube' | (string & {});
|
|
4
4
|
export interface LoadedEvent {
|
|
5
5
|
id: string;
|
|
6
6
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PlayerControllerImpl } from './PlayerControllerImpl';
|
|
2
|
+
export declare class SpotifyPlayerController extends PlayerControllerImpl<Spotify.EmbedController> {
|
|
3
|
+
private duration;
|
|
4
|
+
private position;
|
|
5
|
+
private previousIsPaused;
|
|
6
|
+
private currentUri;
|
|
7
|
+
private ended;
|
|
8
|
+
private handlePlaybackUpdate;
|
|
9
|
+
attach(id: string): Promise<void>;
|
|
10
|
+
detach(): Promise<void>;
|
|
11
|
+
loadVideo(id: string): Promise<void>;
|
|
12
|
+
play(): Promise<void>;
|
|
13
|
+
pause(): Promise<void>;
|
|
14
|
+
setCurrentTime(seconds: number): Promise<void>;
|
|
15
|
+
setVolume: undefined;
|
|
16
|
+
setMuted: undefined;
|
|
17
|
+
setPlaybackRate: undefined;
|
|
18
|
+
getDuration(): Promise<number>;
|
|
19
|
+
getCurrentTime(): Promise<number>;
|
|
20
|
+
getVolume: undefined;
|
|
21
|
+
getMuted: undefined;
|
|
22
|
+
getPlaybackRate: undefined;
|
|
23
|
+
}
|
|
@@ -6,6 +6,7 @@ export * from './NullPlayerController';
|
|
|
6
6
|
export * from './PlayerController';
|
|
7
7
|
export * from './PlayerControllerImpl';
|
|
8
8
|
export * from './SoundCloudPlayerController';
|
|
9
|
+
export * from './SpotifyPlayerController';
|
|
9
10
|
export * from './TwitchPlayerController';
|
|
10
11
|
export * from './VimeoPlayerController';
|
|
11
12
|
export * from './YouTubePlayerController';
|