import { useAtomValue, useSetAtom } from "jotai";
import { useContext, useEffect, useState } from "react";
import { useTimer } from "react-use-precision-timer";
import { useDebouncedCallback } from "use-debounce";
import {
ApiAuthTokenContext,
apiGetGame,
apiGetGamePlayLatestState,
apiPostGamePlayCode,
apiPostGamePlaySubmit,
} from "../api/client";
import type { components } from "../api/schema";
import {
gameStateKindAtom,
handleSubmitCodePostAtom,
handleSubmitCodePreAtom,
setCurrentTimestampAtom,
setGameStartedAtAtom,
setLatestGameStateAtom,
} from "../states/play";
import GolfPlayAppFinished from "./GolfPlayApps/GolfPlayAppFinished";
import GolfPlayAppGaming from "./GolfPlayApps/GolfPlayAppGaming";
import GolfPlayAppLoading from "./GolfPlayApps/GolfPlayAppLoading";
import GolfPlayAppStarting from "./GolfPlayApps/GolfPlayAppStarting";
import GolfPlayAppWaiting from "./GolfPlayApps/GolfPlayAppWaiting";
type Game = components["schemas"]["Game"];
type User = components["schemas"]["User"];
type Props = {
game: Game;
player: User;
initialCode: string;
};
export default function GolfPlayApp({ game, player, initialCode }: Props) {
const apiAuthToken = useContext(ApiAuthTokenContext);
const gameStateKind = useAtomValue(gameStateKindAtom);
const setGameStartedAt = useSetAtom(setGameStartedAtAtom);
const setCurrentTimestamp = useSetAtom(setCurrentTimestampAtom);
const handleSubmitCodePre = useSetAtom(handleSubmitCodePreAtom);
const handleSubmitCodePost = useSetAtom(handleSubmitCodePostAtom);
const setLatestGameState = useSetAtom(setLatestGameStateAtom);
useTimer({ delay: 1000, startImmediately: true }, setCurrentTimestamp);
const playerProfile = {
id: player.user_id,
displayName: player.display_name,
iconPath: player.icon_path ?? null,
};
const onCodeChange = useDebouncedCallback(async (code: string) => {
console.log("player:c2s:code");
if (game.game_type === "1v1") {
await apiPostGamePlayCode(apiAuthToken, game.game_id, code);
}
}, 1000);
const onCodeSubmit = useDebouncedCallback(async (code: string) => {
if (code === "") {
return;
}
console.log("player:c2s:submit");
handleSubmitCodePre();
await apiPostGamePlaySubmit(apiAuthToken, game.game_id, code);
handleSubmitCodePost();
}, 1000);
const [isDataPolling, setIsDataPolling] = useState(false);
useEffect(() => {
if (isDataPolling) {
return;
}
const timerId = setInterval(async () => {
if (isDataPolling) {
return;
}
setIsDataPolling(true);
try {
if (gameStateKind === "waiting") {
const { game: g } = await apiGetGame(apiAuthToken, game.game_id);
if (g.started_at != null) {
setGameStartedAt(g.started_at);
}
} else if (gameStateKind === "gaming") {
const { state } = await apiGetGamePlayLatestState(
apiAuthToken,
game.game_id,
);
setLatestGameState(state);
}
} catch (error) {
console.error(error);
} finally {
setIsDataPolling(false);
}
}, 1000);
return () => {
clearInterval(timerId);
};
}, [
isDataPolling,
apiAuthToken,
game.game_id,
gameStateKind,
setGameStartedAt,
setLatestGameState,
]);
if (gameStateKind === "loading") {
return ;
} else if (gameStateKind === "waiting") {
return (
);
} else if (gameStateKind === "starting") {
return ;
} else if (gameStateKind === "gaming") {
return (
);
} else if (gameStateKind === "finished") {
return ;
}
}