aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app')
-rw-r--r--frontend/app/.server/api/schema.d.ts53
-rw-r--r--frontend/app/components/GolfPlayApp.tsx14
-rw-r--r--frontend/app/components/GolfWatchApp.tsx14
-rw-r--r--frontend/app/routes/golf.$gameId.play.tsx49
-rw-r--r--frontend/app/routes/golf.$gameId.watch.tsx49
5 files changed, 143 insertions, 36 deletions
diff --git a/frontend/app/.server/api/schema.d.ts b/frontend/app/.server/api/schema.d.ts
index 1d3313e..cd409f7 100644
--- a/frontend/app/.server/api/schema.d.ts
+++ b/frontend/app/.server/api/schema.d.ts
@@ -64,6 +64,59 @@ export interface paths {
patch?: never;
trace?: never;
};
+ "/token": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ /** Get a short-lived access token */
+ get: {
+ parameters: {
+ query?: never;
+ header: {
+ Authorization: string;
+ };
+ path?: never;
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description Successfully authenticated */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": {
+ /** @example xxxxx.xxxxx.xxxxx */
+ token: string;
+ };
+ };
+ };
+ /** @description Forbidden */
+ 403: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": {
+ /** @example Forbidden operation */
+ message: string;
+ };
+ };
+ };
+ };
+ };
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
"/games": {
parameters: {
query?: never;
diff --git a/frontend/app/components/GolfPlayApp.tsx b/frontend/app/components/GolfPlayApp.tsx
index 13afb22..3cb512a 100644
--- a/frontend/app/components/GolfPlayApp.tsx
+++ b/frontend/app/components/GolfPlayApp.tsx
@@ -15,12 +15,18 @@ type Problem = components["schemas"]["Problem"];
type GameState = "connecting" | "waiting" | "starting" | "gaming" | "finished";
-export default function GolfPlayApp({ game }: { game: Game }) {
- // const socketUrl = `wss://t.nil.ninja/iosdc/2024/sock/golf/${game.game_id}/play`;
+export default function GolfPlayApp({
+ game,
+ sockToken,
+}: {
+ game: Game;
+ sockToken: string;
+}) {
+ // const socketUrl = `wss://t.nil.ninja/iosdc/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`
- : `ws://api-server/sock/golf/${game.game_id}/play`;
+ ? `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, {});
diff --git a/frontend/app/components/GolfWatchApp.tsx b/frontend/app/components/GolfWatchApp.tsx
index bcd1f0f..00ad005 100644
--- a/frontend/app/components/GolfWatchApp.tsx
+++ b/frontend/app/components/GolfWatchApp.tsx
@@ -14,12 +14,18 @@ type Problem = components["schemas"]["Problem"];
type GameState = "connecting" | "waiting" | "starting" | "gaming" | "finished";
-export default function GolfWatchApp({ game }: { game: Game }) {
- // const socketUrl = `wss://t.nil.ninja/iosdc/2024/sock/golf/${game.game_id}/play`;
+export default function GolfWatchApp({
+ game,
+ sockToken,
+}: {
+ game: Game;
+ sockToken: string;
+}) {
+ // const socketUrl = `wss://t.nil.ninja/iosdc/2024/sock/golf/${game.game_id}/watch?token=${sockToken}`;
const socketUrl =
process.env.NODE_ENV === "development"
- ? `ws://localhost:8002/sock/golf/${game.game_id}/play`
- : `ws://api-server/sock/golf/${game.game_id}/play`;
+ ? `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,
diff --git a/frontend/app/routes/golf.$gameId.play.tsx b/frontend/app/routes/golf.$gameId.play.tsx
index bda563f..78ce585 100644
--- a/frontend/app/routes/golf.$gameId.play.tsx
+++ b/frontend/app/routes/golf.$gameId.play.tsx
@@ -8,26 +8,47 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
const { token } = await isAuthenticated(request, {
failureRedirect: "/login",
});
- const { data, error } = await apiClient.GET("/games/{game_id}", {
- params: {
- path: {
- game_id: Number(params.gameId),
+
+ const fetchGame = async () => {
+ const { data, error } = await apiClient.GET("/games/{game_id}", {
+ params: {
+ path: {
+ game_id: Number(params.gameId),
+ },
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
},
- header: {
- Authorization: `Bearer ${token}`,
+ });
+ if (error) {
+ throw new Error(error.message);
+ }
+ return data;
+ };
+
+ const fetchSockToken = async () => {
+ const { data, error } = await apiClient.GET("/token", {
+ params: {
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
},
- },
- });
- if (error) {
- throw new Error(error.message);
- }
+ });
+ if (error) {
+ throw new Error(error.message);
+ }
+ return data.token;
+ };
+
+ const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]);
return {
- game: data,
+ game,
+ sockToken,
};
}
export default function GolfPlay() {
- const { game } = useLoaderData<typeof loader>();
+ const { game, sockToken } = useLoaderData<typeof loader>();
- return <GolfPlayApp game={game} />;
+ return <GolfPlayApp game={game} sockToken={sockToken} />;
}
diff --git a/frontend/app/routes/golf.$gameId.watch.tsx b/frontend/app/routes/golf.$gameId.watch.tsx
index e1cb5d7..28c17cc 100644
--- a/frontend/app/routes/golf.$gameId.watch.tsx
+++ b/frontend/app/routes/golf.$gameId.watch.tsx
@@ -8,26 +8,47 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
const { token } = await isAuthenticated(request, {
failureRedirect: "/login",
});
- const { data, error } = await apiClient.GET("/games/{game_id}", {
- params: {
- path: {
- game_id: Number(params.gameId),
+
+ const fetchGame = async () => {
+ const { data, error } = await apiClient.GET("/games/{game_id}", {
+ params: {
+ path: {
+ game_id: Number(params.gameId),
+ },
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
},
- header: {
- Authorization: `Bearer ${token}`,
+ });
+ if (error) {
+ throw new Error(error.message);
+ }
+ return data;
+ };
+
+ const fetchSockToken = async () => {
+ const { data, error } = await apiClient.GET("/token", {
+ params: {
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
},
- },
- });
- if (error) {
- throw new Error(error.message);
- }
+ });
+ if (error) {
+ throw new Error(error.message);
+ }
+ return data.token;
+ };
+
+ const [game, sockToken] = await Promise.all([fetchGame(), fetchSockToken()]);
return {
- game: data,
+ game,
+ sockToken,
};
}
export default function GolfWatch() {
- const { game } = useLoaderData<typeof loader>();
+ const { game, sockToken } = useLoaderData<typeof loader>();
- return <GolfWatchApp game={game} />;
+ return <GolfWatchApp game={game} sockToken={sockToken} />;
}