diff --git a/src/components/gameboy.tsx b/src/components/gameboy.tsx index e19977730..2edb52065 100644 --- a/src/components/gameboy.tsx +++ b/src/components/gameboy.tsx @@ -3,9 +3,11 @@ import { WasmBoy } from '@soapbox.pub/wasmboy'; import clsx from 'clsx'; import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { exitFullscreen, isFullscreen, requestFullscreen } from 'soapbox/features/ui/util/fullscreen'; + import { IconButton } from './ui'; -interface IGameboy extends Pick, 'onFocus' | 'onBlur'> { +interface IGameboy extends Pick, 'onFocus' | 'onBlur'> { /** Classname of the outer `
`. */ className?: string; /** URL to the ROM. */ @@ -16,10 +18,12 @@ interface IGameboy extends Pick, ' /** Component to display a playable Gameboy emulator. */ const Gameboy: React.FC = ({ className, src, aspect = 'normal', onFocus, onBlur, ...rest }) => { + const node = useRef(null); const canvas = useRef(null); const [paused, setPaused] = useState(false); const [muted, setMuted] = useState(true); + const [fullscreen, setFullscreen] = useState(false); async function init() { await WasmBoy.config(WasmBoyOptions, canvas.current!); @@ -33,14 +37,18 @@ const Gameboy: React.FC = ({ className, src, aspect = 'normal', onFocu } } - const handleFocus: React.FocusEventHandler = useCallback(() => { + const handleFocus: React.FocusEventHandler = useCallback(() => { WasmBoy.enableDefaultJoypad(); }, []); - const handleBlur: React.FocusEventHandler = useCallback(() => { + const handleBlur: React.FocusEventHandler = useCallback(() => { WasmBoy.disableDefaultJoypad(); }, []); + const handleFullscreenChange = useCallback(() => { + setFullscreen(isFullscreen()); + }, []); + const pause = async () => { await WasmBoy.pause(); setPaused(true); @@ -58,6 +66,14 @@ const Gameboy: React.FC = ({ className, src, aspect = 'normal', onFocu setMuted(false); }; + const toggleFullscreen = () => { + if (isFullscreen()) { + exitFullscreen(); + } else if (node.current) { + requestFullscreen(node.current); + } + }; + useEffect(() => { init(); @@ -67,17 +83,27 @@ const Gameboy: React.FC = ({ className, src, aspect = 'normal', onFocu }; }, []); + useEffect(() => { + document.addEventListener('fullscreenchange', handleFullscreenChange, true); + return () => { + document.removeEventListener('fullscreenchange', handleFullscreenChange, true); + }; + }, []); + return ( -
+
@@ -92,6 +118,11 @@ const Gameboy: React.FC = ({ className, src, aspect = 'normal', onFocu onClick={unmute} src={muted ? require('@tabler/icons/volume-3.svg') : require('@tabler/icons/volume.svg')} /> +
);