diff --git a/src/App.tsx b/src/App.tsx index a3a7c5cf..5a72b763 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,7 +26,7 @@ export function App({ router, queryClient, persister }: AppProps) { persistOptions={{ persister, maxAge, - buster: "1", // API version + buster: "2", // API version }} > diff --git a/src/helpers/session.unit.test.ts b/src/helpers/session.unit.test.ts index d4651c97..c068acec 100644 --- a/src/helpers/session.unit.test.ts +++ b/src/helpers/session.unit.test.ts @@ -29,6 +29,7 @@ const makePlayerDataPIT = (gamesPlayed: number, experience: number): PlayerDataP doubles: makeStatsPIT(0), threes: makeStatsPIT(0), fours: makeStatsPIT(gamesPlayed), + "4v4": makeStatsPIT(0), }); describe(addExtrapolatedSessions, () => { diff --git a/src/mocks/data.ts b/src/mocks/data.ts index 25f27ecb..3657ca76 100644 --- a/src/mocks/data.ts +++ b/src/mocks/data.ts @@ -94,7 +94,8 @@ export const makePlayerDataPIT = ( doubles: makeStatsPIT(multiplier), threes: makeStatsPIT(multiplier), fours: makeStatsPIT(multiplier), - overall: makeStatsPIT(multiplier * 4), + "4v4": makeStatsPIT(multiplier), + overall: makeStatsPIT(multiplier * 5), }); export const makeSession = ( @@ -163,6 +164,7 @@ export const makeWrappedResponse = (uuid: string, year: number) => { doubles: { highest: 8, when: startTime }, threes: { highest: 6, when: startTime }, fours: { highest: 10, when: startTime }, + "4v4": { highest: 2, when: startTime }, }, finalKillStreaks: { overall: { highest: 20, when: startTime }, @@ -170,6 +172,7 @@ export const makeWrappedResponse = (uuid: string, year: number) => { doubles: { highest: 12, when: startTime }, threes: { highest: 10, when: startTime }, fours: { highest: 15, when: startTime }, + "4v4": { highest: 3, when: startTime }, }, sessionCoverage: { gamesPlayedPercentage: 0.85, diff --git a/src/queries/playerdata.ts b/src/queries/playerdata.ts index aa7577ec..fc7b3741 100644 --- a/src/queries/playerdata.ts +++ b/src/queries/playerdata.ts @@ -19,6 +19,7 @@ export interface APIPlayerDataPIT { readonly doubles: APIStatsPIT; readonly threes: APIStatsPIT; readonly fours: APIStatsPIT; + readonly "4v4": APIStatsPIT; readonly overall: APIStatsPIT; } @@ -43,6 +44,7 @@ export interface PlayerDataPIT { readonly doubles: StatsPIT; readonly threes: StatsPIT; readonly fours: StatsPIT; + readonly "4v4": StatsPIT; readonly overall: StatsPIT; } @@ -54,5 +56,6 @@ export const apiToPlayerDataPIT = (apiPlayerData: APIPlayerDataPIT): PlayerDataP doubles: apiPlayerData.doubles, threes: apiPlayerData.threes, fours: apiPlayerData.fours, + "4v4": apiPlayerData["4v4"], overall: apiPlayerData.overall, }); diff --git a/src/queries/wrapped.ts b/src/queries/wrapped.ts index 63e6639c..752f1c67 100644 --- a/src/queries/wrapped.ts +++ b/src/queries/wrapped.ts @@ -50,6 +50,7 @@ interface APISessionStats { readonly doubles: StreakInfo; readonly threes: StreakInfo; readonly fours: StreakInfo; + readonly "4v4": StreakInfo; }; readonly finalKillStreaks: { readonly overall: StreakInfo; @@ -57,6 +58,7 @@ interface APISessionStats { readonly doubles: StreakInfo; readonly threes: StreakInfo; readonly fours: StreakInfo; + readonly "4v4": StreakInfo; }; readonly sessionCoverage: { readonly gamesPlayedPercentage: number; @@ -99,6 +101,7 @@ interface SessionStats { readonly doubles: StreakInfo; readonly threes: StreakInfo; readonly fours: StreakInfo; + readonly "4v4": StreakInfo; }; readonly finalKillStreaks: { readonly overall: StreakInfo; @@ -106,6 +109,7 @@ interface SessionStats { readonly doubles: StreakInfo; readonly threes: StreakInfo; readonly fours: StreakInfo; + readonly "4v4": StreakInfo; }; readonly sessionCoverage: { readonly gamesPlayedPercentage: number; diff --git a/src/routes/wrapped/$uuid.tsx b/src/routes/wrapped/$uuid.tsx index c5fc221f..b1d5b607 100644 --- a/src/routes/wrapped/$uuid.tsx +++ b/src/routes/wrapped/$uuid.tsx @@ -929,7 +929,7 @@ const Streaks: React.FC = ({ wrappedData }) => { const { sessionStats } = wrappedData; if (!sessionStats) return null; - const modes = ["overall", "solo", "doubles", "threes", "fours"] as const; + const modes = ["overall", "solo", "doubles", "threes", "fours", "4v4"] as const; return ( <> diff --git a/src/routes/wrapped/-uuid.ui.test.tsx b/src/routes/wrapped/-uuid.ui.test.tsx index 706a8ba7..aef7dc3a 100644 --- a/src/routes/wrapped/-uuid.ui.test.tsx +++ b/src/routes/wrapped/-uuid.ui.test.tsx @@ -417,6 +417,18 @@ describe("Wrapped detail page", () => { kills: 200, deaths: 100, }, + "4v4": { + winstreak: 3, + gamesPlayed: 100, + wins: 60, + losses: 40, + bedsBroken: 80, + bedsLost: 30, + finalKills: 150, + finalDeaths: 50, + kills: 200, + deaths: 100, + }, overall: { winstreak: 12, gamesPlayed: 400, @@ -482,6 +494,18 @@ describe("Wrapped detail page", () => { kills: 600, deaths: 300, }, + "4v4": { + winstreak: 9, + gamesPlayed: 300, + wins: 180, + losses: 120, + bedsBroken: 240, + bedsLost: 90, + finalKills: 450, + finalDeaths: 150, + kills: 600, + deaths: 300, + }, overall: { winstreak: 36, gamesPlayed: 1200, diff --git a/src/stats/keys.ts b/src/stats/keys.ts index b3eceb08..81ca5237 100644 --- a/src/stats/keys.ts +++ b/src/stats/keys.ts @@ -31,6 +31,7 @@ export const ALL_GAMEMODE_KEYS = [ "doubles", "threes", "fours", + "4v4", "overall", ] as const; export type GamemodeKey = (typeof ALL_GAMEMODE_KEYS)[number]; diff --git a/src/stats/labels.ts b/src/stats/labels.ts index 90d2938c..45dff2bc 100644 --- a/src/stats/labels.ts +++ b/src/stats/labels.ts @@ -117,6 +117,9 @@ export const getGamemodeLabel = (gamemode: GamemodeKey, capitalize = false): str case "fours": { return capitalize ? "Fours" : "fours"; } + case "4v4": { + return "4v4"; + } } }; diff --git a/src/stats/progression.unit.test.ts b/src/stats/progression.unit.test.ts index 8344147e..ad1b9c7b 100644 --- a/src/stats/progression.unit.test.ts +++ b/src/stats/progression.unit.test.ts @@ -137,6 +137,7 @@ class PlayerDataBuilder { doubles: { ...emptyStats }, threes: { ...emptyStats }, fours: { ...emptyStats }, + "4v4": { ...emptyStats }, overall: { ...emptyStats }, }; } @@ -159,6 +160,7 @@ class PlayerDataBuilder { doubles: { ...this.player.doubles }, threes: { ...this.player.threes }, fours: { ...this.player.fours }, + "4v4": { ...this.player["4v4"] }, overall: { ...this.player.overall }, }; } diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts index b430b3dc..1a172a1e 100644 --- a/src/theme/tokens.ts +++ b/src/theme/tokens.ts @@ -86,7 +86,7 @@ export const LIGHT_TOKENS: SchemeTokens = { }; /** - * Per-gamemode accent colours for the four real modes. Used for chart strokes + * Per-gamemode accent colours for the real modes. Used for chart strokes * and legend dots so a gamemode keeps a stable identity colour across the app. * Shared across light and dark. "overall" is intentionally absent — it resolves * to the scheme's `primary` colour (added in the theme), so the aggregate @@ -97,6 +97,7 @@ export const GAMEMODE_COLORS: Record, string> = doubles: "#06b6d4", threes: "#22c55e", fours: "#f59e0b", + "4v4": "#ef4444", }; /**