mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-25 00:52:21 +00:00
Account Modal - Games Tab (#4473)
Continuation of https://github.com/openfrontio/infra/pull/386, adds play games sessions <img width="971" height="771" alt="image" src="https://github.com/user-attachments/assets/42c6bcbb-d690-4cd1-b859-3299a03f4350" /> - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory regression is found: w.o.n --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
evanpelle
co-authored by
Claude Opus 4.8
parent
de08d9814f
commit
580460c969
@@ -3,8 +3,12 @@ import { z } from "zod";
|
||||
import type { NewsItem } from "../core/ApiSchemas";
|
||||
import {
|
||||
NewsItemSchema,
|
||||
PlayerGameModeFilter,
|
||||
PlayerGameTypeFilter,
|
||||
PlayerProfile,
|
||||
PlayerProfileSchema,
|
||||
PublicPlayerGamesResponse,
|
||||
PublicPlayerGamesResponseSchema,
|
||||
RankedLeaderboardResponse,
|
||||
RankedLeaderboardResponseSchema,
|
||||
UserMeResponse,
|
||||
@@ -53,6 +57,54 @@ export async function fetchPlayerById(
|
||||
}
|
||||
}
|
||||
|
||||
// GET /public/player/:publicId/games — keyset-paginated personal game history.
|
||||
// Public (no auth). `filter` (mode bucket) and `type` (game-type split) are
|
||||
// orthogonal; `cursor` is the opaque token from the previous response's
|
||||
// nextCursor — round-trip verbatim, never construct it.
|
||||
export async function fetchPublicPlayerGames(
|
||||
publicId: string,
|
||||
opts: {
|
||||
filter?: PlayerGameModeFilter;
|
||||
type?: PlayerGameTypeFilter;
|
||||
cursor?: string;
|
||||
} = {},
|
||||
): Promise<PublicPlayerGamesResponse | { error: "failed" }> {
|
||||
try {
|
||||
const url = new URL(
|
||||
`${getApiBase()}/public/player/${encodeURIComponent(publicId)}/games`,
|
||||
);
|
||||
if (opts.filter) url.searchParams.set("filter", opts.filter);
|
||||
if (opts.type) url.searchParams.set("type", opts.type);
|
||||
if (opts.cursor) url.searchParams.set("cursor", opts.cursor);
|
||||
|
||||
const res = await fetch(url.toString(), {
|
||||
headers: { Accept: "application/json" },
|
||||
});
|
||||
if (!res.ok) {
|
||||
console.warn(
|
||||
"fetchPublicPlayerGames: unexpected status",
|
||||
res.status,
|
||||
res.statusText,
|
||||
);
|
||||
return { error: "failed" };
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
const parsed = PublicPlayerGamesResponseSchema.safeParse(json);
|
||||
if (!parsed.success) {
|
||||
console.warn(
|
||||
"fetchPublicPlayerGames: Zod validation failed",
|
||||
parsed.error,
|
||||
);
|
||||
return { error: "failed" };
|
||||
}
|
||||
return parsed.data;
|
||||
} catch (err) {
|
||||
console.warn("fetchPublicPlayerGames: request failed", err);
|
||||
return { error: "failed" };
|
||||
}
|
||||
}
|
||||
|
||||
let __userMe: Promise<UserMeResponse | false> | null = null;
|
||||
export async function getUserMe(): Promise<UserMeResponse | false> {
|
||||
if (__userMe !== null) {
|
||||
|
||||
Reference in New Issue
Block a user