Game Draw: req/acq/rej
This commit is contained in:
parent
576556afe7
commit
671e13a41d
@ -50,4 +50,46 @@ public class GameController {
|
|||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.ok(finishedGame);
|
.ok(finishedGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{uuid}/drawreq")
|
||||||
|
public ResponseEntity<GameView> drawRequest(
|
||||||
|
@AuthenticationPrincipal User issuer,
|
||||||
|
@PathVariable UUID uuid
|
||||||
|
) {
|
||||||
|
final GameView drawReqGame = cordaClient.gameDrawRequest(
|
||||||
|
issuer.getHoldingIdentity(),
|
||||||
|
uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok(drawReqGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{uuid}/drawacc")
|
||||||
|
public ResponseEntity<GameView> drawAccept(
|
||||||
|
@AuthenticationPrincipal User issuer,
|
||||||
|
@PathVariable UUID uuid
|
||||||
|
) {
|
||||||
|
final GameView drawAccGame = cordaClient.gameDrawAccept(
|
||||||
|
issuer.getHoldingIdentity(),
|
||||||
|
uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok(drawAccGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{uuid}/drawrej")
|
||||||
|
public ResponseEntity<GameView> drawReject(
|
||||||
|
@AuthenticationPrincipal User issuer,
|
||||||
|
@PathVariable UUID uuid
|
||||||
|
) {
|
||||||
|
final GameView drawRejGame = cordaClient.gameDrawReject(
|
||||||
|
issuer.getHoldingIdentity(),
|
||||||
|
uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok(drawRejGame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,29 @@ export default function useGamesApi(gamesReducer, config) {
|
|||||||
onSuccess: (acceptedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(acceptedGame), proposal: gamesInitialState.proposal })
|
onSuccess: (acceptedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(acceptedGame), proposal: gamesInitialState.proposal })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameSurrender: ({ uuid }) => ifNot(games.isPushingActiveGameSurrender) &&
|
pushGameSurrender: ({ uuid }) => ifNot(games.isPushingGameSurrender) &&
|
||||||
doPushing(`/api/game/${uuid}/surrender`, 'PUT', null, {
|
doPushing(`/api/game/${uuid}/surrender`, 'PUT', null, {
|
||||||
onPushing: (isPushingActiveGameSurrender) => dispatchGames({ type: 'next', isPushingActiveGameSurrender }),
|
onPushing: (isPushingGameSurrender) => dispatchGames({ type: 'next', isPushingGameSurrender }),
|
||||||
onSuccess: (finishedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(finishedGame), proposal: gamesInitialState.active })
|
onSuccess: (finishedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(finishedGame), proposal: gamesInitialState.active })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
pushGameDrawRequest: ({ uuid }) => ifNot(games.isPushingGameDrawRequest) &&
|
||||||
|
doPushing(`/api/game/${uuid}/drawreq`, 'PUT', null, {
|
||||||
|
onPushing: (isPushingGameDrawRequest) => dispatchGames({ type: 'next', isPushingGameDrawRequest }),
|
||||||
|
onSuccess: (drawReqGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawReqGame), proposal: gamesInitialState.active })
|
||||||
|
}),
|
||||||
|
|
||||||
|
pushGameDrawAccept: ({ uuid }) => ifNot(games.isPushingGameDrawAccept) &&
|
||||||
|
doPushing(`/api/game/${uuid}/drawacc`, 'PUT', null, {
|
||||||
|
onPushing: (isPushingGameDrawAccept) => dispatchGames({ type: 'next', isPushingGameDrawAccept }),
|
||||||
|
onSuccess: (drawAccGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawAccGame), proposal: gamesInitialState.active })
|
||||||
|
}),
|
||||||
|
|
||||||
|
pushGameDrawReject: ({ uuid }) => ifNot(games.isPushingGameDrawReject) &&
|
||||||
|
doPushing(`/api/game/${uuid}/drawrej`, 'PUT', null, {
|
||||||
|
onPushing: (isPushingGameDrawReject) => dispatchGames({ type: 'next', isPushingGameDrawReject }),
|
||||||
|
onSuccess: (drawRejGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawRejGame), proposal: gamesInitialState.active })
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,3 +146,36 @@
|
|||||||
.ActionPanel .Accept.ready:active {
|
.ActionPanel .Accept.ready:active {
|
||||||
background-color:#00af00a0;
|
background-color:#00af00a0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw
|
||||||
|
*/
|
||||||
|
.ActionPanel .Draw.ready,
|
||||||
|
.ActionPanel .Draw.accept,
|
||||||
|
.ActionPanel .Draw.reject {
|
||||||
|
background-color: #ffff0018;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.ready:hover {
|
||||||
|
background-color:#ffff0040;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.ready:active {
|
||||||
|
background-color:#ffff00a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.accept:hover {
|
||||||
|
background-color:#a4ff4a50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.accept:active {
|
||||||
|
background-color:#10ff0080;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.reject:hover {
|
||||||
|
background-color:#ffaaaa60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ActionPanel .Draw.reject:active {
|
||||||
|
background-color:#ff000090;
|
||||||
|
}
|
@ -9,9 +9,8 @@ import Create from './games/action/Create';
|
|||||||
import Reject from './games/action/Reject';
|
import Reject from './games/action/Reject';
|
||||||
import Cancel from './games/action/Cancel';
|
import Cancel from './games/action/Cancel';
|
||||||
import Accept from './games/action/Accept';
|
import Accept from './games/action/Accept';
|
||||||
import DrawReq from './games/action/DrawReq';
|
|
||||||
import DrawAcq from './games/action/DrawAcq';
|
|
||||||
import Surrender from './games/action/Surrender';
|
import Surrender from './games/action/Surrender';
|
||||||
|
import { DrawRequest, DrawAccept, DrawReject } from './games/action/Draw';
|
||||||
import Backward from './games/action/Backward';
|
import Backward from './games/action/Backward';
|
||||||
import Forward from './games/action/Forward';
|
import Forward from './games/action/Forward';
|
||||||
|
|
||||||
@ -27,18 +26,19 @@ export default function Games({ context: { gamesReducer, gamesApi }, players })
|
|||||||
return (
|
return (
|
||||||
<GamesContext.Provider value={games} >
|
<GamesContext.Provider value={games} >
|
||||||
<div className='Games'>
|
<div className='Games'>
|
||||||
|
|
||||||
<div className='left-side'>
|
<div className='left-side'>
|
||||||
<ViewSelector games={games} />
|
<ViewSelector games={games} />
|
||||||
<ViewProvider gamesReducer={gamesReducer} players={players} />
|
<ViewProvider gamesReducer={gamesReducer} players={players} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='right-side'>
|
<div className='right-side'>
|
||||||
<ActionPanel gamesApi={gamesApi} players={players} />
|
<ActionPanel gamesApi={gamesApi} players={players} />
|
||||||
|
{/* <GameMessage /> */}
|
||||||
<GameBoard />
|
<GameBoard />
|
||||||
<Message2Opponent dispatchGames={dispatchGames} />
|
<Message2Opponent dispatchGames={dispatchGames} />
|
||||||
{/*
|
|
||||||
<GameMessage />
|
|
||||||
*/}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div >
|
</div >
|
||||||
</GamesContext.Provider>
|
</GamesContext.Provider>
|
||||||
)
|
)
|
||||||
@ -81,6 +81,7 @@ function ViewProvider({ gamesReducer, players }) {
|
|||||||
<Route path='archive' element={
|
<Route path='archive' element={
|
||||||
<GameArchiveSelector onSelect={(selectedUUID) => dispatchGames({ type: 'nextArchive', selectedUUID })} />
|
<GameArchiveSelector onSelect={(selectedUUID) => dispatchGames({ type: 'nextArchive', selectedUUID })} />
|
||||||
} />
|
} />
|
||||||
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -90,22 +91,31 @@ function ActionPanel({ players, gamesApi }) {
|
|||||||
return (
|
return (
|
||||||
<div className='ActionPanel'>
|
<div className='ActionPanel'>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
|
||||||
<Route path='new' element={
|
<Route path='new' element={
|
||||||
<Create isCurrentUser={players.isCurrentUser}
|
<Create isCurrentUser={players.isCurrentUser}
|
||||||
onClick={(reqParams) => gamesApi.pushNewGame(reqParams)}
|
onClick={(reqParams) => gamesApi.pushNewGame(reqParams)}
|
||||||
/>
|
/>
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route path='proposal' element={[
|
<Route path='proposal' element={[
|
||||||
<Accept key={1} onClick={(uuid) => gamesApi.pushGameProposalAccept({ uuid })} />,
|
<Accept key={1} onClick={(uuid) => gamesApi.pushGameProposalAccept({ uuid })} />,
|
||||||
<Reject key={2} onClick={(uuid) => gamesApi.pushGameProposalReject({ uuid })} />,
|
<Reject key={2} onClick={(uuid) => gamesApi.pushGameProposalReject({ uuid })} />,
|
||||||
<Cancel key={3} onClick={(uuid) => gamesApi.pushGameProposalCancel({ uuid })} />
|
<Cancel key={3} onClick={(uuid) => gamesApi.pushGameProposalCancel({ uuid })} />
|
||||||
]} />
|
]} />
|
||||||
|
|
||||||
<Route path='active' element={[
|
<Route path='active' element={[
|
||||||
<DrawReq key={1} />,
|
<DrawRequest key={1} onClick={(uuid) => gamesApi.pushGameDrawRequest({ uuid })} />,
|
||||||
<DrawAcq key={2} />,
|
<DrawAccept key={2} onClick={(uuid) => gamesApi.pushGameDrawAccept({ uuid })} />,
|
||||||
<Surrender key={3} onClick={(uuid) => gamesApi.pushGameSurrender({ uuid })}/>
|
<DrawReject key={3} onClick={(uuid) => gamesApi.pushGameDrawReject({ uuid })} />,
|
||||||
|
<Surrender key={4} onClick={(uuid) => gamesApi.pushGameSurrender({ uuid })} />
|
||||||
]} />
|
]} />
|
||||||
<Route path='archive' element={[<Backward key={1} />, <Forward key={2} />]} />
|
|
||||||
|
<Route path='archive' element={[
|
||||||
|
<Backward key={1} />,
|
||||||
|
<Forward key={2} />
|
||||||
|
]} />
|
||||||
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -127,7 +137,7 @@ function countGames(gamesList) {
|
|||||||
awaiting.proposals++;
|
awaiting.proposals++;
|
||||||
break;
|
break;
|
||||||
case 'GAME_BOARD_WAIT_FOR_YOU':
|
case 'GAME_BOARD_WAIT_FOR_YOU':
|
||||||
case 'DRAW_REQUEST_WAIT_FOR_YO':
|
case 'DRAW_REQUEST_WAIT_FOR_YOU':
|
||||||
awaiting.active++;
|
awaiting.active++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -56,7 +56,7 @@ export default function Message2Opponent({ dispatchGames }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<input className='Message2Opponent'
|
<input className='Message2Opponent'
|
||||||
placeholder='Message to opponent'
|
placeholder='Message'
|
||||||
value={value}
|
value={value}
|
||||||
maxLength={150}
|
maxLength={150}
|
||||||
onChange={e => update(e.target.value)}
|
onChange={e => update(e.target.value)}
|
||||||
|
60
webapp/src/container/games/action/Draw.jsx
Normal file
60
webapp/src/container/games/action/Draw.jsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import Wobler from '../../../components/Wobler';
|
||||||
|
import { GamesContext } from '../../../context/games';
|
||||||
|
|
||||||
|
export function DrawRequest({ onClick }) {
|
||||||
|
const games = useContext(GamesContext);
|
||||||
|
|
||||||
|
const selectedGame = games.findGame({ uuid: games.active.selectedUUID });
|
||||||
|
const gameStatus = selectedGame?.status;
|
||||||
|
const isReady = gameStatus === 'GAME_BOARD_WAIT_FOR_YOU' ? true : '';
|
||||||
|
|
||||||
|
const checkStatus = () => {
|
||||||
|
if (!selectedGame)
|
||||||
|
return alert('You have to select a game');
|
||||||
|
|
||||||
|
if (gameStatus === 'DRAW_REQUEST_WAIT_FOR_OPPONENT')
|
||||||
|
return alert('A draw was alredy offered to the opponent');
|
||||||
|
|
||||||
|
if (!isReady)
|
||||||
|
return alert('You can ask for a draw only during your turn');
|
||||||
|
|
||||||
|
onClick(selectedGame.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameStatus === 'DRAW_REQUEST_WAIT_FOR_YOU')
|
||||||
|
return; // You can not send counter draw request
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button className={'Draw' + (isReady && ' ready')} onClick={() => checkStatus()} >
|
||||||
|
<Wobler text="Draw?" dance={games.isPushingGameDrawRequest} />
|
||||||
|
</button >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DrawAccept({ onClick }) {
|
||||||
|
const games = useContext(GamesContext);
|
||||||
|
|
||||||
|
const selectedGame = games.findGame({ uuid: games.active.selectedUUID });
|
||||||
|
const gameStatus = selectedGame?.status;
|
||||||
|
|
||||||
|
if (gameStatus === 'DRAW_REQUEST_WAIT_FOR_YOU')
|
||||||
|
return (
|
||||||
|
<button className='Draw accept' onClick={() => onClick(selectedGame.uuid)} >
|
||||||
|
<Wobler text="Draw accept" dance={games.isPushingGameDrawAccept} />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DrawReject({ onClick }) {
|
||||||
|
const games = useContext(GamesContext);
|
||||||
|
|
||||||
|
const selectedGame = games.findGame({ uuid: games.active.selectedUUID });
|
||||||
|
|
||||||
|
if (selectedGame?.status === 'DRAW_REQUEST_WAIT_FOR_YOU')
|
||||||
|
return (
|
||||||
|
<button className='Draw reject' onClick={() => onClick(selectedGame.uuid)} >
|
||||||
|
<Wobler text="Reject" dance={games.isPushingGameDrawReject} />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
@ -1,6 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default function DrawAcq() {
|
|
||||||
|
|
||||||
return <button className='DrawAcq'>Draw accept</button>
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default function DrawReq() {
|
|
||||||
|
|
||||||
return <button className='DrawReq'>Draw request</button>
|
|
||||||
}
|
|
@ -14,9 +14,9 @@ export default function Surrender({ onClick }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<button className={'Surrender' + (isReady && ' ready')}
|
<button className={'Surrender' + (isReady && ' ready')}
|
||||||
onClick={() => isReady ? onClick(selectedGame.uuid) : alert('You have to select some game')}
|
onClick={() => isReady ? onClick(selectedGame.uuid) : alert('You have to select a game')}
|
||||||
>
|
>
|
||||||
<Wobler text="Surrender" dance={games.isPushingActiveGameSurrender} />
|
<Wobler text="Surrender" dance={games.isPushingGameSurrender} />
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -49,10 +49,10 @@ export function ActiveGameSelector({ onSelect }) {
|
|||||||
onSelect(uuid);
|
onSelect(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
const yoursList = games.gamesList.filter(game => game.status === 'GAME_BOARD_WAIT_FOR_YOU')
|
const yoursList = games.gamesList.filter(game => (game.status === 'GAME_BOARD_WAIT_FOR_YOU' || game.status === 'DRAW_REQUEST_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 = games.gamesList.filter(game => game.status === 'GAME_BOARD_WAIT_FOR_OPPONENT')
|
const opponentsList = games.gamesList.filter(game => (game.status === 'GAME_BOARD_WAIT_FOR_OPPONENT' || game.status === 'DRAW_REQUEST_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 (
|
||||||
|
@ -27,10 +27,15 @@ export const gamesInitialState = {
|
|||||||
// Network
|
// Network
|
||||||
isPollingGamesList: false,
|
isPollingGamesList: false,
|
||||||
isPushingNewGame: false,
|
isPushingNewGame: false,
|
||||||
|
|
||||||
isPushingGameProposalCancel: false,
|
isPushingGameProposalCancel: false,
|
||||||
isPushingGameProposalReject: false,
|
isPushingGameProposalReject: false,
|
||||||
isPushingGameProposalAccept: false,
|
isPushingGameProposalAccept: false,
|
||||||
isPushingActiveGameSurrender: false,
|
|
||||||
|
isPushingGameSurrender: false,
|
||||||
|
isPushingGameDrawRequest: false,
|
||||||
|
isPushingGameDrawAccept: false,
|
||||||
|
isPushingGameDrawReject: false,
|
||||||
|
|
||||||
findGame,
|
findGame,
|
||||||
nextGameList,
|
nextGameList,
|
||||||
|
Loading…
Reference in New Issue
Block a user