api.push (#36)
Reviewed-on: http://192.168.8.55:3000/HQLAx/CordaCheckers/pulls/36
This commit is contained in:
parent
2482226e0e
commit
04f0b86527
@ -1,4 +1,4 @@
|
|||||||
import usePolling from '../hook/Polling';
|
import { usePolling, doPushing } from '../hook/api';
|
||||||
|
|
||||||
export default function useGamesApi(gamesReducer, config) {
|
export default function useGamesApi(gamesReducer, config) {
|
||||||
const [games, dispatchGames] = gamesReducer;
|
const [games, dispatchGames] = gamesReducer;
|
||||||
@ -16,14 +16,13 @@ export default function useGamesApi(gamesReducer, config) {
|
|||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usePushNewGame = () => {
|
|
||||||
const onSuccess = (game) => {
|
|
||||||
dispatchGames({ type: 'next', game });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pollGamesList: usePollingGamesList,
|
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] })
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import usePolling from "../hook/Polling";
|
import { usePolling } from "../hook/api";
|
||||||
|
|
||||||
export default function useLeaderboardApi(leaderboardReducer, config) {
|
export default function useLeaderboardApi(leaderboardReducer, config) {
|
||||||
const [leaderboard, dispatchLeaderboard] = leaderboardReducer;
|
const [leaderboard, dispatchLeaderboard] = leaderboardReducer;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import usePolling from "../hook/Polling";
|
import { usePolling } from "../hook/api";
|
||||||
|
|
||||||
export default function useUserApi(userReducer) {
|
export default function useUserApi(userReducer) {
|
||||||
const [user, dispatchUser] = userReducer;
|
const [user, dispatchUser] = userReducer;
|
||||||
|
@ -30,7 +30,7 @@ export default function Games({ context: { gamesReducer, gamesApi }, players })
|
|||||||
<ViewProvider players={players} dispatchGames={dispatchGames} />
|
<ViewProvider players={players} dispatchGames={dispatchGames} />
|
||||||
</div>
|
</div>
|
||||||
<div className='right-side'>
|
<div className='right-side'>
|
||||||
<ActionPanel players={players}/>
|
<ActionPanel players={players} gamesApi={gamesApi} />
|
||||||
<GameBoard />
|
<GameBoard />
|
||||||
{/*
|
{/*
|
||||||
<GameMessage />
|
<GameMessage />
|
||||||
@ -81,12 +81,13 @@ function ViewProvider({ players, dispatchGames }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ActionPanel({ players }) {
|
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}
|
||||||
|
pushNewGame={(reqParams) => gamesApi.pushNewGame(reqParams)}
|
||||||
/>
|
/>
|
||||||
} />
|
} />
|
||||||
<Route path='proposal' element={[<Accept key={1} />, <Reject key={2} />, <Cancel key={3} />]} />
|
<Route path='proposal' element={[<Accept key={1} />, <Reject key={2} />, <Cancel key={3} />]} />
|
||||||
|
@ -1,36 +1,45 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { GamesContext } from '../../../context/games';
|
import { GamesContext } from '../../../context/games';
|
||||||
import Wobler from '../../../components/Wobler';
|
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 hasPlayers = checkPlayers(games.newGame);
|
||||||
const newGameCtx = useContext(GamesContext).newGame;
|
const hasCurrentUser = checkCurrentUser(games.newGame, isCurrentUser);
|
||||||
|
|
||||||
const hasPlayers = checkPlayers(newGameCtx);
|
const prepareNewGameRequest = () => {
|
||||||
const hasCurrentUser = checkCurrentUser(newGameCtx, isCurrentUser);
|
|
||||||
|
|
||||||
const prepareRequest = () => {
|
|
||||||
if (!hasPlayers)
|
if (!hasPlayers)
|
||||||
return alert("Black and White players must be selected for the game");
|
return alert("Black and White players must be selected for the game");
|
||||||
|
|
||||||
if (!hasCurrentUser)
|
if (!hasCurrentUser)
|
||||||
return alert("You must be one of the selected players");
|
return alert("You must be one of the selected players");
|
||||||
|
|
||||||
if (newGameCtx.pushing)
|
if (games.isPushingNewGame)
|
||||||
return; // current request is still being processed
|
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 (
|
return (
|
||||||
<button className={'Create'
|
<button className={'Create' + (hasPlayers && hasCurrentUser ? ' ready' : '')}
|
||||||
+ (hasPlayers && hasCurrentUser ? ' ready' : '')
|
onClick={prepareNewGameRequest}
|
||||||
}
|
|
||||||
onClick={prepareRequest}
|
|
||||||
>
|
>
|
||||||
<Wobler text="Create" dance={newGameCtx.pushing} />
|
<Wobler text="Create" dance={games.isPushingNewGame} />
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -43,3 +52,15 @@ function checkPlayers({ whitePlayer, blackPlayer }) {
|
|||||||
function checkCurrentUser({ whitePlayer, blackPlayer }, isCurrentUser) {
|
function checkCurrentUser({ whitePlayer, blackPlayer }, isCurrentUser) {
|
||||||
return isCurrentUser(whitePlayer) || isCurrentUser(blackPlayer);
|
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 ['', ''];
|
||||||
|
}
|
@ -8,7 +8,7 @@ import { useState, useRef, useCallback, useEffect, } from "react"
|
|||||||
- interval_stop
|
- interval_stop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function usePolling(uri, onResponce, mode = null) {
|
export function usePolling(uri, onSuccess, mode = null) {
|
||||||
const [isPolling, setPolling] = useState(false);
|
const [isPolling, setPolling] = useState(false);
|
||||||
|
|
||||||
const initialPollRef = useRef(true);
|
const initialPollRef = useRef(true);
|
||||||
@ -17,13 +17,12 @@ export default function usePolling(uri, onResponce, mode = null) {
|
|||||||
const intervalTimerIdRef = useRef(null);
|
const intervalTimerIdRef = useRef(null);
|
||||||
const intervalTimerId = intervalTimerIdRef.current;
|
const intervalTimerId = intervalTimerIdRef.current;
|
||||||
|
|
||||||
|
|
||||||
const pollData = useCallback(() => {
|
const pollData = useCallback(() => {
|
||||||
setPolling(true);
|
setPolling(true);
|
||||||
initialPollRef.current = false;
|
initialPollRef.current = false;
|
||||||
|
|
||||||
fetch(uri)
|
fetch(uri)
|
||||||
.then((responce) => {
|
.then((response) => {
|
||||||
setPolling(false);
|
setPolling(false);
|
||||||
|
|
||||||
if (typeof mode?.interval_sec === 'number') {
|
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);
|
intervalTimerIdRef.current = setTimeout(pollData, mode.interval_sec * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return responce.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((json) => {
|
.then((json) => {
|
||||||
onResponce(json);
|
onSuccess(json);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.warn(err.message);
|
console.warn(err.message);
|
||||||
})
|
})
|
||||||
}, [uri, mode, onResponce, initialPollRef, intervalTimerIdRef]);
|
}, [uri, mode, onSuccess, initialPollRef, intervalTimerIdRef]);
|
||||||
|
|
||||||
const stopPollInterval = useCallback(() => {
|
const stopPollInterval = useCallback(() => {
|
||||||
console.log("Cancel scheduled fetch for", uri);
|
console.log("Cancel scheduled fetch for", uri);
|
||||||
@ -52,10 +51,35 @@ export default function usePolling(uri, onResponce, mode = null) {
|
|||||||
if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimerId === null)) && !isPolling) {
|
if ((initialPoll || (typeof mode?.interval_sec === 'number' && intervalTimerId === null)) && !isPolling) {
|
||||||
pollData();
|
pollData();
|
||||||
} else
|
} else
|
||||||
if (mode?.interval_stop && intervalTimerId) {
|
if (mode?.interval_stop && intervalTimerId) {
|
||||||
stopPollInterval();
|
stopPollInterval();
|
||||||
}
|
}
|
||||||
}, [initialPoll, mode, intervalTimerId, isPolling, pollData, stopPollInterval]);
|
}, [initialPoll, mode, intervalTimerId, isPolling, pollData, stopPollInterval]);
|
||||||
|
|
||||||
return isPolling;
|
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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user