Game: surrender
This commit is contained in:
		
							parent
							
								
									cacc8c99d8
								
							
						
					
					
						commit
						576556afe7
					
				@ -1,11 +1,14 @@
 | 
			
		||||
package djmil.cordacheckers.api;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.http.ResponseEntity;
 | 
			
		||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
 | 
			
		||||
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.RestController;
 | 
			
		||||
 | 
			
		||||
@ -16,8 +19,8 @@ import djmil.cordacheckers.user.User;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@RestController
 | 
			
		||||
@RequestMapping("api/games")
 | 
			
		||||
public class GameStateController {
 | 
			
		||||
@RequestMapping("api/game")
 | 
			
		||||
public class GameController {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    CordaClient cordaClient;
 | 
			
		||||
@ -26,7 +29,7 @@ public class GameStateController {
 | 
			
		||||
    HoldingIdentityResolver holdingIdentityResolver;
 | 
			
		||||
 | 
			
		||||
    @GetMapping
 | 
			
		||||
    public ResponseEntity<List<GameView>> gameStateList(
 | 
			
		||||
    public ResponseEntity<List<GameView>> list(
 | 
			
		||||
        @AuthenticationPrincipal User player
 | 
			
		||||
    ) {
 | 
			
		||||
        final List<GameView> gsList = cordaClient.gameStateList(player.getHoldingIdentity());
 | 
			
		||||
@ -34,4 +37,17 @@ public class GameStateController {
 | 
			
		||||
        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 });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const isPollingGamesList = usePolling('/api/games', onSuccess, config.intervalMode(30));
 | 
			
		||||
        const isPollingGamesList = usePolling('/api/game', onSuccess, config.intervalMode(30));
 | 
			
		||||
        if (games.isPollingGamesList !== isPollingGamesList) {
 | 
			
		||||
            dispatchGames({ type: 'next', isPollingGamesList });
 | 
			
		||||
        }
 | 
			
		||||
@ -43,6 +43,12 @@ export default function useGamesApi(gamesReducer, config) {
 | 
			
		||||
                onPushing: (isPushingGameProposalAccept) => dispatchGames({ type: 'next', isPushingGameProposalAccept }),
 | 
			
		||||
                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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ActionPanel .Create.ready { /* , */ /* OR  .game-action.busy  */
 | 
			
		||||
.ActionPanel .Create.ready {
 | 
			
		||||
    background-color:#00b0ff30;  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -115,17 +115,23 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ActionPanel .Cancel.ready,
 | 
			
		||||
.ActionPanel .Reject.ready {
 | 
			
		||||
.ActionPanel .Reject.ready,
 | 
			
		||||
.ActionPanel .Surrender.ready  
 | 
			
		||||
{
 | 
			
		||||
    background-color:#ffaaaa60
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ActionPanel .Cancel.ready:hover,
 | 
			
		||||
.ActionPanel .Reject.ready:hover {
 | 
			
		||||
.ActionPanel .Reject.ready:hover,
 | 
			
		||||
.ActionPanel .Surrender.ready:hover
 | 
			
		||||
{
 | 
			
		||||
    background-color:#ff000060
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ActionPanel .Cancel.ready:active,
 | 
			
		||||
.ActionPanel .Reject.ready:active {
 | 
			
		||||
.ActionPanel .Reject.ready:active,
 | 
			
		||||
.ActionPanel .Surrender.ready:active
 | 
			
		||||
 {
 | 
			
		||||
    background-color:#ff0000a0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -96,11 +96,15 @@ function ActionPanel({ players, gamesApi }) {
 | 
			
		||||
          />
 | 
			
		||||
        } />
 | 
			
		||||
        <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 })} />,
 | 
			
		||||
          <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} />]} />
 | 
			
		||||
      </Routes>
 | 
			
		||||
    </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)
 | 
			
		||||
        return <Loading />
 | 
			
		||||
 | 
			
		||||
    const isSelected = (uuid) => uuid === games.proposal.selectedUUID;
 | 
			
		||||
    const isSelected = (uuid) => uuid === games.active.selectedUUID;
 | 
			
		||||
 | 
			
		||||
    const onClick = (uuid) => {
 | 
			
		||||
        if (isSelected(uuid))
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ export const gamesInitialState = {
 | 
			
		||||
  isPushingGameProposalCancel: false,
 | 
			
		||||
  isPushingGameProposalReject: false,
 | 
			
		||||
  isPushingGameProposalAccept: false,
 | 
			
		||||
  isPushingActiveGameSurrender: false,
 | 
			
		||||
 | 
			
		||||
  findGame,
 | 
			
		||||
  nextGameList,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user