diff --git a/src/components/CardFlash/dialog.tsx b/src/components/CardFlash/dialog.tsx index f20e714..8035642 100644 --- a/src/components/CardFlash/dialog.tsx +++ b/src/components/CardFlash/dialog.tsx @@ -7,22 +7,33 @@ interface CardFlashDialogProps { card: Card; } -const CardFlashDialog: FunctionComponent = (props) => { +const CardFlashDialog: FunctionComponent = ({ + open, + card, +}) => { const [cardImageURI, setCardImageURI] = useState( undefined, ); useEffect(() => { - setCardImageURI(getCardImageURI(props.card)); + setCardImageURI(getCardImageURI(card)); return () => { setCardImageURI(undefined); }; - }, [props.card]); + }, [card]); return ( - - {cardImageURI && } + + {cardImageURI && ( + + )} ); }; diff --git a/src/components/CardFlash/provider.tsx b/src/components/CardFlash/provider.tsx index b92fdff..550476a 100644 --- a/src/components/CardFlash/provider.tsx +++ b/src/components/CardFlash/provider.tsx @@ -27,7 +27,7 @@ export interface flashCardOptions { } export const CardFlashProvider: FunctionComponent = ({ - duration = 500, + duration = 750, ...props }) => { const [show, setShow] = useState(false); @@ -37,6 +37,11 @@ export const CardFlashProvider: FunctionComponent = ({ const flashCard = (card: Card, options?: flashCardOptions) => { setCard(card); + if (card.value === 14) { + setShow(false); + return; + } + setTimeoutRef((prev) => { prev && clearTimeout(prev); return setTimeout(() => { diff --git a/src/stores/game.mapper.ts b/src/stores/game.mapper.ts index b585095..5510d12 100644 --- a/src/stores/game.mapper.ts +++ b/src/stores/game.mapper.ts @@ -19,11 +19,15 @@ const mapToRemote = (state: GameState): Game => { cards: state.draws, - dnf_player_ids: state.dnf_player_ids, + dnf_player_ids: playerIndexesToIds(state, state.dnf_player_indexes), dnf: false, // TODO: Implement }; }; +const playerIndexesToIds = (state: GameState, indexes: number[]): number[] => { + return indexes.map((index) => state.players[index].id as number); +}; + const mapToLocal = (game: Game): GameState => { return { id: game.id, @@ -47,8 +51,12 @@ const mapToLocal = (game: Game): GameState => { draws: game.cards, - dnf_player_ids: game.dnf_player_ids, + dnf_player_indexes: playerIdsToIndexes(game, game.dnf_player_ids), }; }; +const playerIdsToIndexes = (game: Game, ids: number[]): number[] => { + return ids.map((id) => game.player_ids.indexOf(id)); +}; + export { mapToLocal, mapToRemote }; diff --git a/src/stores/game.ts b/src/stores/game.ts index f6f94d3..6a9fbd8 100644 --- a/src/stores/game.ts +++ b/src/stores/game.ts @@ -30,7 +30,7 @@ interface GameState { players: Player[]; - dnf_player_ids: number[]; + dnf_player_indexes: number[]; draws: Card[]; } @@ -75,7 +75,7 @@ const initialState: GameState = { players: [], - dnf_player_ids: [], + dnf_player_indexes: [], draws: [], }; @@ -152,41 +152,41 @@ const useGame = create()( useGamesPlayed.getState().incrementStarted(); }, - SetPlayerDNF: (playerId: number, dnf: boolean) => { + SetPlayerDNF: (playerIndex: number, dnf: boolean) => { const state = useGame.getState(); - if (state.offline) { - throw new Error("Cannot set DNF in offline mode"); - } - - const player = state.players.find((player) => player.id === playerId); - if (!player) { - throw new Error("Player id not found"); + let player; + try { + player = state.players[playerIndex]; + } catch (error) { + throw new Error("Player not found"); } - if (dnf && state.dnf_player_ids.includes(playerId)) { + if (dnf && state.dnf_player_indexes.includes(playerIndex)) { return; } - let new_dnfs = [...state.dnf_player_ids]; + let new_dnfs = [...state.dnf_player_indexes]; if (dnf) { - if (state.dnf_player_ids.includes(playerId)) { + if (state.dnf_player_indexes.includes(playerIndex)) { return; } - new_dnfs.push(playerId); + new_dnfs.push(playerIndex); } if (!dnf) { - if (!state.dnf_player_ids.includes(playerId)) { + if (!state.dnf_player_indexes.includes(playerIndex)) { return; } - new_dnfs = state.dnf_player_ids.filter((id) => id !== playerId); + new_dnfs = state.dnf_player_indexes.filter( + (index) => index !== playerIndex, + ); } set({ - dnf_player_ids: new_dnfs, + dnf_player_indexes: new_dnfs, }); try { @@ -194,7 +194,7 @@ const useGame = create()( state.token as string, mapToRemote({ ...state, - dnf_player_ids: new_dnfs, + dnf_player_indexes: new_dnfs, }), ); } catch (error) { diff --git a/src/views/Game/components/DNFDialog.tsx b/src/views/Game/components/DNFDialog.tsx index f4586f9..04d2c5e 100644 --- a/src/views/Game/components/DNFDialog.tsx +++ b/src/views/Game/components/DNFDialog.tsx @@ -19,9 +19,9 @@ import useGame from "../../../stores/game"; interface DNFDialogProps extends DialogProps {} const DNFDialog: FunctionComponent = (props) => { - const { players, dnf_player_ids, SetPlayerDNF } = useGame((state) => ({ + const { players, dnf_player_indexes, SetPlayerDNF } = useGame((state) => ({ players: state.players, - dnf_player_ids: state.dnf_player_ids, + dnf_player_indexes: state.dnf_player_indexes, SetPlayerDNF: state.SetPlayerDNF, })); @@ -30,17 +30,13 @@ const DNFDialog: FunctionComponent = (props) => { const toggle = (index: number) => { sound.play("click"); - const player = players[index]; - - if (player.id === undefined) { - return; - } + const isDNF = dnf_player_indexes.includes(index); - const isDNF = dnf_player_ids.includes(player.id); + const player = players[index]; console.log("Setting DNF for player", player.id, !isDNF); - SetPlayerDNF(player.id, !isDNF); + SetPlayerDNF(index, !isDNF); }; return ( @@ -101,7 +97,7 @@ const DNFDialog: FunctionComponent = (props) => { {player.username} - {dnf_player_ids.includes(player.id || 0) && } + {dnf_player_indexes.includes(index || 0) && } ); })} diff --git a/src/views/Game/components/Header.tsx b/src/views/Game/components/Header.tsx index 3956a4a..da32379 100644 --- a/src/views/Game/components/Header.tsx +++ b/src/views/Game/components/Header.tsx @@ -214,24 +214,19 @@ const Header: FunctionComponent = () => { }, }} > - {!game.offline && ( - + setDNFDialogOpen(true)} > - setDNFDialogOpen(true)} - > - DNF - - - )} + DNF + + = ({ }) => { const theme = useTheme(); - const devices = useVideoDevices(); + const { devices } = useVideoDevices(); const [selectedDevice, setSelectedDevice] = useState( null, ); diff --git a/src/views/Game/components/PlayerItem.tsx b/src/views/Game/components/PlayerItem.tsx index 5a539e7..de87f98 100644 --- a/src/views/Game/components/PlayerItem.tsx +++ b/src/views/Game/components/PlayerItem.tsx @@ -44,12 +44,12 @@ const PlayerItem: FunctionComponent = (props) => { const gameMetrics = useGameMetrics(); const game = useGame((state) => ({ - dnf_player_ids: state.dnf_player_ids, + dnf_player_indexes: state.dnf_player_indexes, })); const isFirstRound = gameMetrics.currentRound === 1; - const isDNF = game.dnf_player_ids.includes(props.player.id || -1); + const isDNF = game.dnf_player_indexes.includes(props.index); const settings = useSettings((state) => ({ simpleCardsMode: state.simpleCardsMode, diff --git a/src/views/Login/New/contexts/newGame.tsx b/src/views/Login/New/contexts/newGame.tsx index 67784d9..1918614 100644 --- a/src/views/Login/New/contexts/newGame.tsx +++ b/src/views/Login/New/contexts/newGame.tsx @@ -77,8 +77,9 @@ export const NewGameProvider: React.FC = ({ if (offline) { setPlayers([ - ...players.map((player) => { + ...players.map((player, i) => { return { + id: i, username: player.username, ready: !!player.username, };