2024-04-22 19:03:07 +02:00
|
|
|
import {makeApiUrl, Scores} from './serverCalls';
|
|
|
|
import {Guid} from './Guid.ts';
|
|
|
|
import Column from './components/Column.tsx';
|
|
|
|
import useWebSocket, {ReadyState} from 'react-use-websocket';
|
|
|
|
import {useEffect, useState} from 'react';
|
2024-04-13 17:56:33 +02:00
|
|
|
|
2024-04-19 13:50:06 +02:00
|
|
|
function ScoreRow({name, value}: {
|
|
|
|
name: string;
|
2024-04-22 19:44:28 +02:00
|
|
|
value?: string | any;
|
2024-04-19 13:50:06 +02:00
|
|
|
}) {
|
2024-04-22 19:44:28 +02:00
|
|
|
let valueStr;
|
|
|
|
if (value === undefined)
|
|
|
|
valueStr = '?';
|
|
|
|
else if (typeof value === 'string' || value instanceof String)
|
|
|
|
valueStr = value;
|
|
|
|
else
|
|
|
|
valueStr = JSON.stringify(value);
|
|
|
|
|
2024-04-19 13:50:06 +02:00
|
|
|
return <tr>
|
|
|
|
<td>{name}</td>
|
2024-04-22 19:44:28 +02:00
|
|
|
<td>{valueStr}</td>
|
2024-04-19 13:50:06 +02:00
|
|
|
</tr>;
|
|
|
|
}
|
|
|
|
|
2024-04-22 19:44:28 +02:00
|
|
|
type TankInfo = {
|
|
|
|
readonly explosiveBullets: number;
|
|
|
|
readonly position: { x: number; y: number };
|
|
|
|
readonly orientation: number;
|
|
|
|
readonly moving: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-22 19:03:07 +02:00
|
|
|
type PlayerInfoMessage = {
|
|
|
|
readonly name: string;
|
|
|
|
readonly scores: Scores;
|
2024-04-22 20:13:31 +02:00
|
|
|
readonly controls: string;
|
2024-04-22 19:44:28 +02:00
|
|
|
readonly tank?: TankInfo;
|
2024-04-22 19:03:07 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 23:09:01 +02:00
|
|
|
export default function PlayerInfo({playerId}: { playerId: Guid }) {
|
2024-04-22 19:44:28 +02:00
|
|
|
const [shouldSendMessage, setShouldSendMessage] = useState(false);
|
2024-04-22 19:03:07 +02:00
|
|
|
|
|
|
|
const url = makeApiUrl('/player');
|
|
|
|
url.searchParams.set('id', playerId);
|
|
|
|
|
|
|
|
const {lastJsonMessage, readyState, sendMessage} = useWebSocket<PlayerInfoMessage>(url.toString(), {
|
2024-04-22 19:44:28 +02:00
|
|
|
onMessage: () => setShouldSendMessage(true),
|
|
|
|
shouldReconnect: () => true,
|
2024-04-17 23:09:01 +02:00
|
|
|
});
|
2024-04-13 17:56:33 +02:00
|
|
|
|
2024-04-22 19:03:07 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (!shouldSendMessage || readyState !== ReadyState.OPEN)
|
|
|
|
return;
|
|
|
|
setShouldSendMessage(false);
|
|
|
|
sendMessage('');
|
|
|
|
}, [readyState, shouldSendMessage]);
|
|
|
|
|
|
|
|
if (!lastJsonMessage)
|
|
|
|
return <></>;
|
|
|
|
|
|
|
|
return <Column className="PlayerInfo">
|
2024-04-13 23:53:09 +02:00
|
|
|
<h3>
|
2024-04-22 19:03:07 +02:00
|
|
|
Playing as {lastJsonMessage.name}
|
2024-04-13 23:53:09 +02:00
|
|
|
</h3>
|
2024-04-22 19:03:07 +02:00
|
|
|
<table>
|
2024-04-14 00:49:39 +02:00
|
|
|
<tbody>
|
2024-04-22 20:13:31 +02:00
|
|
|
<ScoreRow name="controls" value={lastJsonMessage.controls}/>
|
2024-04-22 19:44:28 +02:00
|
|
|
<ScoreRow name="explosive bullets" value={lastJsonMessage.tank?.explosiveBullets}/>
|
|
|
|
<ScoreRow name="position" value={lastJsonMessage.tank?.position}/>
|
|
|
|
<ScoreRow name="orientation" value={lastJsonMessage.tank?.orientation}/>
|
|
|
|
<ScoreRow name="moving" value={lastJsonMessage.tank?.moving}/>
|
2024-04-22 21:26:46 +02:00
|
|
|
|
|
|
|
<ScoreRow name="kills" value={lastJsonMessage.scores.kills}/>
|
|
|
|
<ScoreRow name="deaths" value={lastJsonMessage.scores.deaths}/>
|
|
|
|
|
|
|
|
<ScoreRow name="walls destroyed" value={lastJsonMessage.scores.wallsDestroyed}/>
|
|
|
|
<ScoreRow name="bullets fired" value={lastJsonMessage.scores.shotsFired}/>
|
|
|
|
|
|
|
|
<ScoreRow name="score" value={lastJsonMessage.scores.overallScore}/>
|
2024-04-14 00:49:39 +02:00
|
|
|
</tbody>
|
2024-04-22 19:03:07 +02:00
|
|
|
</table>
|
2024-04-13 23:07:08 +02:00
|
|
|
</Column>;
|
2024-04-13 17:56:33 +02:00
|
|
|
}
|