movie-web/src/components/video/VideoContext.tsx

86 lines
1.9 KiB
TypeScript
Raw Normal View History

2023-01-08 13:15:32 +01:00
import React, {
createContext,
MutableRefObject,
2023-01-08 15:37:16 +01:00
useContext,
2023-01-08 13:15:32 +01:00
useEffect,
useReducer,
} from "react";
2023-01-08 15:37:16 +01:00
import {
initialPlayerState,
PlayerState,
useVideoPlayer,
} from "./hooks/useVideoPlayer";
2023-01-08 13:15:32 +01:00
interface VideoPlayerContextType {
2023-01-08 15:37:16 +01:00
source: string | null;
state: PlayerState;
2023-01-08 13:15:32 +01:00
}
2023-01-08 15:37:16 +01:00
const initial: VideoPlayerContextType = {
2023-01-08 13:15:32 +01:00
source: null,
2023-01-08 15:37:16 +01:00
state: initialPlayerState,
};
2023-01-08 13:15:32 +01:00
type VideoPlayerContextAction =
| { type: "SET_SOURCE"; url: string }
| {
type: "UPDATE_PLAYER";
2023-01-08 15:37:16 +01:00
state: PlayerState;
2023-01-08 13:15:32 +01:00
};
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") {
2023-01-08 15:37:16 +01:00
video.state = action.state;
2023-01-08 13:15:32 +01:00
return video;
}
return original;
}
2023-01-08 15:37:16 +01:00
export const VideoPlayerContext =
createContext<VideoPlayerContextType>(initial);
2023-01-08 13:15:32 +01:00
export const VideoPlayerDispatchContext = createContext<
React.Dispatch<VideoPlayerContextAction>
>(null as any);
export function VideoPlayerContextProvider(props: {
children: React.ReactNode;
player: MutableRefObject<HTMLVideoElement | null>;
}) {
2023-01-08 15:37:16 +01:00
const { playerState } = useVideoPlayer(props.player);
2023-01-08 13:15:32 +01:00
const [videoData, dispatch] = useReducer<typeof videoPlayerContextReducer>(
videoPlayerContextReducer,
2023-01-08 15:37:16 +01:00
initial
2023-01-08 13:15:32 +01:00
);
useEffect(() => {
dispatch({
type: "UPDATE_PLAYER",
2023-01-08 15:37:16 +01:00
state: playerState,
2023-01-08 13:15:32 +01:00
});
2023-01-08 15:37:16 +01:00
}, [playerState]);
2023-01-08 13:15:32 +01:00
return (
<VideoPlayerContext.Provider value={videoData}>
<VideoPlayerDispatchContext.Provider value={dispatch}>
{props.children}
</VideoPlayerDispatchContext.Provider>
</VideoPlayerContext.Provider>
);
}
2023-01-08 15:37:16 +01:00
export function useVideoPlayerState() {
const { state } = useContext(VideoPlayerContext);
return {
videoState: state,
};
}