From 04f0b86527445f7032c544db405e53a368ac3340 Mon Sep 17 00:00:00 2001 From: djmil Date: Mon, 13 Nov 2023 16:55:10 +0100 Subject: [PATCH] api.push (#36) Reviewed-on: http://192.168.8.55:3000/HQLAx/CordaCheckers/pulls/36 --- webapp/src/api/games.js | 13 +++--- webapp/src/api/leaderboard.js | 2 +- webapp/src/api/user.js | 2 +- webapp/src/container/Games.jsx | 5 +- webapp/src/container/games/action/Create.jsx | 49 ++++++++++++++------ webapp/src/hook/{Polling.js => api.js} | 46 +++++++++++++----- 6 files changed, 81 insertions(+), 36 deletions(-) rename webapp/src/hook/{Polling.js => api.js} (60%) diff --git a/webapp/src/api/games.js b/webapp/src/api/games.js index 8a4f3ed..58b800d 100644 --- a/webapp/src/api/games.js +++ b/webapp/src/api/games.js @@ -1,4 +1,4 @@ -import usePolling from '../hook/Polling'; +import { usePolling, doPushing } from '../hook/api'; export default function useGamesApi(gamesReducer, config) { const [games, dispatchGames] = gamesReducer; @@ -16,14 +16,13 @@ export default function useGamesApi(gamesReducer, config) { return games; } - const usePushNewGame = () => { - const onSuccess = (game) => { - dispatchGames({ type: 'next', game }); - } - } return { pollGamesList: usePollingGamesList, - pushNewGame: usePushNewGame + + pushNewGame: (reqParams) => doPushing('/api/gameproposal', 'POST', reqParams, { + onPushing: (isPushingNewGame) => dispatchGames({ type: 'next', isPushingNewGame }), + onSuccess: (game) => dispatchGames({ type: 'next', gamesList: [...games.gamesList, game] }) + }), } } \ No newline at end of file diff --git a/webapp/src/api/leaderboard.js b/webapp/src/api/leaderboard.js index fe279a3..280afaa 100644 --- a/webapp/src/api/leaderboard.js +++ b/webapp/src/api/leaderboard.js @@ -1,4 +1,4 @@ -import usePolling from "../hook/Polling"; +import { usePolling } from "../hook/api"; export default function useLeaderboardApi(leaderboardReducer, config) { const [leaderboard, dispatchLeaderboard] = leaderboardReducer; diff --git a/webapp/src/api/user.js b/webapp/src/api/user.js index 39c3a68..9d8df5c 100644 --- a/webapp/src/api/user.js +++ b/webapp/src/api/user.js @@ -1,4 +1,4 @@ -import usePolling from "../hook/Polling"; +import { usePolling } from "../hook/api"; export default function useUserApi(userReducer) { const [user, dispatchUser] = userReducer; diff --git a/webapp/src/container/Games.jsx b/webapp/src/container/Games.jsx index 3ac2c34..e94d41b 100644 --- a/webapp/src/container/Games.jsx +++ b/webapp/src/container/Games.jsx @@ -30,7 +30,7 @@ export default function Games({ context: { gamesReducer, gamesApi }, players })
- + {/* @@ -81,12 +81,13 @@ function ViewProvider({ players, dispatchGames }) { ) } -function ActionPanel({ players }) { +function ActionPanel({ players, gamesApi }) { return (
gamesApi.pushNewGame(reqParams)} /> } /> , , ]} /> diff --git a/webapp/src/container/games/action/Create.jsx b/webapp/src/container/games/action/Create.jsx index 9fd59ca..cddb347 100644 --- a/webapp/src/container/games/action/Create.jsx +++ b/webapp/src/container/games/action/Create.jsx @@ -1,36 +1,45 @@ import React, { useContext } from 'react'; import { GamesContext } from '../../../context/games'; import Wobler from '../../../components/Wobler'; +import { Color } from '../../../components/Checkers'; +export default function Create({ isCurrentUser, pushNewGame }) { + const games = useContext(GamesContext); -export default function Create({ isCurrentUser, onClick }) { - const newGameCtx = useContext(GamesContext).newGame; + const hasPlayers = checkPlayers(games.newGame); + const hasCurrentUser = checkCurrentUser(games.newGame, isCurrentUser); - const hasPlayers = checkPlayers(newGameCtx); - const hasCurrentUser = checkCurrentUser(newGameCtx, isCurrentUser); - - const prepareRequest = () => { + const prepareNewGameRequest = () => { if (!hasPlayers) return alert("Black and White players must be selected for the game"); if (!hasCurrentUser) return alert("You must be one of the selected players"); - if (newGameCtx.pushing) + if (games.isPushingNewGame) return; // current request is still being processed - //onClick - console.log("send request"); + /* + * Prepare & send NewGame request + */ + const [opponentName, opponentColor] = getOpponent(games.newGame, isCurrentUser); + + const reqParams = { + opponentName, + opponentColor, + board: null, // default board configuration + message: 'default NewGame req message' + } + + pushNewGame(reqParams); } return ( - ) } @@ -42,4 +51,16 @@ function checkPlayers({ whitePlayer, blackPlayer }) { function checkCurrentUser({ whitePlayer, blackPlayer }, isCurrentUser) { return isCurrentUser(whitePlayer) || isCurrentUser(blackPlayer); +} + +function getOpponent({whitePlayer, blackPlayer}, isCurrentUser) { + if (isCurrentUser(whitePlayer)) { + return [blackPlayer, Color.black]; + } + + if (isCurrentUser(blackPlayer)) { + return [whitePlayer, Color.white]; + } + + return ['', '']; } \ No newline at end of file diff --git a/webapp/src/hook/Polling.js b/webapp/src/hook/api.js similarity index 60% rename from webapp/src/hook/Polling.js rename to webapp/src/hook/api.js index abfa3b7..28e759c 100644 --- a/webapp/src/hook/Polling.js +++ b/webapp/src/hook/api.js @@ -8,22 +8,21 @@ import { useState, useRef, useCallback, useEffect, } from "react" - interval_stop */ -export default function usePolling(uri, onResponce, mode = null) { +export function usePolling(uri, onSuccess, mode = null) { const [isPolling, setPolling] = useState(false); const initialPollRef = useRef(true); const initialPoll = initialPollRef.current; - + const intervalTimerIdRef = useRef(null); const intervalTimerId = intervalTimerIdRef.current; - const pollData = useCallback(() => { setPolling(true); initialPollRef.current = false; fetch(uri) - .then((responce) => { + .then((response) => { setPolling(false); if (typeof mode?.interval_sec === 'number') { @@ -31,15 +30,15 @@ export default function usePolling(uri, onResponce, mode = null) { intervalTimerIdRef.current = setTimeout(pollData, mode.interval_sec * 1000); } - return responce.json(); + return response.json(); }) .then((json) => { - onResponce(json); + onSuccess(json); }) .catch((err) => { console.warn(err.message); }) - }, [uri, mode, onResponce, initialPollRef, intervalTimerIdRef]); + }, [uri, mode, onSuccess, initialPollRef, intervalTimerIdRef]); const stopPollInterval = useCallback(() => { console.log("Cancel scheduled fetch for", uri); @@ -51,11 +50,36 @@ export default function usePolling(uri, onResponce, mode = null) { useEffect(() => { if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimerId === null)) && !isPolling) { pollData(); - } else - if (mode?.interval_stop && intervalTimerId) { - stopPollInterval(); - } + } else + if (mode?.interval_stop && intervalTimerId) { + stopPollInterval(); + } }, [initialPoll, mode, intervalTimerId, isPolling, pollData, stopPollInterval]); return isPolling; +} + +export async function doPushing(uri, method, data, { onSuccess, onPushing }) { + if (onPushing) + onPushing(true); + + try { + const response = await fetch(uri, { + method, + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), // body data type must match "Content-Type" header + }); + + if (!response.ok) + throw new Error(`Error! status: ${response.status}`); + + if (onSuccess) + onSuccess(await response.json()); +// } catch (err) { + } finally { + if (onPushing) + onPushing(false); + } } \ No newline at end of file