6 changed files with 137 additions and 119 deletions
@ -1,26 +1,27 @@ |
|||||||
import { useCallback, useContext } from "react"; |
// import { useCallback, useContext } from "react";
|
||||||
import { |
// import {
|
||||||
VideoPlayerContext, |
// VideoPlayerContext,
|
||||||
VideoPlayerDispatchContext, |
// VideoPlayerDispatchContext,
|
||||||
} from "../VideoContext"; |
// } from "../VideoContext";
|
||||||
|
|
||||||
export function FullscreenControl() { |
export function FullscreenControl() { |
||||||
const dispatch = useContext(VideoPlayerDispatchContext); |
return <p>Hello world</p>; |
||||||
const video = useContext(VideoPlayerContext); |
// const dispatch = useContext(VideoPlayerDispatchContext);
|
||||||
|
// const video = useContext(VideoPlayerContext);
|
||||||
|
|
||||||
const handleClick = useCallback(() => { |
// const handleClick = useCallback(() => {
|
||||||
dispatch({ |
// dispatch({
|
||||||
type: "FULLSCREEN", |
// type: "FULLSCREEN",
|
||||||
do: video.fullscreen ? "EXIT" : "ENTER", |
// do: video.fullscreen ? "EXIT" : "ENTER",
|
||||||
}); |
// });
|
||||||
}, [video, dispatch]); |
// }, [video, dispatch]);
|
||||||
|
|
||||||
let text = "not fullscreen"; |
// let text = "not fullscreen";
|
||||||
if (video.fullscreen) text = "in fullscreen"; |
// if (video.fullscreen) text = "in fullscreen";
|
||||||
|
|
||||||
return ( |
// return (
|
||||||
<button type="button" onClick={handleClick}> |
// <button type="button" onClick={handleClick}>
|
||||||
{text} |
// {text}
|
||||||
</button> |
// </button>
|
||||||
); |
// );
|
||||||
} |
} |
||||||
|
@ -0,0 +1,20 @@ |
|||||||
|
export interface PlayerControls { |
||||||
|
play(): void; |
||||||
|
pause(): void; |
||||||
|
} |
||||||
|
|
||||||
|
export const initialControls: PlayerControls = { |
||||||
|
play: () => null, |
||||||
|
pause: () => null, |
||||||
|
}; |
||||||
|
|
||||||
|
export function populateControls(player: HTMLVideoElement): PlayerControls { |
||||||
|
return { |
||||||
|
play() { |
||||||
|
player.play(); |
||||||
|
}, |
||||||
|
pause() { |
||||||
|
player.pause(); |
||||||
|
}, |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
import React, { MutableRefObject, useEffect, useState } from "react"; |
||||||
|
import { |
||||||
|
initialControls, |
||||||
|
PlayerControls, |
||||||
|
populateControls, |
||||||
|
} from "./controlVideo"; |
||||||
|
|
||||||
|
export type PlayerState = { |
||||||
|
isPlaying: boolean; |
||||||
|
isPaused: boolean; |
||||||
|
} & PlayerControls; |
||||||
|
|
||||||
|
export const initialPlayerState = { |
||||||
|
isPlaying: false, |
||||||
|
isPaused: true, |
||||||
|
...initialControls, |
||||||
|
}; |
||||||
|
|
||||||
|
type SetPlayer = (s: React.SetStateAction<PlayerState>) => void; |
||||||
|
|
||||||
|
function readState(player: HTMLVideoElement, update: SetPlayer) { |
||||||
|
const state = { |
||||||
|
...initialPlayerState, |
||||||
|
}; |
||||||
|
state.isPaused = player.paused; |
||||||
|
state.isPlaying = !player.paused; |
||||||
|
|
||||||
|
update(state); |
||||||
|
} |
||||||
|
|
||||||
|
function registerListeners(player: HTMLVideoElement, update: SetPlayer) { |
||||||
|
player.addEventListener("pause", () => { |
||||||
|
update((s) => ({ ...s, isPaused: true, isPlaying: false })); |
||||||
|
}); |
||||||
|
player.addEventListener("play", () => { |
||||||
|
update((s) => ({ ...s, isPaused: false, isPlaying: true })); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export function useVideoPlayer(ref: MutableRefObject<HTMLVideoElement | null>) { |
||||||
|
const [state, setState] = useState(initialPlayerState); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const player = ref.current; |
||||||
|
if (player) { |
||||||
|
readState(player, setState); |
||||||
|
registerListeners(player, setState); |
||||||
|
setState((s) => ({ ...s, ...populateControls(player) })); |
||||||
|
} |
||||||
|
}, [ref]); |
||||||
|
|
||||||
|
return { |
||||||
|
playerState: state, |
||||||
|
}; |
||||||
|
} |
Loading…
Reference in new issue