global settings context, provider, hook

This commit is contained in:
Viktor Rådberg
2023-09-22 10:56:46 +02:00
parent 35e21a62fe
commit d7d9d26540
7 changed files with 166 additions and 121 deletions

View File

@@ -1,13 +1,8 @@
import { useEffect, useState } from 'react';
import styled, { createGlobalStyle } from 'styled-components';
import Play from './Components/Views/Play';
import StartMenu from './Components/Views/StartMenu/StartMenu';
import { InitialSettings } from './Data/getInitialPlayers';
import { createGlobalStyle } from 'styled-components';
import { ThemeProvider } from '@mui/material';
import { useWakeLock } from 'react-screen-wake-lock';
import { LifeTrinket } from './Components/LifeTrinket';
import { theme } from './Data/theme';
import { useAnalytics } from './Hooks/useAnalytics';
import { GlobalSettingsProvider } from './Providers/GlobalSettingsProvider';
import { PlayersProvider } from './Providers/PlayersProvider';
const GlobalStyles = createGlobalStyle`
@@ -20,111 +15,14 @@ const GlobalStyles = createGlobalStyle`
}
`;
const StartWrapper = styled.div`
max-width: fit-content;
max-height: fit-content;
`;
const PlayWrapper = styled.div`
position: relative;
z-index: 0;
max-width: fit-content;
max-height: fit-content;
@media (orientation: portrait) {
rotate: 90deg;
}
`;
const EmergencyResetButton = styled.button`
width: 100vmax;
height: 100vmin;
font-size: 4vmax;
position: absolute;
top: 0;
z-index: -1;
background-color: #4e6815;
`;
const App = () => {
const analytics = useAnalytics();
const savedGameSettings = localStorage.getItem('initialGameSettings');
const savedShowPlay = localStorage.getItem('showPlay');
const { isSupported, release, released, request, type } = useWakeLock();
const [initialGameSettings, setInitialGameSettings] =
useState<InitialSettings | null>(
savedGameSettings ? JSON.parse(savedGameSettings) : null
);
const [showPlay, setShowPlay] = useState<boolean>(
savedShowPlay ? savedShowPlay === 'true' : false
);
const isActive = released === undefined ? false : !released;
const wakeLock = {
isSupported,
release,
active: isActive,
request,
type,
};
useEffect(() => {
localStorage.setItem(
'initialGameSettings',
JSON.stringify(initialGameSettings)
);
}, [initialGameSettings]);
const removeLocalStorage = async () => {
localStorage.removeItem('initialGameSettings');
localStorage.removeItem('players');
localStorage.removeItem('playing');
localStorage.removeItem('showPlay');
setShowPlay(localStorage.getItem('showPlay') === 'true' ?? false);
};
const goToStart = async () => {
// this function is broken for the moment, need to set players object
const currentPlayers = localStorage.getItem('players');
if (currentPlayers) {
analytics.trackEvent('go_to_start', {
playersBeforeReset: currentPlayers,
});
}
await removeLocalStorage();
// setPlayers([]);
};
return (
<ThemeProvider theme={theme}>
<GlobalStyles />
<PlayersProvider>
{showPlay && initialGameSettings ? (
<PlayWrapper>
<Play
gridAreas={initialGameSettings?.gridAreas}
goToStart={goToStart}
wakeLock={wakeLock}
/>
<EmergencyResetButton onClick={goToStart}>
<p>If you can see this, something is wrong.</p>
<p>Press screen to go to start.</p>
<br />
<p>If the issue persists, please inform me.</p>
</EmergencyResetButton>
</PlayWrapper>
) : (
<StartWrapper>
<StartMenu
initialGameSettings={initialGameSettings}
setInitialGameSettings={setInitialGameSettings}
wakeLock={wakeLock}
setShowPlay={setShowPlay}
/>
</StartWrapper>
)}
<GlobalSettingsProvider>
<LifeTrinket />
</GlobalSettingsProvider>
</PlayersProvider>
</ThemeProvider>
);

View File

@@ -0,0 +1,114 @@
import { useState, useEffect } from 'react';
import { useWakeLock } from 'react-screen-wake-lock';
import styled from 'styled-components';
import { InitialSettings } from '../Data/getInitialPlayers';
import { useAnalytics } from '../Hooks/useAnalytics';
import Play from './Views/Play';
import StartMenu from './Views/StartMenu/StartMenu';
const StartWrapper = styled.div`
max-width: fit-content;
max-height: fit-content;
`;
const PlayWrapper = styled.div`
position: relative;
z-index: 0;
max-width: fit-content;
max-height: fit-content;
@media (orientation: portrait) {
rotate: 90deg;
}
`;
const EmergencyResetButton = styled.button`
width: 100vmax;
height: 100vmin;
font-size: 4vmax;
position: absolute;
top: 0;
z-index: -1;
background-color: #4e6815;
`;
export const LifeTrinket = () => {
const analytics = useAnalytics();
const savedGameSettings = localStorage.getItem('initialGameSettings');
const savedShowPlay = localStorage.getItem('showPlay');
const { isSupported, release, released, request, type } = useWakeLock();
const [initialGameSettings, setInitialGameSettings] =
useState<InitialSettings | null>(
savedGameSettings ? JSON.parse(savedGameSettings) : null
);
const [showPlay, setShowPlay] = useState<boolean>(
savedShowPlay ? savedShowPlay === 'true' : false
);
const isActive = released === undefined ? false : !released;
const wakeLock = {
isSupported,
release,
active: isActive,
request,
type,
};
useEffect(() => {
localStorage.setItem(
'initialGameSettings',
JSON.stringify(initialGameSettings)
);
}, [initialGameSettings]);
const removeLocalStorage = async () => {
localStorage.removeItem('initialGameSettings');
localStorage.removeItem('players');
localStorage.removeItem('playing');
localStorage.removeItem('showPlay');
setShowPlay(localStorage.getItem('showPlay') === 'true' ?? false);
};
const goToStart = async () => {
// this function is broken for the moment, need to set players object
const currentPlayers = localStorage.getItem('players');
if (currentPlayers) {
analytics.trackEvent('go_to_start', {
playersBeforeReset: currentPlayers,
});
}
await removeLocalStorage();
// setPlayers([]);
};
return (
<>
{showPlay && initialGameSettings ? (
<PlayWrapper>
<Play
gridAreas={initialGameSettings?.gridAreas}
goToStart={goToStart}
wakeLock={wakeLock}
/>
<EmergencyResetButton onClick={goToStart}>
<p>If you can see this, something is wrong.</p>
<p>Press screen to go to start.</p>
<br />
<p>If the issue persists, please inform me.</p>
</EmergencyResetButton>
</PlayWrapper>
) : (
<StartWrapper>
<StartMenu
initialGameSettings={initialGameSettings}
setInitialGameSettings={setInitialGameSettings}
wakeLock={wakeLock}
setShowPlay={setShowPlay}
/>
</StartWrapper>
)}
</>
);
};

View File

@@ -11,9 +11,9 @@ import {
} from '../../Icons/generated';
import { Player, Rotation } from '../../Types/Player';
import { WakeLock } from '../../Types/WakeLock';
import { useFullscreen } from '../../Hooks/useFullscreen';
import { theme } from '../../Data/theme';
import { InitialSettings } from '../../Data/getInitialPlayers';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
const SettingsContainer = styled.div<{
$rotation: Rotation;
@@ -145,7 +145,8 @@ const Settings = ({
opponents,
setShowPlayerMenu,
}: SettingsProps) => {
const { disableFullscreen, enableFullscreen, isFullscreen } = useFullscreen();
const { disableFullscreen, enableFullscreen, isFullscreen } =
useGlobalSettings();
const isSide =
player.settings.rotation === Rotation.Side ||
player.settings.rotation === Rotation.SideFlipped;

View File

@@ -15,9 +15,9 @@ import { InfoModal } from '../../Misc/InfoModal';
import { SupportMe } from '../../Misc/SupportMe';
import { H2, Paragraph } from '../../Misc/TextComponents';
import LayoutOptions from './LayoutOptions';
import { useFullscreen } from '../../../Hooks/useFullscreen';
import { Spacer } from '../../Misc/Spacer';
import { usePlayers } from '../../../Hooks/usePlayers';
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
const MainWrapper = styled.div`
width: 100dvw;
@@ -124,7 +124,7 @@ const Start = ({
);
const [wakeLockActive, setWakeLockActive] = useState(true);
const { enableFullscreen } = useFullscreen();
const { enableFullscreen } = useGlobalSettings();
const toggleWakeLock = () => {
if (wakeLock.active && wakeLockActive) {

View File

@@ -0,0 +1,10 @@
import { createContext } from 'react';
export type GlobalSettingsContextType = {
isFullscreen: boolean;
enableFullscreen: () => void;
disableFullscreen: () => void;
};
export const GlobalSettingsContext =
createContext<GlobalSettingsContextType | null>(null);

View File

@@ -0,0 +1,12 @@
import { useContext } from 'react';
import { GlobalSettingsContext } from '../Contexts/GlobalSettingsContext';
export const useGlobalSettings = () => {
const context = useContext(GlobalSettingsContext);
if (!context) {
throw new Error('useGlobalSettings hook had an issue with the context');
}
return { ...context };
};

View File

@@ -1,12 +1,14 @@
import { useEffect, useState } from 'react';
import { ReactNode, useEffect, useMemo, useState } from 'react';
import {
GlobalSettingsContext,
GlobalSettingsContextType,
} from '../Contexts/GlobalSettingsContext';
type FullscreenHookReturnType = {
isFullscreen: boolean;
enableFullscreen: () => void;
disableFullscreen: () => void;
};
export const useFullscreen = (): FullscreenHookReturnType => {
export const GlobalSettingsProvider = ({
children,
}: {
children: ReactNode;
}) => {
const [isFullscreen, setIsFullscreen] = useState(false);
const enableFullscreen = () => {
@@ -37,5 +39,13 @@ export const useFullscreen = (): FullscreenHookReturnType => {
};
}, []);
return { isFullscreen, enableFullscreen, disableFullscreen };
const ctxValue = useMemo((): GlobalSettingsContextType => {
return { isFullscreen, enableFullscreen, disableFullscreen };
}, [isFullscreen]);
return (
<GlobalSettingsContext.Provider value={ctxValue}>
{children}
</GlobalSettingsContext.Provider>
);
};