diff --git a/js/components/Fullscreen.tsx b/js/components/Fullscreen.tsx index 824f0fe9..8e606128 100644 --- a/js/components/Fullscreen.tsx +++ b/js/components/Fullscreen.tsx @@ -1,5 +1,5 @@ // Adapted from https://github.com/snakesilk/react-fullscreen -import React, { ReactNode } from "react"; +import React, { ReactNode, useRef, useLayoutEffect, useEffect } from "react"; import fscreen from "fscreen"; interface Props { @@ -8,67 +8,51 @@ interface Props { onChange(fullscreen: boolean): void; } -class FullScreen extends React.Component { - node?: HTMLDivElement | null; - - constructor(props: Props) { - super(props); - } - - componentDidMount() { - this.handleProps(this.props); - fscreen.addEventListener("fullscreenchange", this.detectFullScreen); - } - - componentWillUnmount() { - fscreen.removeEventListener("fullscreenchange", this.detectFullScreen); - } - - componentDidUpdate() { - this.handleProps(this.props); - } - - handleProps(props: Props) { - const enabled = fscreen.fullscreenElement === this.node; - if (enabled && !props.enabled) { - this.leaveFullScreen(); - } else if (!enabled && props.enabled) { - this.enterFullScreen(); - } - } - - detectFullScreen = () => { - if (this.props.onChange) { - this.props.onChange(fscreen.fullscreenElement === this.node); - } - }; - - enterFullScreen() { - if (fscreen.fullscreenEnabled && this.node != null) { - fscreen.requestFullscreen(this.node); - } - } - - leaveFullScreen() { - if (fscreen.fullscreenEnabled) { - fscreen.exitFullscreen(); - } - } - - render() { - return ( -
{ - this.node = node; - }} - style={ - this.props.enabled ? { height: "100%", width: "100%" } : undefined - } - > - {this.props.children} -
- ); +function leaveFullScreen() { + if (fscreen.fullscreenEnabled) { + fscreen.exitFullscreen(); } } +function enterFullScreen(node: HTMLDivElement) { + if (fscreen.fullscreenEnabled) { + fscreen.requestFullscreen(node); + } +} + +function FullScreen(props: Props) { + const ref = useRef(null); + + useEffect(() => { + function detectFullScreen() { + if (props.onChange) { + props.onChange(fscreen.fullscreenElement === ref.current); + } + } + fscreen.addEventListener("fullscreenchange", detectFullScreen); + return () => { + fscreen.removeEventListener("fullscreenchange", detectFullScreen); + }; + }, [props.onChange, ref.current]); + + // This must run in response to a click event, so we'll use useLayoutEffect just in case. + useLayoutEffect(() => { + const enabled = fscreen.fullscreenElement === ref.current; + if (enabled && !props.enabled) { + leaveFullScreen(); + } else if (!enabled && props.enabled && ref.current != null) { + enterFullScreen(ref.current); + } + }, [props.enabled, ref.current]); + + return ( +
+ {props.children} +
+ ); +} + export default FullScreen;