aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app/components')
-rw-r--r--frontend/app/components/GolfPlayApp.client.tsx260
-rw-r--r--frontend/app/components/GolfPlayApps/GolfPlayAppConnecting.tsx18
-rw-r--r--frontend/app/components/GolfPlayApps/GolfPlayAppFinished.tsx14
-rw-r--r--frontend/app/components/GolfPlayApps/GolfPlayAppGaming.tsx68
-rw-r--r--frontend/app/components/GolfPlayApps/GolfPlayAppStarting.tsx20
-rw-r--r--frontend/app/components/GolfPlayApps/GolfPlayAppWaiting.tsx1150
-rw-r--r--frontend/app/components/GolfWatchApp.client.tsx218
-rw-r--r--frontend/app/components/GolfWatchApps/GolfWatchAppConnecting.tsx18
-rw-r--r--frontend/app/components/GolfWatchApps/GolfWatchAppFinished.tsx14
-rw-r--r--frontend/app/components/GolfWatchApps/GolfWatchAppGaming.tsx70
-rw-r--r--frontend/app/components/GolfWatchApps/GolfWatchAppStarting.tsx20
-rw-r--r--frontend/app/components/GolfWatchApps/GolfWatchAppWaiting.tsx2
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>;
}