diff --git a/tank-frontend/package-lock.json b/tank-frontend/package-lock.json index 9839298..34a1ffd 100644 --- a/tank-frontend/package-lock.json +++ b/tank-frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "tank-frontend", "version": "0.0.0", "dependencies": { + "@tanstack/react-query": "^5.29.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-use-websocket": "^4.8.1" @@ -1188,6 +1189,30 @@ "win32" ] }, + "node_modules/@tanstack/query-core": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.29.0.tgz", + "integrity": "sha512-WgPTRs58hm9CMzEr5jpISe8HXa3qKQ8CxewdYZeVnA54JrPY9B1CZiwsCoLpLkf0dGRZq+LcX5OiJb0bEsOFww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.29.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.29.2.tgz", + "integrity": "sha512-nyuWILR4u7H5moLGSiifLh8kIqQDLNOHGuSz0rcp+J75fNc8aQLyr5+I2JCHU3n+nJrTTW1ssgAD8HiKD7IFBQ==", + "dependencies": { + "@tanstack/query-core": "5.29.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", diff --git a/tank-frontend/package.json b/tank-frontend/package.json index ba60c09..c2378a4 100644 --- a/tank-frontend/package.json +++ b/tank-frontend/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@tanstack/react-query": "^5.29.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-use-websocket": "^4.8.1" diff --git a/tank-frontend/src/App.tsx b/tank-frontend/src/App.tsx index 78a9104..e065fc7 100644 --- a/tank-frontend/src/App.tsx +++ b/tank-frontend/src/App.tsx @@ -44,8 +44,8 @@ export default function App() { {nameId.name === '' && } - {isLoggedIn && } - {isLoggedIn && } + {isLoggedIn && } + {isLoggedIn && } ; diff --git a/tank-frontend/src/Controls.tsx b/tank-frontend/src/Controls.tsx index bc76ad8..f922e3f 100644 --- a/tank-frontend/src/Controls.tsx +++ b/tank-frontend/src/Controls.tsx @@ -1,19 +1,17 @@ import './Controls.css'; import useWebSocket, {ReadyState} from 'react-use-websocket'; import {useEffect} from 'react'; +import {Guid} from "./Guid.ts"; -export default function Controls({playerId, logout}: { - playerId: string, - logout: () => void -}) { +export default function Controls({playerId}: { playerId: Guid }) { const url = new URL('controls', import.meta.env.VITE_TANK_WS); url.searchParams.set('playerId', playerId); + const { sendMessage, getWebSocket, readyState } = useWebSocket(url.toString(), { - onError: logout, shouldReconnect: () => true, }); diff --git a/tank-frontend/src/PlayerInfo.tsx b/tank-frontend/src/PlayerInfo.tsx index fec65f0..a14cb3d 100644 --- a/tank-frontend/src/PlayerInfo.tsx +++ b/tank-frontend/src/PlayerInfo.tsx @@ -1,43 +1,40 @@ -import {useEffect, useState} from 'react'; -import {Player, getPlayer} from './serverCalls'; +import {useQuery} from '@tanstack/react-query' +import {Player} from './serverCalls'; import {Guid} from "./Guid.ts"; import Column from "./components/Column.tsx"; -export default function PlayerInfo({playerId, logout}: { - playerId: Guid, - logout: () => void -}) { - const [player, setPlayer] = useState(); +export default function PlayerInfo({playerId}: { playerId: Guid }) { + const query = useQuery({ + queryKey: ['player'], + refetchInterval: 1000, + queryFn: async () => { + const url = new URL('/player', import.meta.env.VITE_TANK_API); + url.searchParams.set('id', playerId); - useEffect(() => { - const refresh = () => { - getPlayer(playerId).then(response => { - if (response.successResult) - setPlayer(response.successResult); - else - logout(); - }); - }; - - const timer = setInterval(refresh, 5000); - return () => clearInterval(timer); - }, [playerId]); + const response = await fetch(url, {method: 'GET'}); + if (!response.ok) + throw new Error(`response failed with code ${response.status} (${response.status})${await response.text()}`) + return await response.json() as Player; + } + }); return

- {player ? `Playing as ${player?.name}` : 'loading...'} + {query.isPending && 'loading...'} + {query.isSuccess && `Playing as ${query.data.name}`}

- + {query.isError &&

{query.error.message}

} + {query.isSuccess &&
- + - + -
kills:{player?.scores.kills}{query.data?.scores?.kills ?? '?'}
deaths:{player?.scores.deaths}{query.data?.scores?.deaths ?? '?'}
+ }
; } diff --git a/tank-frontend/src/Scoreboard.tsx b/tank-frontend/src/Scoreboard.tsx index 4b266af..f9cb4aa 100644 --- a/tank-frontend/src/Scoreboard.tsx +++ b/tank-frontend/src/Scoreboard.tsx @@ -1,28 +1,31 @@ -import {getScores, Player} from "./serverCalls.tsx"; -import {useEffect, useState} from "react"; +import {Player} from "./serverCalls.tsx"; import DataTable from "./components/DataTable.tsx"; +import {useQuery} from "@tanstack/react-query"; function numberSorter(a: number, b: number) { return b - a; } export default function Scoreboard({}: {}) { - const [players, setPlayers] = useState([]); + const query = useQuery({ + queryKey: ['scores'], + refetchInterval: 1000, + queryFn: async () => { + const url = new URL('/scores', import.meta.env.VITE_TANK_API); + const response = await fetch(url, {method: 'GET'}); + if (!response.ok) + throw new Error(`response failed with code ${response.status} (${response.status})${await response.text()}`) + return await response.json() as Player[]; + } + }); - useEffect(() => { - const refresh = () => { - getScores().then(value => { - if (value.successResult) - setPlayers(value.successResult); - }); - }; - - const timer = setInterval(refresh, 5000); - return () => clearInterval(timer); - }, [players]); + if (query.isError) + return

{query.error.message}

; + if (query.isPending) + return

loading...

; return - + + + ); diff --git a/tank-frontend/src/serverCalls.tsx b/tank-frontend/src/serverCalls.tsx index 22a0555..15832c4 100644 --- a/tank-frontend/src/serverCalls.tsx +++ b/tank-frontend/src/serverCalls.tsx @@ -44,15 +44,3 @@ export function postPlayer({name, id}: NameId) { return fetchTyped({url, method: 'POST'}); } - -export function getPlayer(id: Guid) { - const url = new URL('/player', import.meta.env.VITE_TANK_API); - url.searchParams.set('id', id); - - return fetchTyped({url, method: 'GET'}); -} - -export function getScores() { - const url = new URL('/scores', import.meta.env.VITE_TANK_API); - return fetchTyped({url, method: 'GET'}); -}