import React, { createContext, MutableRefObject, useContext, useEffect, useReducer, } from "react"; import { initialPlayerState, PlayerState, useVideoPlayer, } from "./hooks/useVideoPlayer"; interface VideoPlayerContextType { source: string | null; state: PlayerState; } const initial: VideoPlayerContextType = { source: null, state: initialPlayerState, }; type VideoPlayerContextAction = | { type: "SET_SOURCE"; url: string } | { type: "UPDATE_PLAYER"; state: PlayerState; }; function videoPlayerContextReducer( original: VideoPlayerContextType, action: VideoPlayerContextAction ): VideoPlayerContextType { const video = { ...original }; if (action.type === "SET_SOURCE") { video.source = action.url; return video; } if (action.type === "UPDATE_PLAYER") { video.state = action.state; return video; } return original; } export const VideoPlayerContext = createContext(initial); export const VideoPlayerDispatchContext = createContext< React.Dispatch >(null as any); export function VideoPlayerContextProvider(props: { children: React.ReactNode; player: MutableRefObject; }) { const { playerState } = useVideoPlayer(props.player); const [videoData, dispatch] = useReducer( videoPlayerContextReducer, initial ); useEffect(() => { dispatch({ type: "UPDATE_PLAYER", state: playerState, }); }, [playerState]); return ( {props.children} ); } export function useVideoPlayerState() { const { state } = useContext(VideoPlayerContext); return { videoState: state, }; }