diff options
Diffstat (limited to 'frontend/app/components')
12 files changed, 936 insertions, 936 deletions
diff --git a/frontend/app/components/GolfPlayApp.client.tsx b/frontend/app/components/GolfPlayApp.client.tsx index 0ab8fff..ace0710 100644 --- a/frontend/app/components/GolfPlayApp.client.tsx +++ b/frontend/app/components/GolfPlayApp.client.tsx @@ -16,136 +16,136 @@ type Problem = components["schemas"]["Problem"]; type GameState = "connecting" | "waiting" | "starting" | "gaming" | "finished"; export default function GolfPlayApp({ - game, - sockToken, + game, + sockToken, }: { - game: Game; - sockToken: string; + game: Game; + sockToken: string; }) { - // const socketUrl = `wss://t.nil.ninja/iosdc-japan/2024/sock/golf/${game.game_id}/play?token=${sockToken}`; - const socketUrl = - process.env.NODE_ENV === "development" - ? `ws://localhost:8002/sock/golf/${game.game_id}/play?token=${sockToken}` - : `ws://api-server/sock/golf/${game.game_id}/play?token=${sockToken}`; - - const { sendJsonMessage, lastJsonMessage, readyState } = - useWebSocket<WebSocketMessage>(socketUrl, {}); - - const [gameState, setGameState] = useState<GameState>("connecting"); - - const [problem, setProblem] = useState<Problem | null>(null); - - const [startedAt, setStartedAt] = useState<number | null>(null); - - const [timeLeftSeconds, setTimeLeftSeconds] = useState<number | null>(null); - - useEffect(() => { - if (gameState === "starting" && startedAt !== null) { - const timer1 = setInterval(() => { - setTimeLeftSeconds((prev) => { - if (prev === null) { - return null; - } - if (prev <= 1) { - clearInterval(timer1); - setGameState("gaming"); - return 0; - } - return prev - 1; - }); - }, 1000); - - const timer2 = setInterval(() => { - const nowSec = Math.floor(Date.now() / 1000); - const finishedAt = startedAt + game.duration_seconds; - if (nowSec >= finishedAt) { - clearInterval(timer2); - setGameState("finished"); - } - }, 1000); - - return () => { - clearInterval(timer1); - clearInterval(timer2); - }; - } - }, [gameState, startedAt, game.duration_seconds]); - - const [currentScore, setCurrentScore] = useState<number | null>(null); - - const onCodeChange = useDebouncedCallback((code: string) => { - console.log("player:c2s:code"); - sendJsonMessage({ - type: "player:c2s:code", - data: { code }, - }); - }, 1000); - - if (readyState === ReadyState.UNINSTANTIATED) { - throw new Error("WebSocket is not connected"); - } - - useEffect(() => { - if (readyState === ReadyState.CLOSING || readyState === ReadyState.CLOSED) { - if (gameState !== "finished") { - setGameState("connecting"); - } - } else if (readyState === ReadyState.CONNECTING) { - setGameState("connecting"); - } else if (readyState === ReadyState.OPEN) { - if (lastJsonMessage !== null) { - console.log(lastJsonMessage.type); - if (lastJsonMessage.type === "player:s2c:prepare") { - const { problem } = lastJsonMessage.data; - setProblem(problem); - console.log("player:c2s:ready"); - sendJsonMessage({ type: "player:c2s:ready" }); - } else if (lastJsonMessage.type === "player:s2c:start") { - if ( - gameState !== "starting" && - gameState !== "gaming" && - gameState !== "finished" - ) { - const { start_at } = lastJsonMessage.data; - setStartedAt(start_at); - const nowSec = Math.floor(Date.now() / 1000); - setTimeLeftSeconds(start_at - nowSec); - setGameState("starting"); - } - } else if (lastJsonMessage.type === "player:s2c:execresult") { - const { score } = lastJsonMessage.data; - if ( - score !== null && - (currentScore === null || score < currentScore) - ) { - setCurrentScore(score); - } - } - } else { - setGameState("waiting"); - console.log("player:c2s:entry"); - sendJsonMessage({ type: "player:c2s:entry" }); - } - } - }, [sendJsonMessage, lastJsonMessage, readyState, gameState, currentScore]); - - if (gameState === "connecting") { - return <GolfPlayAppConnecting />; - } else if (gameState === "waiting") { - return <GolfPlayAppWaiting />; - } else if (gameState === "starting") { - return <GolfPlayAppStarting timeLeft={timeLeftSeconds!} />; - } else if (gameState === "gaming") { - return ( - <GolfPlayAppGaming - problem={problem!.description} - onCodeChange={onCodeChange} - currentScore={currentScore} - /> - ); - } else if (gameState === "finished") { - return <GolfPlayAppFinished />; - } else { - return null; - } + // const socketUrl = `wss://t.nil.ninja/iosdc-japan/2024/sock/golf/${game.game_id}/play?token=${sockToken}`; + const socketUrl = + process.env.NODE_ENV === "development" + ? `ws://localhost:8002/sock/golf/${game.game_id}/play?token=${sockToken}` + : `ws://api-server/sock/golf/${game.game_id}/play?token=${sockToken}`; + + const { sendJsonMessage, lastJsonMessage, readyState } = + useWebSocket<WebSocketMessage>(socketUrl, {}); + + const [gameState, setGameState] = useState<GameState>("connecting"); + + const [problem, setProblem] = useState<Problem | null>(null); + + const [startedAt, setStartedAt] = useState<number | null>(null); + + const [timeLeftSeconds, setTimeLeftSeconds] = useState<number | null>(null); + + useEffect(() => { + if (gameState === "starting" && startedAt !== null) { + const timer1 = setInterval(() => { + setTimeLeftSeconds((prev) => { + if (prev === null) { + return null; + } + if (prev <= 1) { + clearInterval(timer1); + setGameState("gaming"); + return 0; + } + return prev - 1; + }); + }, 1000); + + const timer2 = setInterval(() => { + const nowSec = Math.floor(Date.now() / 1000); + const finishedAt = startedAt + game.duration_seconds; + if (nowSec >= finishedAt) { + clearInterval(timer2); + setGameState("finished"); + } + }, 1000); + + return () => { + clearInterval(timer1); + clearInterval(timer2); + }; + } + }, [gameState, startedAt, game.duration_seconds]); + + const [currentScore, setCurrentScore] = useState<number | null>(null); + + const onCodeChange = useDebouncedCallback((code: string) => { + console.log("player:c2s:code"); + sendJsonMessage({ + type: "player:c2s:code", + data: { code }, + }); + }, 1000); + + if (readyState === ReadyState.UNINSTANTIATED) { + throw new Error("WebSocket is not connected"); + } + + useEffect(() => { + if (readyState === ReadyState.CLOSING || readyState === ReadyState.CLOSED) { + if (gameState !== "finished") { + setGameState("connecting"); + } + } else if (readyState === ReadyState.CONNECTING) { + setGameState("connecting"); + } else if (readyState === ReadyState.OPEN) { + if (lastJsonMessage !== null) { + console.log(lastJsonMessage.type); + if (lastJsonMessage.type === "player:s2c:prepare") { + const { problem } = lastJsonMessage.data; + setProblem(problem); + console.log("player:c2s:ready"); + sendJsonMessage({ type: "player:c2s:ready" }); + } else if (lastJsonMessage.type === "player:s2c:start") { + if ( + gameState !== "starting" && + gameState !== "gaming" && + gameState !== "finished" + ) { + const { start_at } = lastJsonMessage.data; + setStartedAt(start_at); + const nowSec = Math.floor(Date.now() / 1000); + setTimeLeftSeconds(start_at - nowSec); + setGameState("starting"); + } + } else if (lastJsonMessage.type === "player:s2c:execresult") { + const { score } = lastJsonMessage.data; + if ( + score !== null && + (currentScore === null || score < currentScore) + ) { + setCurrentScore(score); + } + } + } else { + setGameState("waiting"); + console.log("player:c2s:entry"); + sendJsonMessage({ type: "player:c2s:entry" }); + } + } + }, [sendJsonMessage, lastJsonMessage, readyState, gameState, currentScore]); + + if (gameState === "connecting") { + return <GolfPlayAppConnecting />; + } else if (gameState === "waiting") { + return <GolfPlayAppWaiting />; + } else if (gameState === "starting") { + return <GolfPlayAppStarting timeLeft={timeLeftSeconds!} />; + } else if (gameState === "gaming") { + return ( + <GolfPlayAppGaming + problem={problem!.description} + onCodeChange={onCodeChange} + currentScore={currentScore} + /> + ); + } else if (gameState === "finished") { + return <GolfPlayAppFinished />; + } else { + return null; + } } diff --git a/frontend/app/components/GolfPlayApps/GolfPlayAppConnecting.tsx b/frontend/app/components/GolfPlayApps/GolfPlayAppConnecting.tsx index 6a954c1..d97131b 100644 --- a/frontend/app/components/GolfPlayApps/GolfPlayAppConnecting.tsx +++ b/frontend/app/components/GolfPlayApps/GolfPlayAppConnecting.tsx @@ -1,11 +1,11 @@ export default function GolfPlayAppConnecting() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4"> - Connecting... - </h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4"> + Connecting... + </h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfPlayApps/GolfPlayAppFinished.tsx b/frontend/app/components/GolfPlayApps/GolfPlayAppFinished.tsx index db06890..c3ef2d4 100644 --- a/frontend/app/components/GolfPlayApps/GolfPlayAppFinished.tsx +++ b/frontend/app/components/GolfPlayApps/GolfPlayAppFinished.tsx @@ -1,9 +1,9 @@ export default function GolfPlayAppFinished() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4">Finished</h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4">Finished</h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfPlayApps/GolfPlayAppGaming.tsx b/frontend/app/components/GolfPlayApps/GolfPlayAppGaming.tsx index fc672f5..75ab18e 100644 --- a/frontend/app/components/GolfPlayApps/GolfPlayAppGaming.tsx +++ b/frontend/app/components/GolfPlayApps/GolfPlayAppGaming.tsx @@ -1,41 +1,41 @@ type Props = { - problem: string; - onCodeChange: (code: string) => void; - currentScore: number | null; + problem: string; + onCodeChange: (code: string) => void; + currentScore: number | null; }; export default function GolfPlayAppGaming({ - problem, - onCodeChange, - currentScore, + problem, + onCodeChange, + currentScore, }: Props) { - const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { - onCodeChange(e.target.value); - }; + const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { + onCodeChange(e.target.value); + }; - return ( - <div className="min-h-screen flex"> - <div className="mx-auto flex min-h-full flex-grow"> - <div className="flex w-1/2 flex-col justify-between p-4"> - <div> - <div className="mb-2 text-xl font-bold">TODO</div> - <div className="text-gray-700">{problem}</div> - </div> - <div className="mb-4 mt-auto"> - <div className="font-semibold text-green-500"> - Score: {currentScore == null ? "-" : `${currentScore}`} - </div> - </div> - </div> - <div className="w-1/2 p-4 flex"> - <div className="flex-grow"> - <textarea - className="h-full w-full rounded-lg border border-gray-300 p-2 focus:outline-none focus:ring-2 focus:ring-blue-500" - onChange={handleTextChange} - ></textarea> - </div> - </div> - </div> - </div> - ); + return ( + <div className="min-h-screen flex"> + <div className="mx-auto flex min-h-full flex-grow"> + <div className="flex w-1/2 flex-col justify-between p-4"> + <div> + <div className="mb-2 text-xl font-bold">TODO</div> + <div className="text-gray-700">{problem}</div> + </div> + <div className="mb-4 mt-auto"> + <div className="font-semibold text-green-500"> + Score: {currentScore == null ? "-" : `${currentScore}`} + </div> + </div> + </div> + <div className="w-1/2 p-4 flex"> + <div className="flex-grow"> + <textarea + className="h-full w-full rounded-lg border border-gray-300 p-2 focus:outline-none focus:ring-2 focus:ring-blue-500" + onChange={handleTextChange} + ></textarea> + </div> + </div> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfPlayApps/GolfPlayAppStarting.tsx b/frontend/app/components/GolfPlayApps/GolfPlayAppStarting.tsx index df179f1..0d60fc9 100644 --- a/frontend/app/components/GolfPlayApps/GolfPlayAppStarting.tsx +++ b/frontend/app/components/GolfPlayApps/GolfPlayAppStarting.tsx @@ -1,15 +1,15 @@ type Props = { - timeLeft: number; + timeLeft: number; }; export default function GolfPlayAppStarting({ timeLeft }: Props) { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4"> - Starting... ({timeLeft} s) - </h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4"> + Starting... ({timeLeft} s) + </h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfPlayApps/GolfPlayAppWaiting.tsx b/frontend/app/components/GolfPlayApps/GolfPlayAppWaiting.tsx index f4fc6c5..a1da33e 100644 --- a/frontend/app/components/GolfPlayApps/GolfPlayAppWaiting.tsx +++ b/frontend/app/components/GolfPlayApps/GolfPlayAppWaiting.tsx @@ -1,584 +1,584 @@ export default function GolfPlayAppWaiting() { - return ( - <> - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4">Waiting...</h1> - </div> - </div> - <style> - {` + return ( + <> + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4">Waiting...</h1> + </div> + </div> + <style> + {` @keyframes changeHeight { 0% { height: 20%; } 50% { height: 100%; } 100% { height: 20%; } } `} - </style> - <div - style={{ - position: "fixed", - bottom: 0, - width: "100%", - display: "flex", - justifyContent: "center", - alignItems: "flex-end", - height: "100px", - margin: "0 2px", - }} - > - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "2.0s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.9s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.8s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.7s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.6s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.1s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.0s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.9s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.8s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.7s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.6s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.1s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.1s", - }} - ></div> + </style> + <div + style={{ + position: "fixed", + bottom: 0, + width: "100%", + display: "flex", + justifyContent: "center", + alignItems: "flex-end", + height: "100px", + margin: "0 2px", + }} + > + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "2.0s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.9s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.8s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.7s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.6s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.1s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.0s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.9s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.8s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.7s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.6s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.1s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.1s", + }} + ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.1s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.1s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.6s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.7s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.8s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "0.9s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.0s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.1s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.2s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.3s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.4s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.5s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.6s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.7s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.8s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "1.9s", - }} - ></div> - <div - style={{ - width: "2%", - margin: "0 2px", - background: - "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", - display: "inline-block", - animation: "changeHeight 1s infinite ease-in-out", - animationDelay: "2.0s", - }} - ></div> - </div> - </> - ); + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.1s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.1s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.6s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.7s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.8s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "0.9s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.0s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.1s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.2s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.3s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.4s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.5s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.6s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.7s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.8s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "1.9s", + }} + ></div> + <div + style={{ + width: "2%", + margin: "0 2px", + background: + "linear-gradient(345deg, rgb(230, 36, 136) 0%, rgb(240, 184, 106) 100%)", + display: "inline-block", + animation: "changeHeight 1s infinite ease-in-out", + animationDelay: "2.0s", + }} + ></div> + </div> + </> + ); } diff --git a/frontend/app/components/GolfWatchApp.client.tsx b/frontend/app/components/GolfWatchApp.client.tsx index 0373944..aefe945 100644 --- a/frontend/app/components/GolfWatchApp.client.tsx +++ b/frontend/app/components/GolfWatchApp.client.tsx @@ -14,126 +14,126 @@ type Game = components["schemas"]["Game"]; type GameState = "connecting" | "waiting" | "starting" | "gaming" | "finished"; export default function GolfWatchApp({ - game, - sockToken, + game, + sockToken, }: { - game: Game; - sockToken: string; + game: Game; + sockToken: string; }) { - // const socketUrl = `wss://t.nil.ninja/iosdc-japan/2024/sock/golf/${game.game_id}/watch?token=${sockToken}`; - const socketUrl = - process.env.NODE_ENV === "development" - ? `ws://localhost:8002/sock/golf/${game.game_id}/watch?token=${sockToken}` - : `ws://api-server/sock/golf/${game.game_id}/watch?token=${sockToken}`; + // const socketUrl = `wss://t.nil.ninja/iosdc-japan/2024/sock/golf/${game.game_id}/watch?token=${sockToken}`; + const socketUrl = + process.env.NODE_ENV === "development" + ? `ws://localhost:8002/sock/golf/${game.game_id}/watch?token=${sockToken}` + : `ws://api-server/sock/golf/${game.game_id}/watch?token=${sockToken}`; - const { lastJsonMessage, readyState } = useWebSocket<WebSocketMessage>( - socketUrl, - {}, - ); + const { lastJsonMessage, readyState } = useWebSocket<WebSocketMessage>( + socketUrl, + {}, + ); - const [gameState, setGameState] = useState<GameState>("connecting"); + const [gameState, setGameState] = useState<GameState>("connecting"); - const [startedAt, setStartedAt] = useState<number | null>(null); + const [startedAt, setStartedAt] = useState<number | null>(null); - const [timeLeftSeconds, setTimeLeftSeconds] = useState<number | null>(null); + const [timeLeftSeconds, setTimeLeftSeconds] = useState<number | null>(null); - useEffect(() => { - if (gameState === "starting" && startedAt !== null) { - const timer1 = setInterval(() => { - setTimeLeftSeconds((prev) => { - if (prev === null) { - return null; - } - if (prev <= 1) { - clearInterval(timer1); - setGameState("gaming"); - return 0; - } - return prev - 1; - }); - }, 1000); + useEffect(() => { + if (gameState === "starting" && startedAt !== null) { + const timer1 = setInterval(() => { + setTimeLeftSeconds((prev) => { + if (prev === null) { + return null; + } + if (prev <= 1) { + clearInterval(timer1); + setGameState("gaming"); + return 0; + } + return prev - 1; + }); + }, 1000); - const timer2 = setInterval(() => { - const nowSec = Math.floor(Date.now() / 1000); - const finishedAt = startedAt + game.duration_seconds; - if (nowSec >= finishedAt) { - clearInterval(timer2); - setGameState("finished"); - } - }, 1000); + const timer2 = setInterval(() => { + const nowSec = Math.floor(Date.now() / 1000); + const finishedAt = startedAt + game.duration_seconds; + if (nowSec >= finishedAt) { + clearInterval(timer2); + setGameState("finished"); + } + }, 1000); - return () => { - clearInterval(timer1); - clearInterval(timer2); - }; - } - }, [gameState, startedAt, game.duration_seconds]); + return () => { + clearInterval(timer1); + clearInterval(timer2); + }; + } + }, [gameState, startedAt, game.duration_seconds]); - const [scoreA, setScoreA] = useState<number | null>(null); - const [scoreB, setScoreB] = useState<number | null>(null); - const [codeA, setCodeA] = useState<string>(""); - const [codeB, setCodeB] = useState<string>(""); + const [scoreA, setScoreA] = useState<number | null>(null); + const [scoreB, setScoreB] = useState<number | null>(null); + const [codeA, setCodeA] = useState<string>(""); + const [codeB, setCodeB] = useState<string>(""); - if (readyState === ReadyState.UNINSTANTIATED) { - throw new Error("WebSocket is not connected"); - } + if (readyState === ReadyState.UNINSTANTIATED) { + throw new Error("WebSocket is not connected"); + } - useEffect(() => { - if (readyState === ReadyState.CLOSING || readyState === ReadyState.CLOSED) { - if (gameState !== "finished") { - setGameState("connecting"); - } - } else if (readyState === ReadyState.CONNECTING) { - setGameState("connecting"); - } else if (readyState === ReadyState.OPEN) { - if (lastJsonMessage !== null) { - console.log(lastJsonMessage.type); - if (lastJsonMessage.type === "watcher:s2c:start") { - if ( - gameState !== "starting" && - gameState !== "gaming" && - gameState !== "finished" - ) { - const { start_at } = lastJsonMessage.data; - setStartedAt(start_at); - const nowSec = Math.floor(Date.now() / 1000); - setTimeLeftSeconds(start_at - nowSec); - setGameState("starting"); - } - } else if (lastJsonMessage.type === "watcher:s2c:code") { - const { player_id, code } = lastJsonMessage.data; - setCodeA(code); - } else if (lastJsonMessage.type === "watcher:s2c:execresult") { - const { score } = lastJsonMessage.data; - if (score !== null && (scoreA === null || score < scoreA)) { - setScoreA(score); - } - } - } else { - setGameState("waiting"); - } - } - }, [lastJsonMessage, readyState, gameState, scoreA]); + useEffect(() => { + if (readyState === ReadyState.CLOSING || readyState === ReadyState.CLOSED) { + if (gameState !== "finished") { + setGameState("connecting"); + } + } else if (readyState === ReadyState.CONNECTING) { + setGameState("connecting"); + } else if (readyState === ReadyState.OPEN) { + if (lastJsonMessage !== null) { + console.log(lastJsonMessage.type); + if (lastJsonMessage.type === "watcher:s2c:start") { + if ( + gameState !== "starting" && + gameState !== "gaming" && + gameState !== "finished" + ) { + const { start_at } = lastJsonMessage.data; + setStartedAt(start_at); + const nowSec = Math.floor(Date.now() / 1000); + setTimeLeftSeconds(start_at - nowSec); + setGameState("starting"); + } + } else if (lastJsonMessage.type === "watcher:s2c:code") { + const { player_id, code } = lastJsonMessage.data; + setCodeA(code); + } else if (lastJsonMessage.type === "watcher:s2c:execresult") { + const { score } = lastJsonMessage.data; + if (score !== null && (scoreA === null || score < scoreA)) { + setScoreA(score); + } + } + } else { + setGameState("waiting"); + } + } + }, [lastJsonMessage, readyState, gameState, scoreA]); - if (gameState === "connecting") { - return <GolfWatchAppConnecting />; - } else if (gameState === "waiting") { - return <GolfWatchAppWaiting />; - } else if (gameState === "starting") { - return <GolfWatchAppStarting timeLeft={timeLeftSeconds!} />; - } else if (gameState === "gaming") { - return ( - <GolfWatchAppGaming - problem={game.problem!.description} - codeA={codeA} - scoreA={scoreA} - codeB={codeB} - scoreB={scoreB} - /> - ); - } else if (gameState === "finished") { - return <GolfWatchAppFinished />; - } else { - return null; - } + if (gameState === "connecting") { + return <GolfWatchAppConnecting />; + } else if (gameState === "waiting") { + return <GolfWatchAppWaiting />; + } else if (gameState === "starting") { + return <GolfWatchAppStarting timeLeft={timeLeftSeconds!} />; + } else if (gameState === "gaming") { + return ( + <GolfWatchAppGaming + problem={game.problem!.description} + codeA={codeA} + scoreA={scoreA} + codeB={codeB} + scoreB={scoreB} + /> + ); + } else if (gameState === "finished") { + return <GolfWatchAppFinished />; + } else { + return null; + } } diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppConnecting.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppConnecting.tsx index b91339a..3704656 100644 --- a/frontend/app/components/GolfWatchApps/GolfWatchAppConnecting.tsx +++ b/frontend/app/components/GolfWatchApps/GolfWatchAppConnecting.tsx @@ -1,11 +1,11 @@ export default function GolfWatchAppConnecting() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4"> - Connecting... - </h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4"> + Connecting... + </h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppFinished.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppFinished.tsx index 866e18a..58cb2df 100644 --- a/frontend/app/components/GolfWatchApps/GolfWatchAppFinished.tsx +++ b/frontend/app/components/GolfWatchApps/GolfWatchAppFinished.tsx @@ -1,9 +1,9 @@ export default function GolfWatchAppFinished() { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4">Finished</h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4">Finished</h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx index 10d68fe..22277f8 100644 --- a/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx +++ b/frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx @@ -1,41 +1,41 @@ type Props = { - problem: string; - codeA: string; - scoreA: number | null; - codeB: string; - scoreB: number | null; + problem: string; + codeA: string; + scoreA: number | null; + codeB: string; + scoreB: number | null; }; export default function GolfWatchAppGaming({ - problem, - codeA, - scoreA, - codeB, - scoreB, + problem, + codeA, + scoreA, + codeB, + scoreB, }: Props) { - return ( - <div style={{ display: "flex", flexDirection: "column" }}> - <div style={{ display: "flex", flex: 1, justifyContent: "center" }}> - <div>{problem}</div> - </div> - <div style={{ display: "flex", flex: 3 }}> - <div style={{ display: "flex", flex: 3, flexDirection: "column" }}> - <div style={{ flex: 1, justifyContent: "center" }}>{scoreA}</div> - <div style={{ flex: 3 }}> - <pre> - <code>{codeA}</code> - </pre> - </div> - </div> - <div style={{ display: "flex", flex: 3, flexDirection: "column" }}> - <div style={{ flex: 1, justifyContent: "center" }}>{scoreB}</div> - <div style={{ flex: 3 }}> - <pre> - <code>{codeB}</code> - </pre> - </div> - </div> - </div> - </div> - ); + return ( + <div style={{ display: "flex", flexDirection: "column" }}> + <div style={{ display: "flex", flex: 1, justifyContent: "center" }}> + <div>{problem}</div> + </div> + <div style={{ display: "flex", flex: 3 }}> + <div style={{ display: "flex", flex: 3, flexDirection: "column" }}> + <div style={{ flex: 1, justifyContent: "center" }}>{scoreA}</div> + <div style={{ flex: 3 }}> + <pre> + <code>{codeA}</code> + </pre> + </div> + </div> + <div style={{ display: "flex", flex: 3, flexDirection: "column" }}> + <div style={{ flex: 1, justifyContent: "center" }}>{scoreB}</div> + <div style={{ flex: 3 }}> + <pre> + <code>{codeB}</code> + </pre> + </div> + </div> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppStarting.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppStarting.tsx index 3c9919c..ef72cec 100644 --- a/frontend/app/components/GolfWatchApps/GolfWatchAppStarting.tsx +++ b/frontend/app/components/GolfWatchApps/GolfWatchAppStarting.tsx @@ -1,15 +1,15 @@ type Props = { - timeLeft: number; + timeLeft: number; }; export default function GolfWatchAppStarting({ timeLeft }: Props) { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <h1 className="text-4xl font-bold text-black-600 mb-4"> - Starting... ({timeLeft} s) - </h1> - </div> - </div> - ); + return ( + <div className="min-h-screen bg-gray-100 flex items-center justify-center"> + <div className="text-center"> + <h1 className="text-4xl font-bold text-black-600 mb-4"> + Starting... ({timeLeft} s) + </h1> + </div> + </div> + ); } diff --git a/frontend/app/components/GolfWatchApps/GolfWatchAppWaiting.tsx b/frontend/app/components/GolfWatchApps/GolfWatchAppWaiting.tsx index 6733b3b..d58ec19 100644 --- a/frontend/app/components/GolfWatchApps/GolfWatchAppWaiting.tsx +++ b/frontend/app/components/GolfWatchApps/GolfWatchAppWaiting.tsx @@ -1,3 +1,3 @@ export default function GolfWatchAppWaiting() { - return <div>Waiting...</div>; + return <div>Waiting...</div>; } |
