mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 15:26:15 +08:00
impr: show min speed if not qualified for daily lb (HyperDanisH, Miodec) (#4519)
This commit is contained in:
parent
87d3362560
commit
0086398073
|
@ -11,13 +11,22 @@ interface DailyLeaderboardEntry {
|
|||
acc: number;
|
||||
consistency: number;
|
||||
timestamp: number;
|
||||
rank?: number;
|
||||
count?: number;
|
||||
discordAvatar?: string;
|
||||
discordId?: string;
|
||||
badgeId?: number;
|
||||
}
|
||||
|
||||
interface GetRankResponse {
|
||||
minWpm: number;
|
||||
count: number;
|
||||
rank: number | null;
|
||||
entry: DailyLeaderboardEntry | null;
|
||||
}
|
||||
|
||||
interface LbEntryWithRank extends DailyLeaderboardEntry {
|
||||
rank: number;
|
||||
}
|
||||
|
||||
const dailyLeaderboardNamespace = "monkeytype:dailyleaderboard";
|
||||
const scoresNamespace = `${dailyLeaderboardNamespace}:scores`;
|
||||
const resultsNamespace = `${dailyLeaderboardNamespace}:results`;
|
||||
|
@ -115,7 +124,7 @@ export class DailyLeaderboard {
|
|||
minRank: number,
|
||||
maxRank: number,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<DailyLeaderboardEntry[]> {
|
||||
): Promise<LbEntryWithRank[]> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !dailyLeaderboardsConfig.enabled) {
|
||||
return [];
|
||||
|
@ -134,7 +143,7 @@ export class DailyLeaderboard {
|
|||
"false"
|
||||
);
|
||||
|
||||
const resultsWithRanks: DailyLeaderboardEntry[] = results.map(
|
||||
const resultsWithRanks: LbEntryWithRank[] = results.map(
|
||||
(resultJSON, index) => ({
|
||||
...JSON.parse(resultJSON),
|
||||
rank: minRank + index + 1,
|
||||
|
@ -147,7 +156,7 @@ export class DailyLeaderboard {
|
|||
public async getRank(
|
||||
uid: string,
|
||||
dailyLeaderboardsConfig: MonkeyTypes.Configuration["dailyLeaderboards"]
|
||||
): Promise<DailyLeaderboardEntry | null> {
|
||||
): Promise<GetRankResponse | null> {
|
||||
const connection = RedisClient.getConnection();
|
||||
if (!connection || !dailyLeaderboardsConfig.enabled) {
|
||||
return null;
|
||||
|
@ -156,21 +165,32 @@ export class DailyLeaderboard {
|
|||
const { leaderboardScoresKey, leaderboardResultsKey } =
|
||||
this.getTodaysLeaderboardKeys();
|
||||
|
||||
const [[, rank], [, count], [, result]] = await connection
|
||||
const [[, rank], [, count], [, result], [, minScore]] = await connection
|
||||
.multi()
|
||||
.zrevrank(leaderboardScoresKey, uid)
|
||||
.zcard(leaderboardScoresKey)
|
||||
.hget(leaderboardResultsKey, uid)
|
||||
.zrange(leaderboardScoresKey, 0, 0, "WITHSCORES")
|
||||
.exec();
|
||||
|
||||
const minWpm =
|
||||
minScore.length > 0 ? parseInt(minScore[1]?.slice(1, 6)) / 100 : 0;
|
||||
if (rank === null) {
|
||||
return null;
|
||||
return {
|
||||
minWpm,
|
||||
count: count ?? 0,
|
||||
rank: null,
|
||||
entry: null,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
rank: rank + 1,
|
||||
minWpm,
|
||||
count: count ?? 0,
|
||||
...JSON.parse(result ?? "null"),
|
||||
rank: rank + 1,
|
||||
entry: {
|
||||
...JSON.parse(result ?? "null"),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,15 @@ let currentData: {
|
|||
"60": [],
|
||||
};
|
||||
|
||||
interface GetRankResponse {
|
||||
minWpm: number;
|
||||
count: number;
|
||||
rank: number | null;
|
||||
entry: MonkeyTypes.LeaderboardEntry | null;
|
||||
}
|
||||
|
||||
let currentRank: {
|
||||
[key in LbKey]: MonkeyTypes.LeaderboardEntry | Record<string, never>;
|
||||
[key in LbKey]: GetRankResponse | Record<string, never>;
|
||||
} = {
|
||||
"15": {},
|
||||
"60": {},
|
||||
|
@ -159,18 +166,28 @@ function updateFooter(lb: LbKey): void {
|
|||
</tr>
|
||||
`);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
|
||||
const lbRank = currentRank[lb];
|
||||
|
||||
if (
|
||||
currentTimeRange === "daily" &&
|
||||
lbRank !== null &&
|
||||
lbRank.minWpm === undefined
|
||||
) {
|
||||
//old response format
|
||||
$(`#leaderboardsWrapper table.${side} tfoot`).html(`
|
||||
<tr>
|
||||
<td colspan="6" style="text-align:center;">Not qualified</>
|
||||
<td colspan="6" style="text-align:center;">Looks like the server returned data in a new format, please refresh</>
|
||||
</tr>
|
||||
`);
|
||||
return;
|
||||
}
|
||||
|
||||
let toppercent;
|
||||
if (currentTimeRange === "allTime" && currentRank[lb]) {
|
||||
if (currentTimeRange === "allTime" && lbRank && lbRank?.rank) {
|
||||
const num = Misc.roundTo2(
|
||||
(currentRank[lb]["rank"] / (currentRank[lb].count as number)) * 100
|
||||
(lbRank.rank / (currentRank[lb].count as number)) * 100
|
||||
);
|
||||
if (currentRank[lb]["rank"] === 1) {
|
||||
toppercent = "GOAT";
|
||||
|
@ -180,12 +197,12 @@ function updateFooter(lb: LbKey): void {
|
|||
toppercent = `<br><span class="sub">${toppercent}</span>`;
|
||||
}
|
||||
|
||||
if (currentRank[lb]) {
|
||||
const entry = currentRank[lb];
|
||||
const entry = lbRank?.entry;
|
||||
if (entry) {
|
||||
const date = new Date(entry.timestamp);
|
||||
$(`#leaderboardsWrapper table.${side} tfoot`).html(`
|
||||
<tr>
|
||||
<td>${entry.rank}</td>
|
||||
<td>${lbRank.rank}</td>
|
||||
<td><span class="top">You</span>${toppercent ? toppercent : ""}</td>
|
||||
<td class="alignRight">${typingSpeedUnit.fromWpm(entry.wpm).toFixed(2)}<br>
|
||||
<div class="sub">${entry.acc.toFixed(2)}%</div></td>
|
||||
|
@ -199,6 +216,18 @@ function updateFooter(lb: LbKey): void {
|
|||
<div class='sub'>${format(date, "HH:mm")}</div></td>
|
||||
</tr>
|
||||
`);
|
||||
} else if (currentTimeRange === "daily") {
|
||||
$(`#leaderboardsWrapper table.${side} tfoot`).html(`
|
||||
<tr>
|
||||
<td colspan="6" style="text-align:center;">Not qualified ${`(min speed required: ${currentRank[lb]?.minWpm} wpm)`}</>
|
||||
</tr>
|
||||
`);
|
||||
} else {
|
||||
$(`#leaderboardsWrapper table.${side} tfoot`).html(`
|
||||
<tr>
|
||||
<td colspan="6" style="text-align:center;">Not qualified</>
|
||||
</tr>
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,10 +243,11 @@ function checkLbMemory(lb: LbKey): void {
|
|||
|
||||
const memory = DB.getSnapshot()?.lbMemory?.time?.[lb]?.["english"] ?? 0;
|
||||
|
||||
if (currentRank[lb]) {
|
||||
const difference = memory - currentRank[lb].rank;
|
||||
const rank = currentRank[lb]?.rank;
|
||||
if (rank) {
|
||||
const difference = memory - rank;
|
||||
if (difference > 0) {
|
||||
DB.updateLbMemory("time", lb, "english", currentRank[lb].rank, true);
|
||||
DB.updateLbMemory("time", lb, "english", rank, true);
|
||||
if (memory !== 0) {
|
||||
$(`#leaderboardsWrapper table.${side} tfoot tr td .top`).append(
|
||||
` (<i class="fas fa-fw fa-angle-up"></i>${Math.abs(
|
||||
|
@ -226,7 +256,7 @@ function checkLbMemory(lb: LbKey): void {
|
|||
);
|
||||
}
|
||||
} else if (difference < 0) {
|
||||
DB.updateLbMemory("time", lb, "english", currentRank[lb].rank, true);
|
||||
DB.updateLbMemory("time", lb, "english", rank, true);
|
||||
if (memory !== 0) {
|
||||
$(`#leaderboardsWrapper table.${side} tfoot tr td .top`).append(
|
||||
` (<i class="fas fa-fw fa-angle-down"></i>${Math.abs(
|
||||
|
@ -473,6 +503,7 @@ async function update(): Promise<void> {
|
|||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [lb15Data, lb60Data, lb15Rank, lb60Rank] = responses.map(
|
||||
(response) => response.data
|
||||
);
|
||||
|
@ -581,7 +612,7 @@ async function requestNew(lb: LbKey, skip: number): Promise<void> {
|
|||
hideLoader(lb);
|
||||
}
|
||||
|
||||
function show(): void {
|
||||
export function show(): void {
|
||||
if (!ConnectionState.get()) {
|
||||
Notifications.add("You can't view leaderboards while offline", 0);
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue