connect FE submit resign to BE game service

This commit is contained in:
sorrelbri 2020-06-07 13:47:09 -07:00
parent 77ced54c6f
commit 17b2e2c31f
7 changed files with 108 additions and 39 deletions

View file

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import "./PlayerArea.scss"; import "./PlayerArea.scss";
const PlayerArea = ({ playerMeta, turn }) => { const PlayerArea = ({ handleResignClick, playerMeta, turn }) => {
const { stones, player, rank, captures } = playerMeta; const { stones, player, rank, captures } = playerMeta;
const isTurn = const isTurn =
(stones === "black" && turn === 1) || (stones === "white" && turn === -1); (stones === "black" && turn === 1) || (stones === "white" && turn === -1);
@ -28,6 +28,7 @@ const PlayerArea = ({ playerMeta, turn }) => {
> >
<p <p
className={`player-container__resign-message player-container__resign-message--${stones}`} className={`player-container__resign-message player-container__resign-message--${stones}`}
{...(isTurn ? { onClick: () => handleResignClick(stones) } : null)}
> >
Resign? Resign?
</p> </p>

View file

@ -42,6 +42,10 @@ const launch = (nsp, dispatch) => {
dispatch({ type: "GAMES", message: "UPDATE_BOARD", body: data }); dispatch({ type: "GAMES", message: "UPDATE_BOARD", body: data });
}); });
socket.on("game_resign", (data) => {
dispatch({ type: "GAMES", message: "GAME_RESIGN", body: data });
});
return socket; return socket;
}; };

View file

