Skip to content

Commit

Permalink
refactor(types): leaderboard types
Browse files Browse the repository at this point in the history
move to shared types (#4774)
add types to ape client (#4786)
  • Loading branch information
Miodec committed Feb 8, 2024
1 parent b5465be commit 15c6978
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 90 deletions.
4 changes: 2 additions & 2 deletions backend/__tests__/dal/leaderboards.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe("LeaderboardsDal", () => {
"15",
"english",
0
)) as MonkeyTypes.LeaderboardEntry[];
)) as SharedTypes.LeaderboardEntry[];

//THEN
const lb = result.map((it) => _.omit(it, ["_id"]));
Expand All @@ -70,7 +70,7 @@ describe("LeaderboardsDal", () => {
"60",
"english",
0
)) as MonkeyTypes.LeaderboardEntry[];
)) as SharedTypes.LeaderboardEntry[];

//THEN
const lb = result.map((it) => _.omit(it, ["_id"]));
Expand Down
10 changes: 5 additions & 5 deletions backend/src/dal/leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ export async function get(
language: string,
skip: number,
limit = 50
): Promise<MonkeyTypes.LeaderboardEntry[] | false> {
): Promise<SharedTypes.LeaderboardEntry[] | false> {
if (leaderboardUpdating[`${language}_${mode}_${mode2}`]) return false;
if (limit > 50 || limit <= 0) limit = 50;
if (skip < 0) skip = 0;
const preset = await db
.collection<MonkeyTypes.LeaderboardEntry>(
.collection<SharedTypes.LeaderboardEntry>(
`leaderboards.${language}.${mode}.${mode2}`
)
.find()
Expand All @@ -31,7 +31,7 @@ export async function get(
interface GetRankResponse {
count: number;
rank: number | null;
entry: MonkeyTypes.LeaderboardEntry | null;
entry: SharedTypes.LeaderboardEntry | null;
}

export async function getRank(
Expand All @@ -42,7 +42,7 @@ export async function getRank(
): Promise<GetRankResponse | false> {
if (leaderboardUpdating[`${language}_${mode}_${mode2}`]) return false;
const entry = await db
.collection<MonkeyTypes.LeaderboardEntry>(
.collection<SharedTypes.LeaderboardEntry>(
`leaderboards.${language}.${mode}.${mode2}`
)
.findOne({ uid });
Expand Down Expand Up @@ -71,7 +71,7 @@ export async function update(
const start1 = performance.now();
const lb = db
.collection<MonkeyTypes.User>("users")
.aggregate<MonkeyTypes.LeaderboardEntry>(
.aggregate<SharedTypes.LeaderboardEntry>(
[
{
$match: {
Expand Down
4 changes: 2 additions & 2 deletions backend/src/jobs/update-leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ const RECENT_AGE_MILLISECONDS = RECENT_AGE_MINUTES * 60 * 1000;

async function getTop10(
leaderboardTime: string
): Promise<MonkeyTypes.LeaderboardEntry[]> {
): Promise<SharedTypes.LeaderboardEntry[]> {
return (await LeaderboardsDAL.get(
"time",
leaderboardTime,
"english",
0,
10
)) as MonkeyTypes.LeaderboardEntry[]; //can do that because gettop10 will not be called during an update
)) as SharedTypes.LeaderboardEntry[]; //can do that because gettop10 will not be called during an update
}

async function updateLeaderboardAndNotifyChanges(
Expand Down
18 changes: 0 additions & 18 deletions backend/src/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,24 +139,6 @@ declare namespace MonkeyTypes {
personalBests: SharedTypes.PersonalBests;
}

interface LeaderboardEntry {
_id: ObjectId;
acc: number;
consistency: number;
difficulty: SharedTypes.Config.Difficulty;
lazyMode: boolean;
language: string;
punctuation: boolean;
raw: number;
wpm: number;
timestamp: number;
uid: string;
name: string;
rank: number;
badges?: Badge[];
badgeId?: number;
}

interface CustomTheme {
_id: ObjectId;
name: string;
Expand Down
21 changes: 6 additions & 15 deletions frontend/src/ts/ape/endpoints/leaderboards.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
const BASE_PATH = "/leaderboards";

interface LeaderboardQuery {
language: string;
mode: SharedTypes.Config.Mode;
mode2: string;
isDaily?: boolean;
daysBefore?: number;
}

interface LeadeboardQueryWithPagination extends LeaderboardQuery {
skip?: number;
limit?: number;
}

export default class Leaderboards {
constructor(private httpClient: Ape.HttpClient) {
this.httpClient = httpClient;
}

async get(query: LeadeboardQueryWithPagination): Ape.EndpointResponse {
async get(
query: Ape.Leaderboards.QueryWithPagination
): Ape.EndpointResponse<Ape.Leaderboards.GetLeaderboard> {
const {
language,
mode,
Expand All @@ -44,7 +33,9 @@ export default class Leaderboards {
return await this.httpClient.get(endpointPath, { searchQuery });
}

async getRank(query: LeaderboardQuery): Ape.EndpointResponse {
async getRank(
query: Ape.Leaderboards.Query
): Ape.EndpointResponse<Ape.Leaderboards.GetRank> {
const { language, mode, mode2, isDaily, daysBefore } = query;
const includeDaysBefore = (isDaily ?? false) && (daysBefore ?? 0) > 0;

Expand Down
25 changes: 25 additions & 0 deletions frontend/src/ts/ape/types/leaderboards.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// for some reason when using the dot notaion, the types are not being recognized as used
declare namespace Ape.Leaderboards {
interface Query {
language: string;
mode: SharedTypes.Config.Mode;
mode2: string;
isDaily?: boolean;
daysBefore?: number;
}

interface QueryWithPagination extends Query {
skip?: number;
limit?: number;
}

type GetLeaderboard = SharedTypes.LeaderboardEntry[];

type GetRank = {
minWpm: number;
count: number;
rank: number | null;
entry: SharedTypes.LeaderboardEntry | null;
};
}
57 changes: 29 additions & 28 deletions frontend/src/ts/elements/leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,14 @@ let showingYesterday = false;
type LbKey = "15" | "60";

let currentData: {
[key in LbKey]: MonkeyTypes.LeaderboardEntry[];
[key in LbKey]: SharedTypes.LeaderboardEntry[];
} = {
"15": [],
"60": [],
};

interface GetRankResponse {
minWpm: number;
count: number;
rank: number | null;
entry: MonkeyTypes.LeaderboardEntry | null;
}

let currentRank: {
[key in LbKey]: GetRankResponse | Record<string, never>;
[key in LbKey]: Ape.Leaderboards.GetRank | Record<string, never>;
} = {
"15": {},
"60": {},
Expand Down Expand Up @@ -438,7 +431,7 @@ async function update(): Promise<void> {

const timeModes = ["15", "60"];

const leaderboardRequests = timeModes.map(async (mode2) => {
const lbDataRequests = timeModes.map(async (mode2) => {
return Ape.leaderboards.get({
language: currentLanguage,
mode: "time",
Expand All @@ -447,8 +440,11 @@ async function update(): Promise<void> {
});
});

const lbRankRequests: Promise<
Ape.HttpClientResponse<Ape.Leaderboards.GetRank>
>[] = [];
if (Auth?.currentUser) {
leaderboardRequests.push(
lbRankRequests.push(
...timeModes.map(async (mode2) => {
return Ape.leaderboards.getRank({
language: currentLanguage,
Expand All @@ -460,26 +456,28 @@ async function update(): Promise<void> {
);
}

const responses = await Promise.all(leaderboardRequests);
const responses = await Promise.all(lbDataRequests);
const rankResponses = await Promise.all(lbRankRequests);

const failedResponse = responses.find((response) => response.status !== 200);
if (failedResponse) {
const atLeastOneFailed =
responses.find((response) => response.status !== 200) ||
rankResponses.find((response) => response.status !== 200);
if (atLeastOneFailed) {
hideLoader("15");
hideLoader("60");
return Notifications.add(
"Failed to load leaderboards: " + failedResponse.message,
"Failed to load leaderboards: " + atLeastOneFailed.message,
-1
);
}

const [lb15Data, lb60Data, lb15Rank, lb60Rank] = responses.map(
(response) => response.data
);
const [lb15Data, lb60Data] = responses.map((response) => response.data);
const [lb15Rank, lb60Rank] = rankResponses.map((response) => response.data);

currentData["15"] = lb15Data;
currentData["60"] = lb60Data;
currentRank["15"] = lb15Rank;
currentRank["60"] = lb60Rank;
if (lb15Data !== undefined && lb15Data !== null) currentData["15"] = lb15Data;
if (lb60Data !== undefined && lb60Data !== null) currentData["60"] = lb60Data;
if (lb15Rank !== undefined && lb15Rank !== null) currentRank["15"] = lb15Rank;
if (lb60Rank !== undefined && lb60Rank !== null) currentRank["60"] = lb60Rank;

const leaderboardKeys: LbKey[] = ["15", "60"];

Expand Down Expand Up @@ -535,9 +533,9 @@ async function requestMore(lb: LbKey, prepend = false): Promise<void> {
limit: limitVal,
...getDailyLeaderboardQuery(),
});
const data: MonkeyTypes.LeaderboardEntry[] = response.data;
const data = response.data;

if (response.status !== 200 || data.length === 0) {
if (response.status !== 200 || data === null || data.length === 0) {
hideLoader(lb);
requesting[lb] = false;
return;
Expand Down Expand Up @@ -575,7 +573,7 @@ async function requestNew(lb: LbKey, skip: number): Promise<void> {
skip,
...getDailyLeaderboardQuery(),
});
const data: MonkeyTypes.LeaderboardEntry[] = response.data;
const data = response.data;

if (response.status === 503) {
Notifications.add(
Expand All @@ -588,7 +586,7 @@ async function requestNew(lb: LbKey, skip: number): Promise<void> {
clearBody(lb);
currentData[lb] = [];
currentAvatars[lb] = [];
if (response.status !== 200 || data.length === 0) {
if (response.status !== 200 || data === null || data.length === 0) {
hideLoader(lb);
return;
}
Expand All @@ -604,11 +602,14 @@ async function requestNew(lb: LbKey, skip: number): Promise<void> {
}

async function getAvatarUrls(
data: MonkeyTypes.LeaderboardEntry[]
data: Ape.Leaderboards.GetLeaderboard
): Promise<(string | null)[]> {
return Promise.allSettled(
data.map(async (entry) =>
Misc.getDiscordAvatarUrl(entry.discordId, entry.discordAvatar)
Misc.getDiscordAvatarUrl(
entry.discordId ?? undefined,
entry.discordAvatar ?? undefined
)
)
).then((promises) => {
return promises.map((promise) => {
Expand Down
21 changes: 1 addition & 20 deletions frontend/src/ts/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,29 +200,10 @@ declare namespace MonkeyTypes {

interface Leaderboards {
time: {
[key in 15 | 60]: LeaderboardEntry[];
[key in 15 | 60]: SharedTypes.LeaderboardEntry[];
};
}

interface LeaderboardEntry {
difficulty: string;
timestamp: number;
language: string;
wpm: number;
consistency: number | "-";
punctuation: boolean;
acc: number;
raw: number;
uid?: string;
name: string;
discordId?: string;
discordAvatar?: string;
badgeId?: number;
rank: number;
count?: number;
hidden?: boolean;
}

interface QuoteRatings {
[language: string]: {
[id: number]: number;
Expand Down
16 changes: 16 additions & 0 deletions shared-types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,4 +438,20 @@ declare namespace SharedTypes {
name: string;
config: SharedTypes.ConfigPreset;
}

interface LeaderboardEntry {
_id: string;
wpm: number;
acc: number;
timestamp: number;
raw: number;
consistency: number | "-";
uid: string;
name: string;
discordId: string | null | undefined;
discordAvatar: string | null | undefined;
rank: number;
badgeId: number | null;
hidden?: boolean;
}
}

0 comments on commit 15c6978

Please sign in to comment.