movie-web/src/components/video/VideoContext.tsx
2023-01-08 15:37:16 +01:00

86 lines
1.9 KiB
TypeScript

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<VideoPlayerContextType>(initial);
export const VideoPlayerDispatchContext = createContext<
React.Dispatch<VideoPlayerContextAction>
>(null as any);
export function VideoPlayerContextProvider(props: {
children: React.ReactNode;
player: MutableRefObject<HTMLVideoElement | null>;
}) {
const { playerState } = useVideoPlayer(props.player);
const [videoData, dispatch] = useReducer<typeof videoPlayerContextReducer>(
videoPlayerContextReducer,
initial
);
useEffect(() => {
dispatch({
type: "UPDATE_PLAYER",
state: playerState,
});
}, [playerState]);
return (
<VideoPlayerContext.Provider value={videoData}>
<VideoPlayerDispatchContext.Provider value={dispatch}>
{props.children}
</VideoPlayerDispatchContext.Provider>
</VideoPlayerContext.Provider>
);
}
export function useVideoPlayerState() {
const { state } = useContext(VideoPlayerContext);
return {
videoState: state,
};
}