@ -61,17 +61,39 @@ const Game = (props) => {
}); });
}, [playerState, game]); }, [playerState, game]);
const handleResignClick = (player) => {
const action = {
type: "SOCKET",
message: "RESIGN",
body: { game, player },
};
dispatch(action);
};
return ( return (
<div className="Game" data-testid="Game"> <div className="Game" data-testid="Game">
<div className="Game__meta-container"> <div className="Game__meta-container">
<span className="Game__socket-flag">{state.socket ? "✓" : " ⃠"}</span> <span className="Game__socket-flag">{state.socket ? "✓" : " ⃠"}</span>
<Logo /> <Logo />
{state?.meta?.winner ? (
<p>
{`winner: ${
state.meta.winner === 1
? playerBlackMeta?.player
: playerWhiteMeta?.player
}
`}
</p>
) : (
<></>
)}
<p>Timer</p> <p>Timer</p>
<p>? Game Tree</p> <p>? Game Tree</p>
</div> </div>
<div className="Game__board-container"> <div className="Game__board-container">
<PlayerArea <PlayerArea
handleResignClick={handleResignClick}
playerMeta={ playerMeta={
state.user && state.user &&
playerBlackMeta.playerBlack && playerBlackMeta.playerBlack &&
@ -90,6 +112,7 @@ const Game = (props) => {
board={state.board} board={state.board}
/> />
<PlayerArea <PlayerArea
handleResignClick={handleResignClick}
playerMeta={ playerMeta={
state.user && state.user &&
playerBlackMeta.playerWhite && playerBlackMeta.playerWhite &&

View file

@ -1,62 +1,77 @@
import { stateReducer } from '../reducer'; import { stateReducer } from "../reducer";
export const gamesReducer = (state, action) => { export const gamesReducer = (state, action) => {
switch(action.message) { switch (action.message) {
case "SET_GAMES": {
const games = formatGames(action);
return { ...state, games };
}
case 'SET_GAMES': case "JOIN_REQUEST": {
const games = formatGames(action);;
return {...state, games};
case 'JOIN_REQUEST':
if (!Object.entries(state.user).length) { if (!Object.entries(state.user).length) {
const errAction = { const errAction = {
type: 'ERR', type: "ERR",
message: 'JOIN_GAME_ERROR', message: "JOIN_GAME_ERROR",
body: {joinGameError: 'user not logged in'} body: { joinGameError: "user not logged in" },
} };
return stateReducer(state, errAction) return stateReducer(state, errAction);
} }
const id = action.body; const id = action.body;
return {...state, joinGame: id}; return { ...state, joinGame: id };
}
case 'UPDATE_BOARD': case "UPDATE_BOARD": {
const { gameRecord, pass, turn, winner, playerState } = action.body.meta; const { gameRecord, pass, turn, winner, playerState } = action.body.meta;
return {...state, board: action.body.board, meta: {gameRecord, pass, turn, winner, playerState } }; return {
...state,
board: action.body.board,
meta: { gameRecord, pass, turn, winner, playerState },
};
}
case 'SET_ACTIVE': case "GAME_RESIGN": {
return {...state, active: action.body}; const { gameRecord, pass, turn, winner, playerState } = action.body.meta;
return {
...state,
meta: { gameRecord, pass, turn, winner, playerState },
};
}
default: case "SET_ACTIVE": {
return { ...state, active: action.body };
}
default: {
return state; return state;
} }
} }
};
function parseRank(rank) { function parseRank(rank) {
switch(rank[0]) { switch (rank[0]) {
case 'D': case "D":
return `${rank.slice(1)}${rank[0].toLowerCase()}` return `${rank.slice(1)}${rank[0].toLowerCase()}`;
case 'K': case "K":
return `${rank.slice(1)}${rank[0].toLowerCase()}` return `${rank.slice(1)}${rank[0].toLowerCase()}`;
case 'U': case "U":
return '?' return "?";
default: default:
return '?' return "?";
} }
} }
function formatGames(action) { function formatGames(action) {
const games = [...action.body].map(game => { const games = [...action.body].map((game) => {
if (game.playerBlackRank) { if (game.playerBlackRank) {
game.playerBlackRank = parseRank(game.playerBlackRank) game.playerBlackRank = parseRank(game.playerBlackRank);
} }
if (game.playerWhiteRank) { if (game.playerWhiteRank) {
game.playerWhiteRank = parseRank(game.playerWhiteRank) game.playerWhiteRank = parseRank(game.playerWhiteRank);
} }
return game; return game;
}) });
return games; return games;
} }

View file

@ -34,6 +34,10 @@ export const socketReducer = (state, action) => {
return makeMove(state, action); return makeMove(state, action);
} }
case "RESIGN": {
return resign(state, action);
}
default: default:
return state; return state;
} }
@ -58,8 +62,13 @@ function connectGame(state, action) {
} }
function makeMove(state, action) { function makeMove(state, action) {
// const { user, game, room, board, move } = action.body;
const socket = state.socket; const socket = state.socket;
socket.emit("make_move", { ...action.body }); socket.emit("make_move", { ...action.body });
return state; return state;
} }
function resign(state, action) {
const socket = state.socket;
socket.emit("resign", { ...action.body });
return state;
}

View file

@ -70,6 +70,10 @@ const GameService = (moveQueries) => {
getAllGames: () => { getAllGames: () => {
return gamesInProgress; return gamesInProgress;
}, },
resign: ({ id, player }) => {
return gamesInProgress[id].submitResign(player).getMeta();
},
}; };
}; };

View file

@ -21,8 +21,6 @@ io.on("connection", async (socket) => {
const game = `game-${data.game.id}`; const game = `game-${data.game.id}`;
socket.join(game, async () => { socket.join(game, async () => {
const gameRecord = await moveQueries.findGameRecord(data.game.id); const gameRecord = await moveQueries.findGameRecord(data.game.id);
console.log("gameRecord from db");
console.log(gameRecord);
await gameServices.initGame({ id: data.game.id, gameRecord }); await gameServices.initGame({ id: data.game.id, gameRecord });
const { board, ...meta } = await gameServices.getDataForUI( const { board, ...meta } = await gameServices.getDataForUI(
data.game.id data.game.id
@ -52,6 +50,21 @@ io.on("connection", async (socket) => {
}); });
} }
}); });
socket.on("resign", async ({ game, player }) => {
const { id, room } = game;
const gameNsp = `game-${id}`;
try {
const meta = await gameServices.resign({
id,
player,
});
socket.join(gameNsp, () => {
io.of(room).to(gameNsp).emit("game_resign", meta);
});
} catch (e) {
console.log(e);
}
});
}); });
}); });
}); });