react query
This commit is contained in:
		
							parent
							
								
									2a94a47a96
								
							
						
					
					
						commit
						25a3adea2a
					
				
					 8 changed files with 77 additions and 60 deletions
				
			
		
							
								
								
									
										25
									
								
								tank-frontend/package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										25
									
								
								tank-frontend/package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -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", | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -44,8 +44,8 @@ export default function App() { | |||
|         <ClientScreen logout={logout} theme={theme} playerId={nameId.id}/> | ||||
|         {nameId.name === '' && <JoinForm setNameId={setNameId} clientId={nameId.id}/>} | ||||
|         <Row className='GadgetRows'> | ||||
|             {isLoggedIn && <Controls playerId={nameId.id} logout={logout}/>} | ||||
|             {isLoggedIn && <PlayerInfo playerId={nameId.id} logout={logout}/>} | ||||
|             {isLoggedIn && <Controls playerId={nameId.id}/>} | ||||
|             {isLoggedIn && <PlayerInfo playerId={nameId.id}/>} | ||||
|             <Scoreboard/> | ||||
|         </Row> | ||||
|     </Column>; | ||||
|  |  | |||
|  | @ -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, | ||||
|     }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<Player | null>(); | ||||
| 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 <Column className='PlayerInfo'> | ||||
|         <h3> | ||||
|             {player ? `Playing as ${player?.name}` : 'loading...'} | ||||
|             {query.isPending && 'loading...'} | ||||
|             {query.isSuccess && `Playing as ${query.data.name}`} | ||||
|         </h3> | ||||
|         <table> | ||||
|         {query.isError && <p>{query.error.message}</p>} | ||||
|         {query.isSuccess && <table> | ||||
|             <tbody> | ||||
|             <tr> | ||||
|                 <td>kills:</td> | ||||
|                 <td>{player?.scores.kills}</td> | ||||
|                 <td>{query.data?.scores?.kills ?? '?'}</td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td>deaths:</td> | ||||
|                 <td>{player?.scores.deaths}</td> | ||||
|                 <td>{query.data?.scores?.deaths ?? '?'}</td> | ||||
|             </tr> | ||||
|             </tbody> | ||||
|         </table> | ||||
|         </table>} | ||||
|     </Column>; | ||||
| } | ||||
|  |  | |||
|  | @ -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<Player[]>([]); | ||||
|     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 <p>{query.error.message}</p>; | ||||
|     if (query.isPending) | ||||
|         return <p>loading...</p>; | ||||
| 
 | ||||
|     return <DataTable | ||||
|         data={players} | ||||
|         data={query.data} | ||||
|         columns={[ | ||||
|             {field: 'name'}, | ||||
|             { | ||||
|  |  | |||
|  | @ -2,9 +2,14 @@ import React from 'react'; | |||
| import {createRoot} from 'react-dom/client'; | ||||
| import './index.css'; | ||||
| import App from "./App.tsx"; | ||||
| import {QueryClient, QueryClientProvider} from "@tanstack/react-query"; | ||||
| 
 | ||||
| const queryClient = new QueryClient() | ||||
| 
 | ||||
| createRoot(document.getElementById('root')!).render( | ||||
|     <React.StrictMode> | ||||
|         <App/> | ||||
|         <QueryClientProvider client={queryClient}> | ||||
|             <App/> | ||||
|         </QueryClientProvider> | ||||
|     </React.StrictMode> | ||||
| ); | ||||
|  |  | |||
|  | @ -44,15 +44,3 @@ export function postPlayer({name, id}: NameId) { | |||
| 
 | ||||
|     return fetchTyped<NameId>({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<Player>({url, method: 'GET'}); | ||||
| } | ||||
| 
 | ||||
| export function getScores() { | ||||
|     const url = new URL('/scores', import.meta.env.VITE_TANK_API); | ||||
|     return fetchTyped<Player[]>({url, method: 'GET'}); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter