diff --git a/src/assets/league-tier-backgrounds/diamond_tournament_1.svg b/src/assets/league-tier-backgrounds/diamond_tournament_1.svg
new file mode 100644
index 0000000..d747d3c
--- /dev/null
+++ b/src/assets/league-tier-backgrounds/diamond_tournament_1.svg
@@ -0,0 +1,32 @@
+
diff --git a/src/assets/league-tier-backgrounds/diamond_tournament_2.svg b/src/assets/league-tier-backgrounds/diamond_tournament_2.svg
new file mode 100644
index 0000000..13fde48
--- /dev/null
+++ b/src/assets/league-tier-backgrounds/diamond_tournament_2.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/league-tier-backgrounds/diamond_tournament_3.svg b/src/assets/league-tier-backgrounds/diamond_tournament_3.svg
new file mode 100644
index 0000000..31a4cd3
--- /dev/null
+++ b/src/assets/league-tier-backgrounds/diamond_tournament_3.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/entities/models/user.ts b/src/entities/models/user.ts
index f4418f1..5f9fe49 100644
--- a/src/entities/models/user.ts
+++ b/src/entities/models/user.ts
@@ -10,12 +10,12 @@ export class User {
public static fromResponse(
response: UserDto,
- leaderboardTier?: number,
+ leaderboardInfo?: LeaderBoardInfo,
): User {
- return new User(response, leaderboardTier);
+ return new User(response, leaderboardInfo);
}
- private constructor(user: UserDto, leaderboardTier?: number) {
+ private constructor(user: UserDto, leaderboardInfo?: LeaderBoardInfo) {
this.name = user.name;
this.username = user.username;
this.pictureUrl = user.picture.replace("//", "https://") + "/xxlarge";
@@ -26,8 +26,8 @@ export class User {
if (currentCourse) {
this.currentCourse = CurrentCourse.fromResponse(currentCourse);
}
- if (leaderboardTier !== undefined && this.streak.days > 0) {
- this.currentLeaderboardTier = mapLeaderboardTier(leaderboardTier);
+ if (leaderboardInfo !== undefined && this.streak.days > 0) {
+ this.currentLeaderboardTier = mapLeaderboardTier(leaderboardInfo);
}
}
}
@@ -81,9 +81,28 @@ class CurrentCourse {
}
}
-const mapLeaderboardTier = (tier: number): Tier => {
- // Map the leaderboard tier to the enum value, any value higher than the max tier will be mapped to the max tier.
- return Math.min(tier, Tier.DIAMOND);
+const mapLeaderboardTier = (leaderBoardInfo: LeaderBoardInfo): Tier => {
+ let tier = Math.min(leaderBoardInfo.tier, Tier.DIAMOND);
+
+ if (tier >= Tier.DIAMOND) {
+ switch (leaderBoardInfo.numWins ?? 0) {
+ case 1:
+ tier = Tier.DIAMOND_TOURNAMENT_1;
+ break;
+ case 2:
+ tier = Tier.DIAMOND_TOURNAMENT_2;
+ break;
+ case 3:
+ tier = Tier.DIAMOND_TOURNAMENT_3;
+ break;
+ case 0:
+ default:
+ tier = Tier.DIAMOND;
+ break;
+ }
+ }
+
+ return tier;
};
export enum Tier {
@@ -97,4 +116,12 @@ export enum Tier {
PEARL = 7,
OBSIDIAN = 8,
DIAMOND = 9,
+ DIAMOND_TOURNAMENT_1 = 10,
+ DIAMOND_TOURNAMENT_2 = 11,
+ DIAMOND_TOURNAMENT_3 = 12,
}
+
+export type LeaderBoardInfo = {
+ tier: number;
+ numWins: number;
+};
diff --git a/src/hooks/useUserData.ts b/src/hooks/useUserData.ts
index 72655fd..d757ef2 100644
--- a/src/hooks/useUserData.ts
+++ b/src/hooks/useUserData.ts
@@ -1,7 +1,7 @@
import { useQuery } from "@tanstack/react-query";
import { fetchWithProxy } from "../utilities";
import { DuolingoUserResponse, UserDto } from "../entities/responses";
-import { User } from "../entities/models";
+import { LeaderBoardInfo, User } from "../entities/models";
import { DuolingoLeaderboardResponse } from "../entities/responses/duolingo-leaderboard-response";
/**
@@ -44,15 +44,18 @@ const fetchUser = async (userName: string): Promise => {
const fetchLeaderboardTier = async (
userId: number,
-): Promise => {
+): Promise => {
try {
const rawUserResponse = await fetchWithProxy(
`https://duolingo-leaderboards-prod.duolingo.com/leaderboards/7d9f5dd1-8423-491a-91f2-2532052038ce/users/${userId}`,
);
const typedUserResponse =
(await rawUserResponse.json()) as DuolingoLeaderboardResponse;
- const leaderboardTier = typedUserResponse.tier;
- return leaderboardTier;
+
+ return {
+ tier: typedUserResponse.tier,
+ numWins: typedUserResponse.stats.num_wins,
+ };
} catch (error) {
console.error("Error fetching leaderboard tier", error);
return undefined;
diff --git a/src/utilities/league-tier-background/determine-league-background.ts b/src/utilities/league-tier-background/determine-league-background.ts
index 2d952c0..048fd07 100644
--- a/src/utilities/league-tier-background/determine-league-background.ts
+++ b/src/utilities/league-tier-background/determine-league-background.ts
@@ -9,32 +9,47 @@ import leagueAmethystSvg from "../../assets/league-tier-backgrounds/amethyst.svg
import leaguePearlSvg from "../../assets/league-tier-backgrounds/pearl.svg";
import leagueObsidianSvg from "../../assets/league-tier-backgrounds/obsidian.svg";
import leagueDiamondSvg from "../../assets/league-tier-backgrounds/diamond.svg";
+import leagueDiamondTournament1Svg from "../../assets/league-tier-backgrounds/diamond_tournament_1.svg";
+import leagueDiamondTournament2Svg from "../../assets/league-tier-backgrounds/diamond_tournament_2.svg";
+import leagueDiamondTournament3Svg from "../../assets/league-tier-backgrounds/diamond_tournament_3.svg";
export const getLeagueBackgroundImage = (
- currentLeaderboardTier?: number,
+ currentLeaderboardTier?: Tier,
useUrl = false,
): string => {
- switch (Tier[currentLeaderboardTier ?? -1]) {
- case "BRONZE":
+ switch (currentLeaderboardTier) {
+ case Tier.BRONZE:
return useUrl ? createUrl(leagueBronzeSvg) : leagueBronzeSvg;
- case "SILVER":
+ case Tier.SILVER:
return useUrl ? createUrl(leagueSilverSvg) : leagueSilverSvg;
- case "GOLD":
+ case Tier.GOLD:
return useUrl ? createUrl(leagueGoldSvg) : leagueGoldSvg;
- case "SAPPHIRE":
+ case Tier.SAPPHIRE:
return useUrl ? createUrl(leagueSapphireSvg) : leagueSapphireSvg;
- case "RUBY":
+ case Tier.RUBY:
return useUrl ? createUrl(leagueRubySvg) : leagueRubySvg;
- case "EMERALD":
+ case Tier.EMERALD:
return useUrl ? createUrl(leagueEmeraldSvg) : leagueEmeraldSvg;
- case "AMETHYST":
+ case Tier.AMETHYST:
return useUrl ? createUrl(leagueAmethystSvg) : leagueAmethystSvg;
- case "PEARL":
+ case Tier.PEARL:
return useUrl ? createUrl(leaguePearlSvg) : leaguePearlSvg;
- case "OBSIDIAN":
+ case Tier.OBSIDIAN:
return useUrl ? createUrl(leagueObsidianSvg) : leagueObsidianSvg;
- case "DIAMOND":
+ case Tier.DIAMOND:
return useUrl ? createUrl(leagueDiamondSvg) : leagueDiamondSvg;
+ case Tier.DIAMOND_TOURNAMENT_1:
+ return useUrl
+ ? createUrl(leagueDiamondTournament1Svg)
+ : leagueDiamondTournament1Svg;
+ case Tier.DIAMOND_TOURNAMENT_2:
+ return useUrl
+ ? createUrl(leagueDiamondTournament2Svg)
+ : leagueDiamondTournament2Svg;
+ case Tier.DIAMOND_TOURNAMENT_3:
+ return useUrl
+ ? createUrl(leagueDiamondTournament3Svg)
+ : leagueDiamondTournament3Svg;
default:
return "";
}