diff --git a/tank-frontend/src/JoinForm.tsx b/tank-frontend/src/JoinForm.tsx index d5d2821..8655f08 100644 --- a/tank-frontend/src/JoinForm.tsx +++ b/tank-frontend/src/JoinForm.tsx @@ -1,6 +1,6 @@ import {useEffect, useState} from 'react'; import './JoinForm.css'; -import {Player, postPlayer} from './serverCalls'; +import {makeApiUrl, Player} from './serverCalls'; import Column from './components/Column.tsx'; import Button from './components/Button.tsx'; import TextInput from './components/TextInput.tsx'; @@ -16,20 +16,20 @@ export default function JoinForm({onDone}: { if (!clicked || data) return; - postPlayer(name).then(response => { - if (response.ok && response.successResult) { - onDone(response.successResult!.trim()); + const url = makeApiUrl('/player'); + url.searchParams.set('name', name); + + fetch(url, {method: 'POST'}) + .then(async response => { + if (!response.ok) { + setErrorText(`${response.status} (${response.statusText}): ${await response.text()}`); + setClicked(false); + return; + } + + onDone((await response.json()).trim()); setErrorText(null); - return; - } - - if (response.additionalErrorText) - setErrorText(`${response.statusCode} (${response.statusText}): ${response.additionalErrorText}`); - else - setErrorText(`${response.statusCode} (${response.statusText})`); - - setClicked(false); - }); + }); }, [clicked, setData, data, setClicked, onDone, errorText]); const [name, setName] = useState(''); diff --git a/tank-frontend/src/MapChooser.tsx b/tank-frontend/src/MapChooser.tsx index 9491570..9564dfa 100644 --- a/tank-frontend/src/MapChooser.tsx +++ b/tank-frontend/src/MapChooser.tsx @@ -1,29 +1,34 @@ -import { ChangeEvent, useEffect, useState } from "react"; -import { getMaps, postMaps } from "./serverCalls"; -import './MapChooser.css' +import {ChangeEvent} from 'react'; +import {makeApiUrl} from './serverCalls'; +import './MapChooser.css'; +import {useQuery} from '@tanstack/react-query'; export default function MapChooser() { - const [mapList, setMaps] = useState(null); - - useEffect(() => { - let aborted = false; - async function startFetch() { - const response = await getMaps(); - if (!aborted && response.ok && response.successResult) - setMaps(response.successResult); + const query = useQuery({ + queryKey: ['get-maps'], + queryFn: async () => { + const url = makeApiUrl('/map'); + 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 string[]; } - startFetch(); - return () => { aborted = true }; - }, []); + }); const onChange = (event: ChangeEvent) => { - postMaps(event.target.options[event.target.selectedIndex].value); + if (event.target.selectedIndex < 1) + return; event.preventDefault(); + + const url = makeApiUrl('/map'); + url.searchParams.set('name', event.target.options[event.target.selectedIndex].value); + + fetch(url, {method: 'POST'}); }; - return + + {query.isSuccess && query.data.map(m => )} - + ; } diff --git a/tank-frontend/src/serverCalls.tsx b/tank-frontend/src/serverCalls.tsx index c0dd334..5071c46 100644 --- a/tank-frontend/src/serverCalls.tsx +++ b/tank-frontend/src/serverCalls.tsx @@ -2,14 +2,6 @@ export function makeApiUrl(path: string, protocol: 'http' | 'ws' = 'http') { return new URL(`${protocol}://${window.location.hostname}${path}`); } -export type ServerResponse = { - ok: boolean; - statusCode: number; - statusText: string; - additionalErrorText?: string; - successResult?: T; -} - export type Scores = { readonly kills: number; readonly deaths: number; @@ -22,37 +14,3 @@ export type Player = { readonly name: string; readonly scores: Scores; }; - -export async function fetchTyped({url, method}: { url: URL; method: string; }): Promise> { - const response = await fetch(url, {method}); - const result: ServerResponse = { - ok: response.ok, - statusCode: response.status, - statusText: response.statusText - }; - - if (response.ok) - result.successResult = await response.json(); - else - result.additionalErrorText = await response.text(); - return result; -} - -export function postPlayer(name: string) { - const url = makeApiUrl('/player'); - url.searchParams.set('name', name); - - return fetchTyped({url, method: 'POST'}); -} - -export async function getMaps() { - const url = makeApiUrl('/map'); - return await fetchTyped({url, method: 'GET'}); -} - -export function postMaps(map: string) { - const url = makeApiUrl('/map'); - url.searchParams.set('name', map); - - return fetchTyped({url, method: 'POST'}); -}