GameSlector split into thre sub components

This commit is contained in:
djmil 2023-11-15 18:10:44 +01:00
parent 3063146a76
commit 6343f70851
3 changed files with 117 additions and 21 deletions

View File

@ -3,7 +3,7 @@ import { GamesContext } from '../context/games';
import { NavLink, Routes, Route } from 'react-router-dom'; import { NavLink, Routes, Route } from 'react-router-dom';
import NewGame from './games/view/NewGame'; import NewGame from './games/view/NewGame';
import GameSelector from './games/view/GameSelector'; import { GameProposalSelector, ActiveGameSelector, GameArchiveSelector } from './games/view/GameSelector';
import Create from './games/action/Create'; import Create from './games/action/Create';
import Reject from './games/action/Reject'; import Reject from './games/action/Reject';
@ -58,30 +58,29 @@ function ViewSelector({ games }) {
} }
function ViewProvider({ gamesReducer, players }) { function ViewProvider({ gamesReducer, players }) {
const [games, dispatchGames] = gamesReducer; const [/*games*/, dispatchGames] = gamesReducer;
return ( return (
<div className='ViewProvider'> <div className='ViewProvider'>
<Routes> <Routes>
<Route path='new' element={ <Route path='new' element={
<NewGame <NewGame onSelectPlayer={(whitePlayer, blackPlayer) => dispatchGames({ type: 'nextNewGame', whitePlayer, blackPlayer })}
onSelectPlayer={(whitePlayer, blackPlayer) => dispatchGames({ type: 'nextNewGame', whitePlayer, blackPlayer })}
players={players} players={players}
/> />
} /> } />
<Route path='proposal' element={ <Route path='proposal' element={
<GameSelector <GameProposalSelector onSelect={(selectedUUID) => dispatchGames({ type: 'nextProposal', selectedUUID })} />
yours='GAME_PROPOSAL_WAIT_FOR_YOU'
opponents='GAME_PROPOSAL_WAIT_FOR_OPPONENT'
isSelected={(uuid) => uuid === games.proposal.selectedUUID}
onSelect={(selectedUUID) => dispatchGames({ type: 'nextProposal', selectedUUID })}
/>
} /> } />
<Route path='active' element={<GameSelector />} /> <Route path='active' element={
<Route path='archive' element={<GameSelector />} /> <ActiveGameSelector onSelect={(selectedUUID) => dispatchGames({ type: 'nextActive', selectedUUID })} />
} />
<Route path='archive' element={
<GameArchiveSelector onSelect={(selectedUUID) => dispatchGames({ type: 'nextArchive', selectedUUID })} />
} />
</Routes> </Routes>
</div> </div>
) )
@ -99,7 +98,7 @@ function ActionPanel({ players, gamesApi }) {
<Route path='proposal' element={[ <Route path='proposal' element={[
<Accept key={1} />, <Accept key={1} />,
<Reject key={2} />, <Reject key={2} />,
<Cancel key={3} onClick={({uuid}) => gamesApi.pushGameProposalCancel({ uuid })} /> <Cancel key={3} onClick={({ uuid }) => gamesApi.pushGameProposalCancel({ uuid })} />
]} /> ]} />
<Route path='active' element={[<DrawReq key={1} />, <DrawAcq key={2} />, <Surrender key={3} />]} /> <Route path='active' element={[<DrawReq key={1} />, <DrawAcq key={2} />, <Surrender key={3} />]} />
<Route path='archive' element={[<Backward key={1} />, <Forward key={2} />]} /> <Route path='archive' element={[<Backward key={1} />, <Forward key={2} />]} />

View File

@ -6,11 +6,13 @@ import { Color, Player } from '../../../components/Checkers';
import Loading from '../../../components/Loading'; import Loading from '../../../components/Loading';
import Counter from '../../../components/Counter'; import Counter from '../../../components/Counter';
export default function GameSelector({ yours, opponents, isSelected, onSelect }) { export function GameProposalSelector({ onSelect }) {
const gamesList = useContext(GamesContext).gamesList; const games = useContext(GamesContext);
if (gamesList === null) if (games.gamesList === null)
return <Loading /> return <Loading />
const isSelected = (uuid) => uuid === games.proposal.selectedUUID;
const onClick = (uuid) => { const onClick = (uuid) => {
if (isSelected(uuid)) if (isSelected(uuid))
onSelect(null); // deselect previously selected game onSelect(null); // deselect previously selected game
@ -18,21 +20,95 @@ export default function GameSelector({ yours, opponents, isSelected, onSelect })
onSelect(uuid); onSelect(uuid);
} }
const yoursList = gamesList.filter(game => game.status === yours) const yoursList = games.gamesList.filter(game => game.status === 'GAME_PROPOSAL_WAIT_FOR_YOU')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />) .map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const opponentsList = gamesList.filter(game => game.status === opponents) const opponentsList = games.gamesList.filter(game => game.status === 'GAME_PROPOSAL_WAIT_FOR_OPPONENT')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />) .map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
return ( return (
<div className='GameSelector'> <div className='GameSelector'>
{yoursList} {yoursList}
{opponentsList.length > 0 && <Separator counter={opponentsList.length} />} {opponentsList.length > 0 && <Separator counter={opponentsList.length}>waiting for opponent</Separator>}
{opponentsList} {opponentsList}
</div> </div>
) )
} }
export function ActiveGameSelector({ onSelect }) {
const games = useContext(GamesContext);
if (games.gamesList === null)
return <Loading />
const isSelected = (uuid) => uuid === games.proposal.selectedUUID;
const onClick = (uuid) => {
if (isSelected(uuid))
onSelect(null); // deselect previously selected game
else
onSelect(uuid);
}
const yoursList = games.gamesList.filter(game => game.status === 'GAME_BOARD_WAIT_FOR_YOU')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const opponentsList = games.gamesList.filter(game => game.status === 'GAME_BOARD_WAIT_FOR_OPPONENT')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
return (
<div className='GameSelector'>
{yoursList}
{opponentsList.length > 0 && <Separator counter={opponentsList.length}>waiting for opponent</Separator>}
{opponentsList}
</div>
)
}
export function GameArchiveSelector({ onSelect }) {
const games = useContext(GamesContext);
if (games.gamesList === null)
return <Loading />
const isSelected = (uuid) => uuid === games.archive.selectedUUID;
const onClick = (uuid) => {
if (isSelected(uuid))
onSelect(null); // deselect previously selected game
else
onSelect(uuid);
}
const rejectedList = games.gamesList.filter(game => game.status === 'GAME_PROPOSAL_REJECTED')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const canceledList = games.gamesList.filter(game => game.status === 'GAME_PROPOSAL_CANCELED')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const victoryList = games.gamesList.filter(game => game.status === 'GAME_RESULT_YOU_WON')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const defeatList = games.gamesList.filter(game => game.status === 'GAME_RESULT_YOU_LOOSE')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
const drawList = games.gamesList.filter(game => game.status === 'GAME_RESULT_DRAW')
.map(game => <Selectable game={game} key={game.uuid} selected={isSelected(game.uuid)} onClick={onClick} />)
return (
<div className='GameSelector'>
{rejectedList.length > 0 && <Separator counter={rejectedList.length}>rejected proposals</Separator>}
{rejectedList}
{canceledList.length > 0 && <Separator counter={canceledList.length}>canceled proposals</Separator>}
{canceledList}
{victoryList.length > 0 && <Separator counter={victoryList.length}>victory</Separator>}
{victoryList}
{defeatList.length > 0 && <Separator counter={defeatList.length}>defeat</Separator>}
{defeatList}
{drawList.length > 0 && <Separator counter={drawList.length}>draw</Separator>}
{drawList}
</div>
)
}
function Selectable({ game, selected, onClick }) { function Selectable({ game, selected, onClick }) {
const myColor = game.myColor; const myColor = game.myColor;
const opponentColor = Color.opposite(myColor); const opponentColor = Color.opposite(myColor);
@ -54,10 +130,10 @@ function Selectable({ game, selected, onClick }) {
) )
}; };
function Separator({ counter }) { function Separator({ counter, children }) {
return ( return (
<div className='Separator'> <div className='Separator'>
waiting for opponent {children}
<Counter number={counter} /> <Counter number={counter} />
</div> </div>
) )

View File

@ -15,6 +15,15 @@ export const gamesInitialState = {
message2opponent: '', message2opponent: '',
}, },
active: {
selectedUUID: null,
message2opponent: '',
},
archive: {
selectedUUID: null,
},
// Network // Network
isPollingGamesList: false, isPollingGamesList: false,
isPushingNewGame: false, isPushingNewGame: false,
@ -42,6 +51,18 @@ function reducer(state, action) {
proposal: nextState(state.proposal, action) proposal: nextState(state.proposal, action)
}; };
case 'nextActive':
return {
...state,
proposal: nextState(state.proposal, action)
};
case 'nextArchive':
return {
...state,
proposal: nextState(state.proposal, action)
};
default: default:
throw Error('GamesReducer: unknown action.type', action.type); throw Error('GamesReducer: unknown action.type', action.type);
} }