6 changed files with 137 additions and 119 deletions
@ -1,26 +1,27 @@
@@ -1,26 +1,27 @@
|
||||
import { useCallback, useContext } from "react"; |
||||
import { |
||||
VideoPlayerContext, |
||||
VideoPlayerDispatchContext, |
||||
} from "../VideoContext"; |
||||
// import { useCallback, useContext } from "react";
|
||||
// import {
|
||||
// VideoPlayerContext,
|
||||
// VideoPlayerDispatchContext,
|
||||
// } from "../VideoContext";
|
||||
|
||||
export function FullscreenControl() { |
||||
const dispatch = useContext(VideoPlayerDispatchContext); |
||||
const video = useContext(VideoPlayerContext); |
||||
return <p>Hello world</p>; |
||||
// const dispatch = useContext(VideoPlayerDispatchContext);
|
||||
// const video = useContext(VideoPlayerContext);
|
||||
|
||||
const handleClick = useCallback(() => { |
||||
dispatch({ |
||||
type: "FULLSCREEN", |
||||
do: video.fullscreen ? "EXIT" : "ENTER", |
||||
}); |
||||
}, [video, dispatch]); |
||||
// const handleClick = useCallback(() => {
|
||||
// dispatch({
|
||||
// type: "FULLSCREEN",
|
||||
// do: video.fullscreen ? "EXIT" : "ENTER",
|
||||
// });
|
||||
// }, [video, dispatch]);
|
||||
|
||||
let text = "not fullscreen"; |
||||
if (video.fullscreen) text = "in fullscreen"; |
||||
// let text = "not fullscreen";
|
||||
// if (video.fullscreen) text = "in fullscreen";
|
||||
|
||||
return ( |
||||
<button type="button" onClick={handleClick}> |
||||
{text} |
||||
</button> |
||||
); |
||||
// return (
|
||||
// <button type="button" onClick={handleClick}>
|
||||
// {text}
|
||||
// </button>
|
||||
// );
|
||||
} |
||||
|
@ -0,0 +1,20 @@
@@ -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 @@
@@ -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