create usePlayers hook related context/provider

This commit is contained in:
Viktor Rådberg
2023-09-20 19:52:48 +02:00
parent f61d94ad3b
commit 3dc40bf193
6 changed files with 111 additions and 65 deletions

View File

@@ -3,12 +3,12 @@ import styled, { createGlobalStyle } from 'styled-components';
import Play from './Components/Views/Play'; import Play from './Components/Views/Play';
import StartMenu from './Components/Views/StartMenu/StartMenu'; import StartMenu from './Components/Views/StartMenu/StartMenu';
import { InitialSettings } from './Data/getInitialPlayers'; import { InitialSettings } from './Data/getInitialPlayers';
import { Player } from './Types/Player';
import { ThemeProvider } from '@mui/material'; import { ThemeProvider } from '@mui/material';
import { useWakeLock } from 'react-screen-wake-lock';
import { theme } from './Data/theme'; import { theme } from './Data/theme';
import { useAnalytics } from './Hooks/useAnalytics'; import { useAnalytics } from './Hooks/useAnalytics';
import { useWakeLock } from 'react-screen-wake-lock'; import { PlayersProvider } from './Providers/PlayersProvider';
const GlobalStyles = createGlobalStyle` const GlobalStyles = createGlobalStyle`
html, html,
@@ -53,9 +53,16 @@ const EmergencyResetButton = styled.button`
const App = () => { const App = () => {
const analytics = useAnalytics(); const analytics = useAnalytics();
const savedPlayers = localStorage.getItem('players');
const savedGameSettings = localStorage.getItem('initialGameSettings'); const savedGameSettings = localStorage.getItem('initialGameSettings');
const saveShowPlay = localStorage.getItem('showPlay');
const { isSupported, release, released, request, type } = useWakeLock(); const { isSupported, release, released, request, type } = useWakeLock();
const [initialGameSettings, setInitialGameSettings] =
useState<InitialSettings | null>(
savedGameSettings ? JSON.parse(savedGameSettings) : null
);
const [showPlay, setShowPlay] = useState<boolean>(
saveShowPlay ? saveShowPlay === 'true' : false
);
const isActive = released === undefined ? false : !released; const isActive = released === undefined ? false : !released;
@@ -67,32 +74,15 @@ const App = () => {
type, type,
}; };
const [initialGameSettings, setInitialGameSettings] =
useState<InitialSettings | null>(
savedGameSettings ? JSON.parse(savedGameSettings) : null
);
const [players, setPlayers] = useState<Player[]>(
savedPlayers ? JSON.parse(savedPlayers) : []
);
useEffect(() => { useEffect(() => {
localStorage.setItem('players', JSON.stringify(players));
localStorage.setItem( localStorage.setItem(
'initialGameSettings', 'initialGameSettings',
JSON.stringify(initialGameSettings) JSON.stringify(initialGameSettings)
); );
}, [initialGameSettings, players]); }, [initialGameSettings]);
const handlePlayerChange = (updatedPlayer: Player) => {
const updatedPlayers = players.map((player) =>
player.index === updatedPlayer.index ? updatedPlayer : player
);
setPlayers(updatedPlayers);
};
const goToStart = async () => { const goToStart = async () => {
// this function is broken for the moment, need to set players object
const currentPlayers = localStorage.getItem('players'); const currentPlayers = localStorage.getItem('players');
if (currentPlayers) { if (currentPlayers) {
analytics.trackEvent('go_to_start', { analytics.trackEvent('go_to_start', {
@@ -101,18 +91,16 @@ const App = () => {
} }
await removeLocalStorage(); await removeLocalStorage();
setPlayers([]); // setPlayers([]);
}; };
return ( return (
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<GlobalStyles /> <GlobalStyles />
<PlayersProvider>
{players.length > 0 && initialGameSettings ? ( {showPlay && initialGameSettings ? (
<PlayWrapper> <PlayWrapper>
<Play <Play
players={players}
onPlayerChange={handlePlayerChange}
gridAreas={initialGameSettings?.gridAreas} gridAreas={initialGameSettings?.gridAreas}
goToStart={goToStart} goToStart={goToStart}
wakeLock={wakeLock} wakeLock={wakeLock}
@@ -129,11 +117,12 @@ const App = () => {
<StartMenu <StartMenu
initialGameSettings={initialGameSettings} initialGameSettings={initialGameSettings}
setInitialGameSettings={setInitialGameSettings} setInitialGameSettings={setInitialGameSettings}
setPlayers={setPlayers}
wakeLock={wakeLock} wakeLock={wakeLock}
setShowPlay={setShowPlay}
/> />
</StartWrapper> </StartWrapper>
)} )}
</PlayersProvider>
</ThemeProvider> </ThemeProvider>
); );
}; };

View File

@@ -1,7 +1,7 @@
import styled from 'styled-components'; import styled from 'styled-components';
import Counters from '../Counters/Counters'; import { usePlayers } from '../../Hooks/usePlayers';
import { Player } from '../../Types/Player';
import { WakeLock } from '../../Types/WakeLock'; import { WakeLock } from '../../Types/WakeLock';
import Counters from '../Counters/Counters';
const MainWrapper = styled.div` const MainWrapper = styled.div`
width: 100vmax; width: 100vmax;
@@ -12,25 +12,18 @@ const MainWrapper = styled.div`
`; `;
type PlayProps = { type PlayProps = {
players: Player[];
onPlayerChange: (updatedPlayer: Player) => void;
gridAreas: string; gridAreas: string;
goToStart: () => void; goToStart: () => void;
wakeLock: WakeLock; wakeLock: WakeLock;
}; };
const Play = ({ const Play = ({ gridAreas, goToStart, wakeLock }: PlayProps) => {
players, const { players, updatePlayer } = usePlayers();
onPlayerChange,
gridAreas,
goToStart,
wakeLock,
}: PlayProps) => {
return ( return (
<MainWrapper> <MainWrapper>
<Counters <Counters
players={players} players={players}
onPlayerChange={onPlayerChange} onPlayerChange={updatePlayer}
gridAreas={gridAreas} gridAreas={gridAreas}
goToStart={goToStart} goToStart={goToStart}
wakeLock={wakeLock} wakeLock={wakeLock}

View File

@@ -10,7 +10,6 @@ import {
import { theme } from '../../../Data/theme'; import { theme } from '../../../Data/theme';
import { useAnalytics } from '../../../Hooks/useAnalytics'; import { useAnalytics } from '../../../Hooks/useAnalytics';
import { Info } from '../../../Icons/generated'; import { Info } from '../../../Icons/generated';
import { Player } from '../../../Types/Player';
import { WakeLock } from '../../../Types/WakeLock'; import { WakeLock } from '../../../Types/WakeLock';
import { InfoModal } from '../../Misc/InfoModal'; import { InfoModal } from '../../Misc/InfoModal';
import { SupportMe } from '../../Misc/SupportMe'; import { SupportMe } from '../../Misc/SupportMe';
@@ -18,6 +17,7 @@ import { H2, Paragraph } from '../../Misc/TextComponents';
import LayoutOptions from './LayoutOptions'; import LayoutOptions from './LayoutOptions';
import { useFullscreen } from '../../../Hooks/useFullscreen'; import { useFullscreen } from '../../../Hooks/useFullscreen';
import { Spacer } from '../../Misc/Spacer'; import { Spacer } from '../../Misc/Spacer';
import { usePlayers } from '../../../Hooks/usePlayers';
const MainWrapper = styled.div` const MainWrapper = styled.div`
width: 100dvw; width: 100dvw;
@@ -99,17 +99,18 @@ const healthMarks = [
type StartProps = { type StartProps = {
setInitialGameSettings: (options: InitialSettings) => void; setInitialGameSettings: (options: InitialSettings) => void;
setPlayers: (updatedPlayer: Player[]) => void;
initialGameSettings: InitialSettings | null; initialGameSettings: InitialSettings | null;
wakeLock: WakeLock; wakeLock: WakeLock;
setShowPlay: (showPlay: boolean) => void;
}; };
const Start = ({ const Start = ({
initialGameSettings, initialGameSettings,
setPlayers,
setInitialGameSettings, setInitialGameSettings,
wakeLock, wakeLock,
setShowPlay,
}: StartProps) => { }: StartProps) => {
const { setPlayers } = usePlayers();
const analytics = useAnalytics(); const analytics = useAnalytics();
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [playerOptions, setPlayerOptions] = useState<InitialSettings>( const [playerOptions, setPlayerOptions] = useState<InitialSettings>(
@@ -159,7 +160,10 @@ const Start = ({
setInitialGameSettings(initialGameSettings); setInitialGameSettings(initialGameSettings);
setPlayers(createInitialPlayers(initialGameSettings)); setPlayers(createInitialPlayers(initialGameSettings));
setShowPlay(true);
localStorage.setItem('playing', 'false'); localStorage.setItem('playing', 'false');
//Todo maybe showPlay is redundant?
localStorage.setItem('showPlay', 'true');
}; };
useEffect(() => { useEffect(() => {

View File

@@ -0,0 +1,10 @@
import { createContext } from 'react';
import { Player } from '../Types/Player';
export type PlayersContextType = {
players: Player[] | [];
setPlayers: (players: Player[]) => void;
updatePlayer: (updatedPlayer: Player) => void;
};
export const PlayersContext = createContext<PlayersContextType | null>(null);

12
src/Hooks/usePlayers.tsx Normal file
View File

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

View File

@@ -0,0 +1,38 @@
import { ReactNode, useEffect } from 'react';
import { Player } from '../Types/Player';
import { useMemo, useState } from 'react';
import { PlayersContextType, PlayersContext } from '../Contexts/PlayersContext';
export const PlayersProvider = ({ children }: { children: ReactNode }) => {
const savedPlayers = localStorage.getItem('players');
const [players, setPlayers] = useState<Player[]>(
savedPlayers ? JSON.parse(savedPlayers) : []
);
useEffect(() => {
localStorage.setItem('players', JSON.stringify(players));
}, [players]);
const updatePlayer = (updatedPlayer: Player) => {
const updatedPlayers = players.map((player) =>
player.index === updatedPlayer.index ? updatedPlayer : player
);
setPlayers(updatedPlayers);
};
const ctxValue = useMemo((): PlayersContextType => {
return {
players,
setPlayers,
updatePlayer,
};
}, [players]);
return (
<PlayersContext.Provider value={ctxValue}>
{children}
</PlayersContext.Provider>
);
};