Skip to content

Commit

Permalink
rework log/start/next
Browse files Browse the repository at this point in the history
  • Loading branch information
JessicaMulein committed Oct 22, 2024
1 parent d720526 commit 412f6c4
Show file tree
Hide file tree
Showing 23 changed files with 220 additions and 175 deletions.
2 changes: 1 addition & 1 deletion src/__fixtures__/dominion-lib-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function createMockGame(playerCount: number, overrides?: Partial<IGame>):
{
id: faker.string.uuid(),
timestamp: new Date(),
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
},
],
Expand Down
4 changes: 1 addition & 3 deletions src/components/DominionAssistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ const DominionAssistant: React.FC<DominionAssistantProps> = ({ route, navigation
const nextTurn = () => {
setGameState((prevGame) => {
const nextPlayerIndex = getNextPlayerIndex(prevGame);
addLogEntry(prevGame, NO_PLAYER, GameLogActionWithCount.NEXT_TURN, {
addLogEntry(prevGame, nextPlayerIndex, GameLogActionWithCount.NEXT_TURN, {
playerTurnDetails: gameState.players.map((player) => player.turn),
prevPlayerIndex: gameState.currentPlayerIndex,
newPlayerIndex: nextPlayerIndex,
});
const updatedGame = incrementTurnCountersAndPlayerIndices(prevGame);
return resetPlayerTurnCounters(updatedGame);
Expand All @@ -81,7 +80,6 @@ const DominionAssistant: React.FC<DominionAssistantProps> = ({ route, navigation
setGameState((prevState) => {
addLogEntry(prevState, NO_PLAYER, GameLogActionWithCount.END_GAME, {
prevPlayerIndex: gameState.currentPlayerIndex,
newPlayerIndex: NO_PLAYER,
});

return {
Expand Down
81 changes: 45 additions & 36 deletions src/components/GameLogEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
Button,
Box,
} from '@mui/material';
import TurnIcon from '@mui/icons-material/TurnedIn'; // Example icon for new turn
import EditIcon from '@mui/icons-material/Edit'; // Icon for corrections
import LinkIcon from '@mui/icons-material/Link';
import UndoIcon from '@mui/icons-material/Undo';
Expand Down Expand Up @@ -61,16 +60,14 @@ const GameLogEntry: React.FC<GameLogEntryProps> = ({ logIndex, entry, isCurrentP
};

const actionText = logEntryToString(entry);
const playerName =
entry.playerIndex !== undefined && gameState.players[entry.playerIndex]
? gameState.players[entry.playerIndex].name
: '';

const relevantPlayer = entry.playerIndex > -1 ? gameState.players[entry.playerIndex] : undefined;
const isActivePlayer = entry.playerIndex === gameState.currentPlayerIndex;
const isNewTurn = entry.action === GameLogActionWithCount.NEXT_TURN;
const isAttributeChange = AdjustmentActions.includes(entry.action);
const isAttributeChangeOutOfTurn = isAttributeChange && !isActivePlayer;

if (entry.playerIndex !== undefined && !gameState.players[entry.playerIndex]) {
if (entry.playerIndex > -1 && !gameState.players[entry.playerIndex]) {
console.warn(`Player not found for index ${entry.playerIndex}`, {
entry,
gamePlayersLength: gameState.players.length,
Expand All @@ -95,52 +92,64 @@ const GameLogEntry: React.FC<GameLogEntryProps> = ({ logIndex, entry, isCurrentP
</TableCell>
<TableCell style={{ width: '60%' }}>
<Box display="flex" alignItems="center">
{playerName && (
{relevantPlayer && (
<Chip
label={playerName.charAt(0).toUpperCase()}
label={relevantPlayer.name.charAt(0).toUpperCase()}
size="small"
icon={isNewTurn ? <TurnIcon /> : undefined}
style={{
backgroundColor:
entry.playerIndex !== undefined
? gameState.players[entry.playerIndex].color
: 'gray',
backgroundColor: relevantPlayer !== undefined ? relevantPlayer.color : 'gray',
color: 'white',
marginRight: '8px',
fontWeight: isActivePlayer ? 'bold' : 'normal',
border: isActivePlayer ? '2px solid #000' : 'none',
}}
/>
)}
<Typography
variant="body2"
component="span"
style={{
fontWeight: isCurrentPlayer ? 'bold' : 'normal',
color: isCurrentPlayer ? '#1976d2' : 'inherit',
}}
>
{actionText}
</Typography>
{isAttributeChangeOutOfTurn && (
<ChangeCircleIcon
fontSize="small"
style={{ marginLeft: '8px', color: '#ff9800' }}
titleAccess="Attribute changed outside of player's turn"
/>
)}
{entry.correction && (
<Tooltip title="Correction" arrow>
<EditIcon fontSize="small" style={{ marginLeft: '8px', color: '#ff9800' }} />
</Tooltip>
)}
<Box display="flex" alignItems="center" flexGrow={1}>
{relevantPlayer !== undefined && (
<Typography
component="span"
sx={{
color: relevantPlayer.color,
fontWeight: 'bold',
marginRight: '4px',
}}
>
&lt;{relevantPlayer.name}&gt;:
</Typography>
)}
<Typography
variant="body2"
component="span"
style={{
fontWeight: isCurrentPlayer ? 'bold' : 'normal',
color: isCurrentPlayer ? '#1976d2' : 'inherit',
}}
>
{actionText}
</Typography>
{isAttributeChangeOutOfTurn && (
<ChangeCircleIcon
fontSize="small"
style={{ marginLeft: '8px', color: '#ff9800' }}
titleAccess="Attribute changed outside of player's turn"
/>
)}
{entry.correction && (
<Tooltip title="This entry was a correction" arrow>
<EditIcon fontSize="small" style={{ marginLeft: '8px', color: '#ff9800' }} />
</Tooltip>
)}
</Box>
</Box>
</TableCell>
<TableCell style={{ width: '10%', textAlign: 'right' }}>
{entry.linkedActionId && <LinkIcon fontSize="small" color="action" />}
{canUndoAction(gameState, logIndex) && (
<IconButton onClick={handleUndoClick} size="small">
<UndoIcon fontSize="small" />
<Tooltip title="Undo this entry">
<UndoIcon fontSize="small" />
</Tooltip>
</IconButton>
)}
</TableCell>
Expand Down
10 changes: 7 additions & 3 deletions src/components/GameScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Box, Button, Dialog, DialogContent, Fab, styled } from '@mui/material';
import { Box, Button, Dialog, DialogContent, Fab, styled, Tooltip } from '@mui/material';
import UndoIcon from '@mui/icons-material/Undo';
import InventoryIcon from '@mui/icons-material/Inventory';
import Scoreboard from '@/components/Scoreboard';
Expand Down Expand Up @@ -72,10 +72,14 @@ const GameScreen: React.FC<GameScreenProps> = ({ nextTurn, endGame, undoLastActi
</Container>
<FabContainer>
<Fab color="secondary" aria-label="undo" onClick={undoLastAction} disabled={!canUndo}>
<UndoIcon />
<Tooltip title="Undo the most recent update">
<UndoIcon />
</Tooltip>
</Fab>
<Fab color="primary" aria-label="supply" onClick={handleOpenSupplyDialog}>
<InventoryIcon />
<Tooltip title="Show victory kingdom card supply counts">
<InventoryIcon />
</Tooltip>
</Fab>
</FabContainer>
<Dialog open={supplyDialogOpen} onClose={handleCloseSupplyDialog}>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ const Player: React.FC = () => {
onChange={handleCorrectionChange}
inputProps={{ 'aria-label': 'Correction Checkbox' }}
/>
<Typography variant="body2">Correction</Typography>
<Tooltip title="Use to reverse accidental changes. They will be marked as corrections in the log.">
<Typography variant="body2">Correction</Typography>
</Tooltip>
</CorrectionCheckboxContainer>
{player && (
<Box display="flex" flexWrap="wrap">
Expand Down
3 changes: 1 addition & 2 deletions src/components/Scoreboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ const Scoreboard: React.FC = () => {

const handlePlayerSelect = (index: number) => {
setGameState((prevState) => {
addLogEntry(prevState, NO_PLAYER, GameLogActionWithCount.SELECT_PLAYER, {
addLogEntry(prevState, index, GameLogActionWithCount.SELECT_PLAYER, {
prevPlayerIndex: prevState.selectedPlayerIndex,
newPlayerIndex: index,
});
return { ...prevState, selectedPlayerIndex: index };
});
Expand Down
2 changes: 1 addition & 1 deletion src/game/__tests__/dominion-lib-NewGameState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('NewGameState', () => {
id: expect.any(String),
timestamp: expect.any(Date),
action: GameLogActionWithCount.START_GAME,
playerIndex: -1,
playerIndex: initialGameState.firstPlayerIndex,
} as ILogEntry,
]);
expect(result.supply).toBeDefined();
Expand Down
4 changes: 2 additions & 2 deletions src/game/__tests__/dominion-lib-load-save-loadGame.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('loadGame', () => {
id: id,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
playerIndex: NO_PLAYER,
playerIndex: 0,
},
],
});
Expand All @@ -87,7 +87,7 @@ describe('loadGame', () => {
id: faker.string.uuid(),
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
playerIndex: NO_PLAYER,
playerIndex: 0,
},
{
id: saveGameLogId,
Expand Down
10 changes: 5 additions & 5 deletions src/game/__tests__/dominion-lib-load-save-loadGameAddLog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('loadGameAddLog', () => {
log: [
{
id: 'start',
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
} as ILogEntry,
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('loadGameAddLog', () => {
log: [
{
id: 'start',
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
} as ILogEntry,
Expand All @@ -67,7 +67,7 @@ describe('loadGameAddLog', () => {
log: [
{
id: 'start',
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
} as ILogEntry,
Expand Down Expand Up @@ -107,7 +107,7 @@ describe('loadGameAddLog', () => {
log: [
{
id: 'start',
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
} as ILogEntry,
Expand Down Expand Up @@ -139,7 +139,7 @@ describe('loadGameAddLog', () => {
log: [
{
id: 'start',
playerIndex: NO_PLAYER,
playerIndex: 0,
action: GameLogActionWithCount.START_GAME,
timestamp: new Date(),
} as ILogEntry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ describe('restoreSavedGame', () => {
action: GameLogActionWithCount.SAVE_GAME,
timestamp: saveGameTime.toISOString(),
playerIndex: NO_PLAYER,
playerName: 'player1',
};

// Assuming `createMockGameRaw` returns an IGameRaw object with string timestamps
Expand Down
Loading

0 comments on commit 412f6c4

Please sign in to comment.