Game: surrender
This commit is contained in:
parent
cacc8c99d8
commit
576556afe7
@ -1,11 +1,14 @@
|
|||||||
package djmil.cordacheckers.api;
|
package djmil.cordacheckers.api;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -16,8 +19,8 @@ import djmil.cordacheckers.user.User;
|
|||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/games")
|
@RequestMapping("api/game")
|
||||||
public class GameStateController {
|
public class GameController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CordaClient cordaClient;
|
CordaClient cordaClient;
|
||||||
@ -26,7 +29,7 @@ public class GameStateController {
|
|||||||
HoldingIdentityResolver holdingIdentityResolver;
|
HoldingIdentityResolver holdingIdentityResolver;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseEntity<List<GameView>> gameStateList(
|
public ResponseEntity<List<GameView>> list(
|
||||||
@AuthenticationPrincipal User player
|
@AuthenticationPrincipal User player
|
||||||
) {
|
) {
|
||||||
final List<GameView> gsList = cordaClient.gameStateList(player.getHoldingIdentity());
|
final List<GameView> gsList = cordaClient.gameStateList(player.getHoldingIdentity());
|
||||||
@ -34,4 +37,17 @@ public class GameStateController {
|
|||||||
return ResponseEntity.ok(gsList);
|
return ResponseEntity.ok(gsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{uuid}/surrender")
|
||||||
|
public ResponseEntity<GameView> surrender(
|
||||||
|
@AuthenticationPrincipal User issuer,
|
||||||
|
@PathVariable UUID uuid
|
||||||
|
) {
|
||||||
|
final GameView finishedGame = cordaClient.gameBoardSurrender(
|
||||||
|
issuer.getHoldingIdentity(),
|
||||||
|
uuid
|
||||||
|
);
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.ok(finishedGame);
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ export default function useGamesApi(gamesReducer, config) {
|
|||||||
dispatchGames({ type: 'next', gamesList });
|
dispatchGames({ type: 'next', gamesList });
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPollingGamesList = usePolling('/api/games', onSuccess, config.intervalMode(30));
|
const isPollingGamesList = usePolling('/api/game', onSuccess, config.intervalMode(30));
|
||||||
if (games.isPollingGamesList !== isPollingGamesList) {
|
if (games.isPollingGamesList !== isPollingGamesList) {
|
||||||
dispatchGames({ type: 'next', isPollingGamesList });
|
dispatchGames({ type: 'next', isPollingGamesList });
|
||||||
}
|
}
|
||||||
@ -43,6 +43,12 @@ export default function useGamesApi(gamesReducer, config) {
|
|||||||
onPushing: (isPushingGameProposalAccept) => dispatchGames({ type: 'next', isPushingGameProposalAccept }),
|
onPushing: (isPushingGameProposalAccept) => dispatchGames({ type: 'next', isPushingGameProposalAccept }),
|
||||||
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) &&
|
||||||
|
doPushing(`/api/game/${uuid}/surrender`, 'PUT', null, {
|
||||||
|
onPushing: (isPushingActiveGameSurrender) => dispatchGames({ type: 'next', isPushingActiveGameSurrender }),
|
||||||
|
onSuccess: (finishedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(finishedGame), proposal: gamesInitialState.active })
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
margin: 2px;
|
margin: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ActionPanel .Create.ready { /* , */ /* OR .game-action.busy */
|
.ActionPanel .Create.ready {
|
||||||
background-color:#00b0ff30;
|
background-color:#00b0ff30;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,17 +115,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ActionPanel .Cancel.ready,
|
.ActionPanel .Cancel.ready,
|
||||||
.ActionPanel .Reject.ready {
|
.ActionPanel .Reject.ready,
|
||||||
|
.ActionPanel .Surrender.ready
|
||||||
|
{
|
||||||
background-color:#ffaaaa60
|
background-color:#ffaaaa60
|
||||||
}
|
}
|
||||||
|
|
||||||
.ActionPanel .Cancel.ready:hover,
|
.ActionPanel .Cancel.ready:hover,
|
||||||
.ActionPanel .Reject.ready:hover {
|
.ActionPanel .Reject.ready:hover,
|
||||||
|
.ActionPanel .Surrender.ready:hover
|
||||||
|
{
|
||||||
background-color:#ff000060
|
background-color:#ff000060
|
||||||
}
|
}
|
||||||
|
|
||||||
.ActionPanel .Cancel.ready:active,
|
.ActionPanel .Cancel.ready:active,
|
||||||
.ActionPanel .Reject.ready:active {
|
.ActionPanel .Reject.ready:active,
|
||||||
|
.ActionPanel .Surrender.ready:active
|
||||||
|
{
|
||||||
background-color:#ff0000a0
|
background-color:#ff0000a0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +96,15 @@ function ActionPanel({ players, gamesApi }) {
|
|||||||
/>
|
/>
|
||||||
} />
|
} />
|
||||||
<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={[<DrawReq key={1} />, <DrawAcq key={2} />, <Surrender key={3} />]} />
|
<Route path='active' element={[
|
||||||
|
<DrawReq key={1} />,
|
||||||
|
<DrawAcq key={2} />,
|
||||||
|
<Surrender key={3} 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>
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
import Wobler from '../../../components/Wobler';
|
||||||
|
import { GamesContext } from '../../../context/games';
|
||||||
|
|
||||||
export default function Surrender() {
|
export default function Surrender({ onClick }) {
|
||||||
|
const games = useContext(GamesContext);
|
||||||
|
|
||||||
return <button className='Surrender'>Surrender</button>
|
const selectedGame = games.findGame({ uuid: games.active.selectedUUID });
|
||||||
|
const gameStatus = selectedGame?.status;
|
||||||
|
const isReady = (gameStatus === 'GAME_BOARD_WAIT_FOR_OPPONENT' || gameStatus === 'GAME_BOARD_WAIT_FOR_YOU') ? true : '';
|
||||||
|
|
||||||
|
if (gameStatus === 'DRAW_REQUEST_WAIT_FOR_YOU' || gameStatus === 'DRAW_REQUEST_WAIT_FOR_OPPONENT')
|
||||||
|
return; // You shall not surrender if there is an active tie negotiations
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button className={'Surrender' + (isReady && ' ready')}
|
||||||
|
onClick={() => isReady ? onClick(selectedGame.uuid) : alert('You have to select some game')}
|
||||||
|
>
|
||||||
|
<Wobler text="Surrender" dance={games.isPushingActiveGameSurrender} />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
}
|
}
|
@ -40,7 +40,7 @@ export function ActiveGameSelector({ onSelect }) {
|
|||||||
if (games.gamesList === null)
|
if (games.gamesList === null)
|
||||||
return <Loading />
|
return <Loading />
|
||||||
|
|
||||||
const isSelected = (uuid) => uuid === games.proposal.selectedUUID;
|
const isSelected = (uuid) => uuid === games.active.selectedUUID;
|
||||||
|
|
||||||
const onClick = (uuid) => {
|
const onClick = (uuid) => {
|
||||||
if (isSelected(uuid))
|
if (isSelected(uuid))
|
||||||
|
@ -30,6 +30,7 @@ export const gamesInitialState = {
|
|||||||
isPushingGameProposalCancel: false,
|
isPushingGameProposalCancel: false,
|
||||||
isPushingGameProposalReject: false,
|
isPushingGameProposalReject: false,
|
||||||
isPushingGameProposalAccept: false,
|
isPushingGameProposalAccept: false,
|
||||||
|
isPushingActiveGameSurrender: false,
|
||||||
|
|
||||||
findGame,
|
findGame,
|
||||||
nextGameList,
|
nextGameList,
|
||||||
|
Loading…
Reference in New Issue
Block a user