From a90dd7c9ea44b568e87aeb873c879db1cb5fbc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20R=C3=A5dberg?= Date: Sat, 16 Mar 2024 14:40:18 +0100 Subject: [PATCH 1/5] wip --- src/Components/LifeCounter/LifeCounter.tsx | 76 ++++++++------ src/Components/Misc/SettingsModal.tsx | 20 ++++ src/Components/Player/Player.tsx | 50 ---------- .../{Player => Players}/PlayerMenu.tsx | 0 src/Components/Players/Players.tsx | 99 +++++++++++++++++++ src/Components/Views/Play.tsx | 28 +++--- src/Data/getInitialPlayers.ts | 4 - src/Providers/GlobalSettingsProvider.tsx | 1 + src/Providers/PlayersProvider.tsx | 12 --- src/Types/Player.ts | 2 - src/Types/Settings.ts | 1 + 11 files changed, 183 insertions(+), 110 deletions(-) delete mode 100644 src/Components/Player/Player.tsx rename src/Components/{Player => Players}/PlayerMenu.tsx (100%) create mode 100644 src/Components/Players/Players.tsx diff --git a/src/Components/LifeCounter/LifeCounter.tsx b/src/Components/LifeCounter/LifeCounter.tsx index 0e5be1b..52700b0 100644 --- a/src/Components/LifeCounter/LifeCounter.tsx +++ b/src/Components/LifeCounter/LifeCounter.tsx @@ -13,7 +13,7 @@ import { LoseGameButton } from '../Buttons/LoseButton'; import CommanderDamageBar from '../Counters/CommanderDamageBar'; import ExtraCountersBar from '../Counters/ExtraCountersBar'; import { Paragraph } from '../Misc/TextComponents'; -import PlayerMenu from '../Player/PlayerMenu'; +import PlayerMenu from '../Players/PlayerMenu'; import Health from './Health'; import { baseColors } from '../../../tailwind.config'; @@ -88,16 +88,24 @@ const playerCanLose = (player: Player) => { }; type LifeCounterProps = { + stopRandom: boolean; player: Player; opponents: Player[]; + isStartingPlayer?: boolean; }; const RECENT_DIFFERENCE_TTL = 3_000; -const LifeCounter = ({ player, opponents }: LifeCounterProps) => { +const LifeCounter = ({ + stopRandom, + player, + opponents, + isStartingPlayer, +}: LifeCounterProps) => { const { updatePlayer, updateLifeTotal } = usePlayers(); const { settings } = useGlobalSettings(); const playingTimerRef = useRef(undefined); + const [playing, setPlaying] = useState(false); const [showPlayerMenu, setShowPlayerMenu] = useState(false); const [recentDifference, setRecentDifference] = useState(0); @@ -127,6 +135,7 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => { onSwiping: (e) => e.event.stopPropagation(), rotationAngle, }); + console.log('stopRandom', stopRandom); useEffect(() => { const timer = setTimeout(() => { @@ -153,6 +162,7 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => { useEffect(() => { playingTimerRef.current = setTimeout(() => { localStorage.setItem('playing', 'true'); + setPlaying(true); }, 10_000); return () => clearTimeout(playingTimerRef.current); @@ -191,39 +201,49 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => { style={{ rotate: `${calcRotation}deg` }} {...handlers} > - {settings.showStartingPlayer && - player.isStartingPlayer && - player.showStartingPlayer && ( -
{ + clearTimeout(playingTimerRef.current); + localStorage.setItem('playing', 'true'); + setPlaying(true); + }} + > + { - clearTimeout(playingTimerRef.current); - localStorage.setItem('playing', 'true'); - player.showStartingPlayer = false; - updatePlayer(player); + rotate: `${calcTextRotation}deg`, }} > - -
- 👑 - You start! - (Press to hide) -
-
-
- )} +
+ 👑 + {(stopRandom || !settings.useRandomStartingPlayerInterval) && ( + <> + You start! + (Press to hide) + + )} +
+ + + )} {player.hasLost && ( )} + {settings.useRandomStartingPlayerInterval && !stopRandom && ( +
+ )} { this is enabled. + + + Randomize starting player with interval + { + setSettings({ + ...settings, + useRandomStartingPlayerInterval: + !settings.useRandomStartingPlayerInterval, + }); + }} + /> + + + Will randomize between all players at when starting a game, + pressing the screen aborts the interval and chooses the player + that has the crown. + + Keep Awake diff --git a/src/Components/Player/Player.tsx b/src/Components/Player/Player.tsx deleted file mode 100644 index ee009c1..0000000 --- a/src/Components/Player/Player.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import LifeCounter from '../LifeCounter/LifeCounter'; -import { Player as PlayerType } from '../../Types/Player'; -import { twc } from 'react-twc'; - -const getGridArea = (player: PlayerType) => { - switch (player.index) { - case 0: - return 'grid-in-player0'; - case 1: - return 'grid-in-player1'; - case 2: - return 'grid-in-player2'; - case 3: - return 'grid-in-player3'; - case 4: - return 'grid-in-player4'; - case 5: - return 'grid-in-player5'; - default: - throw new Error('Invalid player index'); - } -}; - -const PlayerWrapper = twc.div`w-full h-full bg-black`; - -export const Player = (players: PlayerType[], gridClasses: string) => { - return ( - -
- {players.map((player) => { - const gridArea = getGridArea(player); - - return ( -
- opponent.index !== player.index - )} - /> -
- ); - })} -
-
- ); -}; diff --git a/src/Components/Player/PlayerMenu.tsx b/src/Components/Players/PlayerMenu.tsx similarity index 100% rename from src/Components/Player/PlayerMenu.tsx rename to src/Components/Players/PlayerMenu.tsx diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx new file mode 100644 index 0000000..e177d3f --- /dev/null +++ b/src/Components/Players/Players.tsx @@ -0,0 +1,99 @@ +import LifeCounter from '../LifeCounter/LifeCounter'; +import { Player as PlayerType } from '../../Types/Player'; +import { twc } from 'react-twc'; +import { useEffect, useRef, useState } from 'react'; +import { useGlobalSettings } from '../../Hooks/useGlobalSettings'; + +const getGridArea = (player: PlayerType) => { + switch (player.index) { + case 0: + return 'grid-in-player0'; + case 1: + return 'grid-in-player1'; + case 2: + return 'grid-in-player2'; + case 3: + return 'grid-in-player3'; + case 4: + return 'grid-in-player4'; + case 5: + return 'grid-in-player5'; + default: + throw new Error('Invalid player index'); + } +}; + +const PlayersWrapper = twc.div`w-full h-full bg-black`; + +export const Players = (players: PlayerType[], gridClasses: string) => { + const randomIntervalRef = useRef(null); + const [randomPlayerIndex, setRandomPlayerIndex] = useState( + Math.floor(Math.random() * players.length) + ); + const [stopRandom, setStopRandom] = useState(false); + const { settings } = useGlobalSettings(); + + useEffect(() => { + if (settings.useRandomStartingPlayerInterval) { + randomIntervalRef.current = setInterval(() => { + let randomIndex: number; + + do { + randomIndex = Math.floor(Math.random() * players.length); + } while (randomIndex === randomPlayerIndex); + + setRandomPlayerIndex(randomIndex); + }, 100); + } + return () => { + if (randomIntervalRef.current) { + clearInterval(randomIntervalRef.current); + } + }; + }, [ + players.length, + randomPlayerIndex, + settings.useRandomStartingPlayerInterval, + ]); + + return ( + + {settings.useRandomStartingPlayerInterval && ( +
{ + if (randomIntervalRef.current) { + clearInterval(randomIntervalRef.current); + randomIntervalRef.current = null; + setStopRandom(true); + } + }} + > + CHOOSE A PLAYER +
+ )} +
+ {players.map((player) => { + const gridArea = getGridArea(player); + + return ( +
+ opponent.index !== player.index + )} + isStartingPlayer={randomPlayerIndex === player.index} + /> +
+ ); + })} +
+
+ ); +}; diff --git a/src/Components/Views/Play.tsx b/src/Components/Views/Play.tsx index c52dc2a..17c6e1e 100644 --- a/src/Components/Views/Play.tsx +++ b/src/Components/Views/Play.tsx @@ -1,7 +1,7 @@ import { useGlobalSettings } from '../../Hooks/useGlobalSettings'; import { usePlayers } from '../../Hooks/usePlayers'; import { Orientation } from '../../Types/Settings'; -import { Player } from '../Player/Player'; +import { Players } from '../Players/Players'; import { twc } from 'react-twc'; const MainWrapper = twc.div`w-[100dvmax] h-[100dvmin] overflow-hidden`; @@ -14,52 +14,52 @@ export const Play = () => { switch (players.length) { case 1: if (initialGameSettings?.orientation === Orientation.Portrait) { - Layout = Player(players, 'grid-areas-onePlayerPortrait'); + Layout = Players(players, 'grid-areas-onePlayerPortrait'); } - Layout = Player(players, 'grid-areas-onePlayerLandscape'); + Layout = Players(players, 'grid-areas-onePlayerLandscape'); break; case 2: switch (initialGameSettings?.orientation) { case Orientation.Portrait: - Layout = Player(players, 'grid-areas-twoPlayersOppositePortrait'); + Layout = Players(players, 'grid-areas-twoPlayersOppositePortrait'); break; default: case Orientation.Landscape: - Layout = Player(players, 'grid-areas-twoPlayersSameSideLandscape'); + Layout = Players(players, 'grid-areas-twoPlayersSameSideLandscape'); break; case Orientation.OppositeLandscape: - Layout = Player(players, 'grid-areas-twoPlayersOppositeLandscape'); + Layout = Players(players, 'grid-areas-twoPlayersOppositeLandscape'); break; } break; case 3: if (initialGameSettings?.orientation === Orientation.Portrait) { - Layout = Player(players, 'grid-areas-threePlayersSide'); + Layout = Players(players, 'grid-areas-threePlayersSide'); break; } - Layout = Player(players, 'grid-areas-threePlayers'); + Layout = Players(players, 'grid-areas-threePlayers'); break; default: case 4: if (initialGameSettings?.orientation === Orientation.Portrait) { - Layout = Player(players, 'grid-areas-fourPlayerPortrait'); + Layout = Players(players, 'grid-areas-fourPlayerPortrait'); break; } - Layout = Player(players, 'grid-areas-fourPlayer'); + Layout = Players(players, 'grid-areas-fourPlayer'); break; case 5: if (initialGameSettings?.orientation === Orientation.Portrait) { - Layout = Player(players, 'grid-areas-fivePlayersSide'); + Layout = Players(players, 'grid-areas-fivePlayersSide'); break; } - Layout = Player(players, 'grid-areas-fivePlayers'); + Layout = Players(players, 'grid-areas-fivePlayers'); break; case 6: if (initialGameSettings?.orientation === Orientation.Portrait) { - Layout = Player(players, 'grid-areas-sixPlayersSide'); + Layout = Players(players, 'grid-areas-sixPlayersSide'); break; } - Layout = Player(players, 'grid-areas-sixPlayers'); + Layout = Players(players, 'grid-areas-sixPlayers'); break; } diff --git a/src/Data/getInitialPlayers.ts b/src/Data/getInitialPlayers.ts index 3584f43..203b8e5 100644 --- a/src/Data/getInitialPlayers.ts +++ b/src/Data/getInitialPlayers.ts @@ -191,10 +191,8 @@ export const createInitialPlayers = ({ }: InitialGameSettings): Player[] => { const players: Player[] = []; const availableColors = [...presetColors]; // Create a copy of the colors array - const firstPlayerIndex = Math.floor(Math.random() * numberOfPlayers); for (let i = 0; i <= numberOfPlayers - 1; i++) { - const isStartingPlayer = i === firstPlayerIndex; const colorIndex = Math.floor(Math.random() * availableColors.length); const color = availableColors[colorIndex]; @@ -224,8 +222,6 @@ export const createInitialPlayers = ({ usePoison: false, rotation, }, - isStartingPlayer, - showStartingPlayer: isStartingPlayer, extraCounters: [], commanderDamage, hasLost: false, diff --git a/src/Providers/GlobalSettingsProvider.tsx b/src/Providers/GlobalSettingsProvider.tsx index bd2b794..59746d3 100644 --- a/src/Providers/GlobalSettingsProvider.tsx +++ b/src/Providers/GlobalSettingsProvider.tsx @@ -39,6 +39,7 @@ export const GlobalSettingsProvider = ({ keepAwake: true, showStartingPlayer: true, showPlayerMenuCog: true, + useRandomStartingPlayerInterval: false, } ); diff --git a/src/Providers/PlayersProvider.tsx b/src/Providers/PlayersProvider.tsx index 7e27b5e..84a11e9 100644 --- a/src/Providers/PlayersProvider.tsx +++ b/src/Providers/PlayersProvider.tsx @@ -50,10 +50,6 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => { return; } - const startingPlayerIndex = Math.floor( - Math.random() * initialGameSettings.numberOfPlayers - ); - players.forEach((player: Player) => { player.commanderDamage.map((damage) => { damage.damageTotal = 0; @@ -68,14 +64,6 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => { player.hasLost = false; - const isStartingPlayer = player.index === startingPlayerIndex; - - player.isStartingPlayer = isStartingPlayer; - - if (player.isStartingPlayer) { - player.showStartingPlayer = true; - } - updatePlayer(player); }); localStorage.setItem('playing', 'false'); diff --git a/src/Types/Player.ts b/src/Types/Player.ts index 93ecd3f..6797d8b 100644 --- a/src/Types/Player.ts +++ b/src/Types/Player.ts @@ -5,8 +5,6 @@ export type Player = { settings: PlayerSettings; commanderDamage: CommanderDamage[]; extraCounters: ExtraCounter[]; - isStartingPlayer: boolean; - showStartingPlayer: boolean; hasLost: boolean; isSide: boolean; }; diff --git a/src/Types/Settings.ts b/src/Types/Settings.ts index 48e025c..e697560 100644 --- a/src/Types/Settings.ts +++ b/src/Types/Settings.ts @@ -17,6 +17,7 @@ export type Settings = { showStartingPlayer: boolean; showPlayerMenuCog: boolean; goFullscreenOnStart: boolean; + useRandomStartingPlayerInterval: boolean; }; export type InitialGameSettings = { From 905912a7fda0f5d086a6582adc3e5beeaccbb475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20R=C3=A5dberg?= Date: Sat, 16 Mar 2024 21:59:24 +0100 Subject: [PATCH 2/5] fix random interval --- src/Components/LifeCounter/LifeCounter.tsx | 61 ++++++------ src/Components/Players/PlayerMenu.tsx | 18 +++- src/Components/Players/Players.tsx | 102 +++++++++++++++------ src/Contexts/GlobalSettingsContext.tsx | 4 + src/Contexts/PlayersContext.tsx | 2 + src/Providers/GlobalSettingsProvider.tsx | 20 ++++ src/Providers/PlayersProvider.tsx | 20 +++- src/Types/Player.ts | 1 + 8 files changed, 167 insertions(+), 61 deletions(-) diff --git a/src/Components/LifeCounter/LifeCounter.tsx b/src/Components/LifeCounter/LifeCounter.tsx index 52700b0..866b6b7 100644 --- a/src/Components/LifeCounter/LifeCounter.tsx +++ b/src/Components/LifeCounter/LifeCounter.tsx @@ -88,7 +88,6 @@ const playerCanLose = (player: Player) => { }; type LifeCounterProps = { - stopRandom: boolean; player: Player; opponents: Player[]; isStartingPlayer?: boolean; @@ -96,16 +95,11 @@ type LifeCounterProps = { const RECENT_DIFFERENCE_TTL = 3_000; -const LifeCounter = ({ - stopRandom, - player, - opponents, - isStartingPlayer, -}: LifeCounterProps) => { +const LifeCounter = ({ player, opponents }: LifeCounterProps) => { const { updatePlayer, updateLifeTotal } = usePlayers(); - const { settings } = useGlobalSettings(); + const { settings, playing, setPlaying, stopPlayerRandomization } = + useGlobalSettings(); const playingTimerRef = useRef(undefined); - const [playing, setPlaying] = useState(false); const [showPlayerMenu, setShowPlayerMenu] = useState(false); const [recentDifference, setRecentDifference] = useState(0); @@ -122,12 +116,10 @@ const LifeCounter = ({ trackMouse: true, onSwipedDown: (e) => { e.event.stopPropagation(); - console.log(`User DOWN Swiped on player ${player.index}`); setShowPlayerMenu(true); }, onSwipedUp: (e) => { e.event.stopPropagation(); - console.log(`User UP Swiped on player ${player.index}`); setShowPlayerMenu(false); }, @@ -135,7 +127,6 @@ const LifeCounter = ({ onSwiping: (e) => e.event.stopPropagation(), rotationAngle, }); - console.log('stopRandom', stopRandom); useEffect(() => { const timer = setTimeout(() => { @@ -160,13 +151,26 @@ const LifeCounter = ({ }, [recentDifference, document.body.clientHeight, document.body.clientWidth]); useEffect(() => { - playingTimerRef.current = setTimeout(() => { - localStorage.setItem('playing', 'true'); - setPlaying(true); - }, 10_000); + if ( + player.isStartingPlayer && + ((!playing && + settings.useRandomStartingPlayerInterval && + stopPlayerRandomization) || + (!settings.useRandomStartingPlayerInterval && !playing)) + ) { + playingTimerRef.current = setTimeout(() => { + setPlaying(true); + }, 10_000); + } return () => clearTimeout(playingTimerRef.current); - }, []); + }, [ + player.isStartingPlayer, + playing, + setPlaying, + settings.useRandomStartingPlayerInterval, + stopPlayerRandomization, + ]); player.settings.rotation === Rotation.SideFlipped || player.settings.rotation === Rotation.Side; @@ -201,19 +205,19 @@ const LifeCounter = ({ style={{ rotate: `${calcRotation}deg` }} {...handlers} > - {!playing && settings.showStartingPlayer && isStartingPlayer && ( + {!playing && settings.showStartingPlayer && player.isStartingPlayer && (
{ clearTimeout(playingTimerRef.current); - localStorage.setItem('playing', 'true'); setPlaying(true); }} > @@ -224,7 +228,8 @@ const LifeCounter = ({ >
👑 - {(stopRandom || !settings.useRandomStartingPlayerInterval) && ( + {(stopPlayerRandomization || + !settings.useRandomStartingPlayerInterval) && ( <> You start! (Press to hide) @@ -238,12 +243,14 @@ const LifeCounter = ({ {player.hasLost && ( )} - {settings.useRandomStartingPlayerInterval && !stopRandom && ( -
- )} + {settings.useRandomStartingPlayerInterval && + !stopPlayerRandomization && + !playing && ( +
+ )} ) => { @@ -122,6 +129,13 @@ const PlayerMenu = ({ const handleResetGame = () => { resetCurrentGame(); setShowPlayerMenu(false); + setPlaying(false); + setStopPlayerRandomization(false); + }; + + const handleGoToStart = () => { + goToStart(); + setStopPlayerRandomization(false); }; const toggleFullscreen = () => { @@ -291,7 +305,7 @@ const PlayerMenu = ({ cursor: 'pointer', userSelect: 'none', }} - onClick={goToStart} + onClick={handleGoToStart} aria-label="Back to start" > diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx index e177d3f..643914f 100644 --- a/src/Components/Players/Players.tsx +++ b/src/Components/Players/Players.tsx @@ -1,8 +1,9 @@ -import LifeCounter from '../LifeCounter/LifeCounter'; -import { Player as PlayerType } from '../../Types/Player'; -import { twc } from 'react-twc'; import { useEffect, useRef, useState } from 'react'; +import { twc } from 'react-twc'; import { useGlobalSettings } from '../../Hooks/useGlobalSettings'; +import { usePlayers } from '../../Hooks/usePlayers'; +import { Player as PlayerType } from '../../Types/Player'; +import LifeCounter from '../LifeCounter/LifeCounter'; const getGridArea = (player: PlayerType) => { switch (player.index) { @@ -27,23 +28,63 @@ const PlayersWrapper = twc.div`w-full h-full bg-black`; export const Players = (players: PlayerType[], gridClasses: string) => { const randomIntervalRef = useRef(null); - const [randomPlayerIndex, setRandomPlayerIndex] = useState( - Math.floor(Math.random() * players.length) - ); - const [stopRandom, setStopRandom] = useState(false); - const { settings } = useGlobalSettings(); + + const prevRandomIndexRef = useRef(-1); + + const { + settings, + stopPlayerRandomization, + setStopPlayerRandomization, + playing, + } = useGlobalSettings(); + + const { setPlayers } = usePlayers(); useEffect(() => { - if (settings.useRandomStartingPlayerInterval) { + if ( + settings.useRandomStartingPlayerInterval && + !stopPlayerRandomization && + !playing + ) { randomIntervalRef.current = setInterval(() => { let randomIndex: number; do { randomIndex = Math.floor(Math.random() * players.length); - } while (randomIndex === randomPlayerIndex); + } while (randomIndex === prevRandomIndexRef.current); - setRandomPlayerIndex(randomIndex); - }, 100); + prevRandomIndexRef.current = randomIndex; + setPlayers( + players.map((p) => + p.index === prevRandomIndexRef.current + ? { + ...p, + isStartingPlayer: true, + } + : { + ...p, + isStartingPlayer: false, + } + ) + ); + }, 200); + } + + if (!settings.useRandomStartingPlayerInterval) { + const randomPlayerIndex = Math.floor(Math.random() * players.length); + setPlayers( + players.map((p) => + p.index === randomPlayerIndex + ? { + ...p, + isStartingPlayer: true, + } + : { + ...p, + isStartingPlayer: false, + } + ) + ); } return () => { if (randomIntervalRef.current) { @@ -52,27 +93,30 @@ export const Players = (players: PlayerType[], gridClasses: string) => { }; }, [ players.length, - randomPlayerIndex, + playing, + setPlayers, settings.useRandomStartingPlayerInterval, + stopPlayerRandomization, ]); return ( - {settings.useRandomStartingPlayerInterval && ( -
{ - if (randomIntervalRef.current) { - clearInterval(randomIntervalRef.current); - randomIntervalRef.current = null; - setStopRandom(true); - } - }} - > - CHOOSE A PLAYER -
- )} + {settings.useRandomStartingPlayerInterval && + !stopPlayerRandomization && + !playing && ( +
{ + if (randomIntervalRef.current) { + clearInterval(randomIntervalRef.current); + randomIntervalRef.current = null; + } + setStopPlayerRandomization(true); + }} + > + CHOOSE A PLAYER +
+ )}
{players.map((player) => { const gridArea = getGridArea(player); @@ -83,12 +127,10 @@ export const Players = (players: PlayerType[], gridClasses: string) => { className={`flex justify-center items-center align-middle ${gridArea}`} > opponent.index !== player.index )} - isStartingPlayer={randomPlayerIndex === player.index} />
); diff --git a/src/Contexts/GlobalSettingsContext.tsx b/src/Contexts/GlobalSettingsContext.tsx index aee0e38..fa06150 100644 --- a/src/Contexts/GlobalSettingsContext.tsx +++ b/src/Contexts/GlobalSettingsContext.tsx @@ -22,6 +22,10 @@ export type GlobalSettingsContextType = { setInitialGameSettings: (initialGameSettings: InitialGameSettings) => void; settings: Settings; setSettings: (settings: Settings) => void; + playing: boolean; + setPlaying: (playing: boolean) => void; + stopPlayerRandomization: boolean; + setStopPlayerRandomization: (stopRandom: boolean) => void; isPWA: boolean; }; diff --git a/src/Contexts/PlayersContext.tsx b/src/Contexts/PlayersContext.tsx index a1e9479..9da2124 100644 --- a/src/Contexts/PlayersContext.tsx +++ b/src/Contexts/PlayersContext.tsx @@ -7,6 +7,8 @@ export type PlayersContextType = { updatePlayer: (updatedPlayer: Player) => void; updateLifeTotal: (player: Player, updatedLifeTotal: number) => number; resetCurrentGame: () => void; + startingPlayerIndex: number; + setStartingPlayerIndex: (index: number) => void; }; export const PlayersContext = createContext(null); diff --git a/src/Providers/GlobalSettingsProvider.tsx b/src/Providers/GlobalSettingsProvider.tsx index 59746d3..4dba78e 100644 --- a/src/Providers/GlobalSettingsProvider.tsx +++ b/src/Providers/GlobalSettingsProvider.tsx @@ -21,11 +21,23 @@ export const GlobalSettingsProvider = ({ const savedShowPlay = localStorage.getItem('showPlay'); const savedGameSettings = localStorage.getItem('initialGameSettings'); const savedSettings = localStorage.getItem('settings'); + const savedPlaying = localStorage.getItem('playing'); + + const [playing, setPlaying] = useState( + savedPlaying ? savedPlaying === 'true' : false + ); + const setPlayingAndLocalStorage = (playing: boolean) => { + setPlaying(playing); + localStorage.setItem('playing', String(playing)); + }; const [showPlay, setShowPlay] = useState( savedShowPlay ? savedShowPlay === 'true' : false ); + const [stopPlayerRandomization, setStopPlayerRandomization] = + useState(false); + const [initialGameSettings, setInitialGameSettings] = useState( savedGameSettings ? JSON.parse(savedGameSettings) : null @@ -48,6 +60,8 @@ export const GlobalSettingsProvider = ({ localStorage.removeItem('players'); localStorage.removeItem('playing'); localStorage.removeItem('showPlay'); + + setPlaying(false); setShowPlay(false); }; @@ -154,10 +168,14 @@ export const GlobalSettingsProvider = ({ goToStart, showPlay, setShowPlay, + playing, + setPlaying: setPlayingAndLocalStorage, initialGameSettings, setInitialGameSettings, settings, setSettings, + stopPlayerRandomization, + setStopPlayerRandomization, isPWA: window?.matchMedia('(display-mode: standalone)').matches, }; }, [ @@ -166,10 +184,12 @@ export const GlobalSettingsProvider = ({ initialGameSettings, isFullscreen, isSupported, + playing, release, request, settings, showPlay, + stopPlayerRandomization, type, ]); diff --git a/src/Providers/PlayersProvider.tsx b/src/Providers/PlayersProvider.tsx index 84a11e9..b5048ae 100644 --- a/src/Providers/PlayersProvider.tsx +++ b/src/Providers/PlayersProvider.tsx @@ -7,6 +7,17 @@ import { InitialGameSettings } from '../Types/Settings'; export const PlayersProvider = ({ children }: { children: ReactNode }) => { const savedPlayers = localStorage.getItem('players'); + const savedStartingPlayerIndex = localStorage.getItem('startingPlayerIndex'); + + const [startingPlayerIndex, setStartingPlayerIndex] = useState( + savedStartingPlayerIndex ? parseInt(savedStartingPlayerIndex) : -1 + ); + + const setStartingPlayerIndexAndLocalStorage = (index: number) => { + setStartingPlayerIndex(index); + localStorage.setItem('startingPlayerIndex', String(index)); + }; + const [players, setPlayers] = useState( savedPlayers ? JSON.parse(savedPlayers) : [] ); @@ -50,6 +61,8 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => { return; } + const newStartingPlayerIndex = Math.floor(Math.random() * players.length); + players.forEach((player: Player) => { player.commanderDamage.map((damage) => { damage.damageTotal = 0; @@ -61,9 +74,10 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => { }); player.lifeTotal = initialGameSettings.startingLifeTotal; - player.hasLost = false; + player.isStartingPlayer = newStartingPlayerIndex === player.index; + updatePlayer(player); }); localStorage.setItem('playing', 'false'); @@ -75,8 +89,10 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => { updatePlayer, updateLifeTotal, resetCurrentGame, + startingPlayerIndex, + setStartingPlayerIndex: setStartingPlayerIndexAndLocalStorage, }; - }, [players]); + }, [players, startingPlayerIndex]); return ( diff --git a/src/Types/Player.ts b/src/Types/Player.ts index 6797d8b..2082975 100644 --- a/src/Types/Player.ts +++ b/src/Types/Player.ts @@ -5,6 +5,7 @@ export type Player = { settings: PlayerSettings; commanderDamage: CommanderDamage[]; extraCounters: ExtraCounter[]; + isStartingPlayer: boolean; hasLost: boolean; isSide: boolean; }; From f11eea5e53e1ec6ae7eae9baf055009305d9a23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20R=C3=A5dberg?= Date: Sat, 16 Mar 2024 22:23:03 +0100 Subject: [PATCH 3/5] better styling --- src/Components/Players/Players.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx index 643914f..7ce34a6 100644 --- a/src/Components/Players/Players.tsx +++ b/src/Components/Players/Players.tsx @@ -67,7 +67,7 @@ export const Players = (players: PlayerType[], gridClasses: string) => { } ) ); - }, 200); + }, 100); } if (!settings.useRandomStartingPlayerInterval) { @@ -105,7 +105,7 @@ export const Players = (players: PlayerType[], gridClasses: string) => { !stopPlayerRandomization && !playing && (
{ if (randomIntervalRef.current) { clearInterval(randomIntervalRef.current); @@ -114,7 +114,9 @@ export const Players = (players: PlayerType[], gridClasses: string) => { setStopPlayerRandomization(true); }} > - CHOOSE A PLAYER +
+ PRESS TO SELECT PLAYER +
)}
From a1b5cfd871ee7e10c42ab8f45a69cbe990f04fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20R=C3=A5dberg?= Date: Sat, 16 Mar 2024 22:26:06 +0100 Subject: [PATCH 4/5] fix tsc --- src/Components/Players/Players.tsx | 2 +- src/Data/getInitialPlayers.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx index 7ce34a6..fa3833f 100644 --- a/src/Components/Players/Players.tsx +++ b/src/Components/Players/Players.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import { twc } from 'react-twc'; import { useGlobalSettings } from '../../Hooks/useGlobalSettings'; import { usePlayers } from '../../Hooks/usePlayers'; diff --git a/src/Data/getInitialPlayers.ts b/src/Data/getInitialPlayers.ts index 203b8e5..d64ebab 100644 --- a/src/Data/getInitialPlayers.ts +++ b/src/Data/getInitialPlayers.ts @@ -225,6 +225,7 @@ export const createInitialPlayers = ({ extraCounters: [], commanderDamage, hasLost: false, + isStartingPlayer: false, isSide: rotation === Rotation.Side || rotation === Rotation.SideFlipped, }; From d4dc44076df4f13b95408901531dd77794d72413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20R=C3=A5dberg?= Date: Sat, 16 Mar 2024 22:28:37 +0100 Subject: [PATCH 5/5] fix lint --- src/Components/Players/Players.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx index fa3833f..92a6427 100644 --- a/src/Components/Players/Players.tsx +++ b/src/Components/Players/Players.tsx @@ -91,6 +91,7 @@ export const Players = (players: PlayerType[], gridClasses: string) => { clearInterval(randomIntervalRef.current); } }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ players.length, playing,