Skip to content

Add a fullscreen button for the game div container #2855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
177c86b
Add a fullscreen button for the game div container
Johnwz123 Mar 19, 2024
2031975
Merge branch 'master' into feat/game-fullscreen
sayomaki Mar 20, 2024
0832d8b
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Mar 21, 2024
af140dc
Merge branch 'master' into feat/game-fullscreen
martin-henz Mar 23, 2024
d9e3a2e
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Mar 24, 2024
31fc2c9
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Mar 24, 2024
1a5b3a9
Modify code to use the useFullscreen hook from the @mantine/hooks pac…
Johnwz123 Mar 25, 2024
eef4ae8
Merge branch 'master' of https://github.com/source-academy/frontend i…
Johnwz123 Mar 25, 2024
f9e4c3e
Merge branch 'feat/game-fullscreen' of https://github.com/source-acad…
Johnwz123 Mar 25, 2024
5ffcabe
Merge branch 'master' into feat/game-fullscreen
martin-henz Mar 26, 2024
7ec8ad3
Merge branch 'master' into feat/game-fullscreen
sayomaki Mar 26, 2024
76e09cb
Merge branch 'master' into feat/game-fullscreen
martin-henz Mar 28, 2024
744b8b3
Bump dependencies
RichDom2185 Mar 28, 2024
3c1a46d
Use `IconNames` instead of magic strings
RichDom2185 Mar 28, 2024
4b50bab
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Mar 28, 2024
daac858
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Mar 30, 2024
e41fd96
Merge branch 'master' into feat/game-fullscreen
lhw-1 Apr 1, 2024
a0d28d1
Merge branch 'master' into feat/game-fullscreen
martin-henz Apr 1, 2024
4f4718e
Merge branch 'master' into feat/game-fullscreen
martin-henz Apr 2, 2024
e2b6672
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Apr 6, 2024
9c6b6bf
Merge branch 'master' into feat/game-fullscreen
RichDom2185 Apr 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion src/pages/academy/game/Game.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Icon } from '@blueprintjs/core';
import React from 'react';
import { useDispatch } from 'react-redux';
import { useTypedSelector } from 'src/commons/utils/Hooks';
Expand Down Expand Up @@ -50,9 +51,82 @@ function Game() {
}
}, [session, achievements, goals]);

// Logic for the fullscreen button to toggle fullscreen.
// Entering fullscreen will also lock the screen orientation to landscape.
const [isFullScreen, setIsFullScreen] = React.useState(false);
const toggleFullScreen = () => {
const elem = document.getElementById('game-display') as HTMLElement;

if (!isFullScreen) {
if (elem.requestFullscreen) {
elem.requestFullscreen().then(() => {
if (window.screen.orientation) {
window.screen.orientation.lock('landscape');
}
});
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen().then(() => {
if (window.screen.orientation) {
window.screen.orientation.unlock();
}
});
}
}
setIsFullScreen(!isFullScreen);
};

// Logic for the fullscreen button to dynamically adjust its size, position and padding
// based on the size of the game display.
const [iconSize, setIconSize] = React.useState(0);
const [iconLeft, setIconLeft] = React.useState('0px');
const [iconPadding, setIconPadding] = React.useState('0px');
const gameDisplayRef = React.useRef<HTMLDivElement | null>(null);

React.useEffect(() => {
const handleResize = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't put this function definition inside the useEffect body, coupled with the resize observer below it results in so many unnecessary function objects being recreated, degrading performance.

if (gameDisplayRef.current) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the values never reset otherwise?

const aspectRatio = 16 / 9;
const height = gameDisplayRef.current.offsetHeight;
const width = gameDisplayRef.current.offsetWidth;
const size = height / 40;
const padding = height / 50;
const leftOffset =
isFullScreen || height * aspectRatio > width ? 0 : (width - height * aspectRatio) / 2;
setIconSize(size);
setIconPadding(`${padding}px`);
setIconLeft(`${leftOffset}px`);
}
};

// When exiting fullscreen, the browser might not have completed the transition
// at the time handleResize is called, so the height of gameDisplayRef.current
// is still the fullscreen height.
// To fix this, we delay handleResize by 100ms.
const delayedHandleResize = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto on moving this out of the useEffect body.

setTimeout(handleResize, 100);
};

window.addEventListener('resize', delayedHandleResize);
delayedHandleResize();

return () => window.removeEventListener('resize', delayedHandleResize);
Comment on lines +124 to +127
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the resize observer for when we already have isFullscreen as a state variable?

}, [isFullScreen]);

return (
<>
<div id="game-display"></div>
<div id="game-display" ref={gameDisplayRef}>
<Icon
id="fullscreen-button"
icon={isFullScreen ? 'minimize' : 'fullscreen'}
color="white"
htmlTitle={isFullScreen ? 'Exit full screen' : 'Full screen'}
size={iconSize}
onClick={toggleFullScreen}
style={{ left: iconLeft, padding: iconPadding }}
/>
</div>
{isTestStudent && (
<div className="Horizontal">
<button
Expand Down
6 changes: 6 additions & 0 deletions src/styles/_game.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@
width: 100%;
align-items: center;
}

#fullscreen-button {
position: absolute;
cursor: pointer;
z-index: 100;
}