mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-25 11:39:51 +01:00
feat: split id and score
This commit is contained in:
1 parent
0d1eb9b12e
commit
933c468e2d
1 file changed
+133
-126
+133
-126
@@ -15,7 +15,6 @@ import { produce } from 'immer';
|
|||||||
import { debounce, range } from 'lodash';
|
import { debounce, range } from 'lodash';
|
||||||
import { ChangeEvent, useEffect, useRef, useState } from 'react';
|
import { ChangeEvent, useEffect, useRef, useState } from 'react';
|
||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { BlitzkriegRatingsLeaderboardEntry } from '../../../../scripts/buildRatingsLeaderboard';
|
|
||||||
import { RatingsInfo, RatingsPlayer } from '../../../commands/ratings';
|
import { RatingsInfo, RatingsPlayer } from '../../../commands/ratings';
|
||||||
import PageWrapper from '../../../components/PageWrapper';
|
import PageWrapper from '../../../components/PageWrapper';
|
||||||
import { LEAGUES } from '../../../constants/leagues';
|
import { LEAGUES } from '../../../constants/leagues';
|
||||||
@@ -46,18 +45,16 @@ interface NameCacheEntry {
|
|||||||
clan?: string;
|
clan?: string;
|
||||||
}
|
}
|
||||||
type NameCache = Record<Region, Record<number, NameCacheEntry | null>>;
|
type NameCache = Record<Region, Record<number, NameCacheEntry | null>>;
|
||||||
type PlayersCache = Record<
|
type LeaderboardCache = Record<Region, Record<number, Record<number, number>>>;
|
||||||
Region,
|
|
||||||
Record<number, Record<number, BlitzkriegRatingsLeaderboardEntry>>
|
|
||||||
>;
|
|
||||||
type InfoCache = Record<Region, Record<number, RatingsInfo | undefined>>;
|
type InfoCache = Record<Region, Record<number, RatingsInfo | undefined>>;
|
||||||
|
type ScoreCache = Record<Region, Record<number, Record<number, number>>>;
|
||||||
|
|
||||||
const useNameCache = create<NameCache>(() => ({
|
const useNameCache = create<NameCache>(() => ({
|
||||||
asia: {},
|
asia: {},
|
||||||
com: {},
|
com: {},
|
||||||
eu: {},
|
eu: {},
|
||||||
}));
|
}));
|
||||||
const usePlayersCache = create<PlayersCache>(() => ({
|
const useLeaderboardCache = create<LeaderboardCache>(() => ({
|
||||||
asia: {},
|
asia: {},
|
||||||
com: {},
|
com: {},
|
||||||
eu: {},
|
eu: {},
|
||||||
@@ -67,6 +64,11 @@ const useInfoCache = create<InfoCache>(() => ({
|
|||||||
com: {},
|
com: {},
|
||||||
eu: {},
|
eu: {},
|
||||||
}));
|
}));
|
||||||
|
const useScoreCache = create<ScoreCache>(() => ({
|
||||||
|
asia: {},
|
||||||
|
com: {},
|
||||||
|
eu: {},
|
||||||
|
}));
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [region, setRegion] = useState<Region>('com');
|
const [region, setRegion] = useState<Region>('com');
|
||||||
@@ -90,9 +92,10 @@ export default function Page() {
|
|||||||
const [latestArchivedSeasonNumber, setLatestArchivedSeasonNumber] = useState<
|
const [latestArchivedSeasonNumber, setLatestArchivedSeasonNumber] = useState<
|
||||||
number | null
|
number | null
|
||||||
>(null);
|
>(null);
|
||||||
|
const scores = useScoreCache()[region][season];
|
||||||
|
|
||||||
const names = useNameCache();
|
const names = useNameCache();
|
||||||
const players = usePlayersCache();
|
const leaderboard = useLeaderboardCache();
|
||||||
|
|
||||||
const positionInput = useRef<HTMLInputElement>(null);
|
const positionInput = useRef<HTMLInputElement>(null);
|
||||||
const scoreInput = useRef<HTMLInputElement>(null);
|
const scoreInput = useRef<HTMLInputElement>(null);
|
||||||
@@ -121,94 +124,91 @@ export default function Page() {
|
|||||||
}, [season, region]);
|
}, [season, region]);
|
||||||
// initial leagues caching for current season
|
// initial leagues caching for current season
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (season in players[region]) return;
|
if (season in leaderboard[region]) return;
|
||||||
|
|
||||||
if (season === 0) {
|
if (season === 0) {
|
||||||
(async () => {
|
(async () => {
|
||||||
const newNameCache: Record<number, NameCacheEntry> = {};
|
const results = (
|
||||||
const results = await Promise.all(
|
await Promise.all(
|
||||||
range(0, 5).map(async (league: number) => {
|
range(0, 5).map((league: number) => {
|
||||||
const leaguePlayers = await getRatingsLeague(region, league);
|
return getRatingsLeague(region, league);
|
||||||
leaguePositionCache.current[league] =
|
}),
|
||||||
leaguePlayers.result[0].number - 1;
|
)
|
||||||
leaguePlayers.result.forEach((player) => {
|
)
|
||||||
newNameCache[player.spa_id] = {
|
.map(({ result }) => result)
|
||||||
nickname: player.nickname,
|
.flat();
|
||||||
clan: player.clan_tag,
|
|
||||||
};
|
useLeaderboardCache.setState(
|
||||||
|
produce((draft: LeaderboardCache) => {
|
||||||
|
if (!(season in draft[region])) draft[region][season] = {};
|
||||||
|
|
||||||
|
results.forEach((result) => {
|
||||||
|
draft[region][season][result.number - 1] = result.spa_id;
|
||||||
});
|
});
|
||||||
|
|
||||||
return leaguePlayers.result.reduce<
|
|
||||||
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
|
||||||
>(
|
|
||||||
(accumulator, player) => ({
|
|
||||||
...accumulator,
|
|
||||||
|
|
||||||
[player.number - 1]: {
|
|
||||||
id: player.spa_id,
|
|
||||||
score: player.score,
|
|
||||||
} satisfies BlitzkriegRatingsLeaderboardEntry,
|
|
||||||
}),
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
const newPlayers = results.reduce<
|
|
||||||
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
|
||||||
>(
|
|
||||||
(accumulator, result) => ({
|
|
||||||
...accumulator,
|
|
||||||
...result,
|
|
||||||
}),
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
usePlayersCache.setState(
|
|
||||||
produce((draft: PlayersCache) => {
|
|
||||||
draft[region][season] = {
|
|
||||||
...draft[region][season],
|
|
||||||
...newPlayers,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
useNameCache.setState(
|
useNameCache.setState(
|
||||||
produce((draft: NameCache) => {
|
produce((draft: NameCache) => {
|
||||||
draft[region] = { ...draft[region], ...newNameCache };
|
results.forEach((result) => {
|
||||||
|
draft[region][result.spa_id] = {
|
||||||
|
nickname: result.nickname,
|
||||||
|
clan: result.clan_tag,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
useScoreCache.setState(
|
||||||
|
produce((draft: ScoreCache) => {
|
||||||
|
if (!(season in draft[region])) draft[region][season] = {};
|
||||||
|
|
||||||
|
results.forEach((result) => {
|
||||||
|
draft[region][season][result.spa_id] = result.score;
|
||||||
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
})();
|
})();
|
||||||
} else {
|
} else {
|
||||||
getArchivedRatingsLeaderboard(region, season).then((result) => {
|
getArchivedRatingsLeaderboard(region, season).then((results) => {
|
||||||
usePlayersCache.setState(
|
useLeaderboardCache.setState(
|
||||||
produce((draft: PlayersCache) => {
|
produce((draft: LeaderboardCache) => {
|
||||||
draft[region][season] = {
|
if (!(season in draft[region])) draft[region][season] = {};
|
||||||
...draft[region][season],
|
|
||||||
...result,
|
results.forEach((result, index) => {
|
||||||
};
|
draft[region][season][index] = result.id;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
useScoreCache.setState(
|
||||||
|
produce((draft: ScoreCache) => {
|
||||||
|
if (!(season in draft[region])) draft[region][season] = {};
|
||||||
|
|
||||||
|
results.forEach((result) => {
|
||||||
|
draft[region][season][result.id] = result.score;
|
||||||
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [season in players[region]]);
|
}, [season in leaderboard[region]]);
|
||||||
// 2nd page caching for current season
|
// 2nd page caching for current season
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
season === 0 &&
|
season === 0 &&
|
||||||
players !== null &&
|
leaderboard !== null &&
|
||||||
players[region][season] &&
|
leaderboard[region][season] &&
|
||||||
0 in players[region][season]
|
0 in leaderboard[region][season]
|
||||||
) {
|
) {
|
||||||
cacheNeighbors(players[region][season][0].id, ROWS_PER_PAGE * 3);
|
cacheNeighbors(leaderboard[region][season][0], ROWS_PER_PAGE * 3);
|
||||||
}
|
}
|
||||||
}, [players[region]?.[season] && 0 in players[region][season]]);
|
}, [leaderboard[region]?.[season] && 0 in leaderboard[region][season]]);
|
||||||
// neighboring page caching for all seasons
|
// neighboring page caching for all seasons
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ratingsInfo || ratingsInfo?.detail) return;
|
if (!ratingsInfo || ratingsInfo?.detail) return;
|
||||||
|
|
||||||
if (season === 0) {
|
if (season === 0) {
|
||||||
const middleIndex = Math.round(page * ROWS_PER_PAGE + ROWS_PER_PAGE / 2);
|
const middleIndex = Math.round(page * ROWS_PER_PAGE + ROWS_PER_PAGE / 2);
|
||||||
if (!(middleIndex in players[region][season])) return;
|
if (!(middleIndex in leaderboard[region][season])) return;
|
||||||
const middleId = players[region][season][middleIndex].id;
|
const middleId = leaderboard[region][season][middleIndex];
|
||||||
cacheNeighbors(middleId, ROWS_PER_PAGE * 3);
|
cacheNeighbors(middleId, ROWS_PER_PAGE * 3);
|
||||||
} else {
|
} else {
|
||||||
const ids = range(
|
const ids = range(
|
||||||
@@ -218,7 +218,7 @@ export default function Page() {
|
|||||||
(page + 1) * ROWS_PER_PAGE + ROWS_PER_PAGE,
|
(page + 1) * ROWS_PER_PAGE + ROWS_PER_PAGE,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.map((index) => players[region][season][index].id)
|
.map((index) => leaderboard[region][season][index])
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.filter((id) => !(id in names[region]));
|
.filter((id) => !(id in names[region]));
|
||||||
|
|
||||||
@@ -244,7 +244,8 @@ export default function Page() {
|
|||||||
region,
|
region,
|
||||||
season,
|
season,
|
||||||
ratingsInfo?.detail,
|
ratingsInfo?.detail,
|
||||||
players[region][season] !== undefined && 0 in players[region][season],
|
leaderboard[region][season] !== undefined &&
|
||||||
|
0 in leaderboard[region][season],
|
||||||
]);
|
]);
|
||||||
// latest archived season number caching
|
// latest archived season number caching
|
||||||
useEffect(() => {}, [
|
useEffect(() => {}, [
|
||||||
@@ -258,8 +259,8 @@ export default function Page() {
|
|||||||
size: number,
|
size: number,
|
||||||
): Promise<RatingsPlayer[]> {
|
): Promise<RatingsPlayer[]> {
|
||||||
const radius = Math.round(size / 2);
|
const radius = Math.round(size / 2);
|
||||||
const targetPosition = Object.entries(players[region][season]).find(
|
const targetPosition = Object.entries(leaderboard[region][season]).find(
|
||||||
([, player]) => id === player.id,
|
([, player]) => id === player,
|
||||||
)?.[0];
|
)?.[0];
|
||||||
|
|
||||||
if (targetPosition !== undefined) {
|
if (targetPosition !== undefined) {
|
||||||
@@ -271,7 +272,7 @@ export default function Page() {
|
|||||||
position <= targetPositionAsNumber + radius;
|
position <= targetPositionAsNumber + radius;
|
||||||
position++
|
position++
|
||||||
) {
|
) {
|
||||||
isMissing = !(position in players[region][season]);
|
isMissing = !(position in leaderboard[region][season]);
|
||||||
if (isMissing) break;
|
if (isMissing) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,28 +280,32 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const seedingPlayerPosition = parseInt(
|
const seedingPlayerPosition = parseInt(
|
||||||
Object.entries(players[region][season]).find(
|
Object.entries(leaderboard[region][season]).find(
|
||||||
([, player]) => id === player.id,
|
([, player]) => id === player,
|
||||||
)![0],
|
)![0],
|
||||||
);
|
);
|
||||||
const { neighbors } = await getRatingsNeighbors(region, id, size, true);
|
const { neighbors } = await getRatingsNeighbors(region, id, size, true);
|
||||||
|
|
||||||
usePlayersCache.setState(
|
useLeaderboardCache.setState(
|
||||||
produce((draft: PlayersCache) => {
|
produce((draft: LeaderboardCache) => {
|
||||||
neighbors.forEach((neighbor, neighborIndex) => {
|
neighbors.forEach((neighbor, neighborIndex) => {
|
||||||
// const position = neighbor.number - 1;
|
|
||||||
const position = neighborIndex - radius + seedingPlayerPosition;
|
const position = neighborIndex - radius + seedingPlayerPosition;
|
||||||
|
|
||||||
if (!(position in draft[region][season])) {
|
if (!(position in draft[region][season])) {
|
||||||
draft[region][season][position] = {
|
draft[region][season][position] = neighbor.spa_id;
|
||||||
id: neighbor.spa_id,
|
}
|
||||||
score: neighbor.score,
|
});
|
||||||
} satisfies BlitzkriegRatingsLeaderboardEntry;
|
}),
|
||||||
|
);
|
||||||
|
useScoreCache.setState(
|
||||||
|
produce((draft: ScoreCache) => {
|
||||||
|
neighbors.forEach((neighbor, neighborIndex) => {
|
||||||
|
if (!(neighbor.spa_id in draft[region][season])) {
|
||||||
|
draft[region][season][neighbor.spa_id] = neighbor.score;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
useNameCache.setState(
|
useNameCache.setState(
|
||||||
produce((draft: NameCache) => {
|
produce((draft: NameCache) => {
|
||||||
neighbors.forEach((neighbor) => {
|
neighbors.forEach((neighbor) => {
|
||||||
@@ -325,8 +330,8 @@ export default function Page() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (season === 0) {
|
if (season === 0) {
|
||||||
const playerEntries = Object.entries(players[region][season]);
|
const playerEntries = Object.entries(leaderboard[region][season]);
|
||||||
let closestPlayer: BlitzkriegRatingsLeaderboardEntry | null = null;
|
let closestPlayerId: number | null = null;
|
||||||
let closestPosition: number | null = null;
|
let closestPosition: number | null = null;
|
||||||
let closestPositionDistance = Infinity;
|
let closestPositionDistance = Infinity;
|
||||||
|
|
||||||
@@ -337,11 +342,11 @@ export default function Page() {
|
|||||||
if (distance < closestPositionDistance) {
|
if (distance < closestPositionDistance) {
|
||||||
closestPositionDistance = distance;
|
closestPositionDistance = distance;
|
||||||
closestPosition = position;
|
closestPosition = position;
|
||||||
closestPlayer = player;
|
closestPlayerId = player;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (closestPlayer === null || closestPosition === null) return;
|
if (closestPlayerId === null || closestPosition === null) return;
|
||||||
|
|
||||||
if (closestPositionDistance === 0) {
|
if (closestPositionDistance === 0) {
|
||||||
setHighlightedPlayer({ type: 'position', position: targetPosition });
|
setHighlightedPlayer({ type: 'position', position: targetPosition });
|
||||||
@@ -352,8 +357,7 @@ export default function Page() {
|
|||||||
|
|
||||||
// 1 going down and -1 going up
|
// 1 going down and -1 going up
|
||||||
const loadingDirection = Math.sign(targetPosition - closestPosition);
|
const loadingDirection = Math.sign(targetPosition - closestPosition);
|
||||||
let seedingPlayer = (closestPlayer as BlitzkriegRatingsLeaderboardEntry)
|
let seedingPlayer = closestPlayerId as number;
|
||||||
.id;
|
|
||||||
let targetPositionAcquired = false;
|
let targetPositionAcquired = false;
|
||||||
let neighbors: RatingsPlayer[];
|
let neighbors: RatingsPlayer[];
|
||||||
|
|
||||||
@@ -385,7 +389,7 @@ export default function Page() {
|
|||||||
} else {
|
} else {
|
||||||
setPage(Math.floor(targetPosition / ROWS_PER_PAGE));
|
setPage(Math.floor(targetPosition / ROWS_PER_PAGE));
|
||||||
|
|
||||||
if (players) {
|
if (leaderboard) {
|
||||||
setHighlightedPlayer({
|
setHighlightedPlayer({
|
||||||
type: 'position',
|
type: 'position',
|
||||||
position: targetPosition,
|
position: targetPosition,
|
||||||
@@ -399,25 +403,25 @@ export default function Page() {
|
|||||||
const targetScore = scoreInput.current!.valueAsNumber;
|
const targetScore = scoreInput.current!.valueAsNumber;
|
||||||
|
|
||||||
if (season === 0) {
|
if (season === 0) {
|
||||||
const playerEntries = Object.entries(players[region][season]);
|
const playerEntries = Object.entries(leaderboard[region][season]);
|
||||||
let closestPlayer: BlitzkriegRatingsLeaderboardEntry | null = null;
|
let closestId: number | null = null;
|
||||||
let closestScore: number | null = null;
|
let closestScore: number | null = null;
|
||||||
let closestScoreDistance = Infinity;
|
let closestScoreDistance = Infinity;
|
||||||
let closesIndex = -1;
|
let closesIndex = -1;
|
||||||
|
|
||||||
playerEntries.forEach(([positionAsString, player], index) => {
|
playerEntries.forEach(([positionAsString, id]) => {
|
||||||
const position = parseInt(positionAsString);
|
const position = parseInt(positionAsString);
|
||||||
const distance = Math.abs(player.score - targetScore);
|
const distance = Math.abs(scores[id] - targetScore);
|
||||||
|
|
||||||
if (distance < closestScoreDistance) {
|
if (distance < closestScoreDistance) {
|
||||||
closestScoreDistance = distance;
|
closestScoreDistance = distance;
|
||||||
closestScore = player.score;
|
closestScore = scores[id];
|
||||||
closestPlayer = player;
|
closestId = id;
|
||||||
closesIndex = position;
|
closesIndex = position;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (closestPlayer === null || closestScore === null) return;
|
if (closestId === null || closestScore === null) return;
|
||||||
|
|
||||||
if (closestScoreDistance === 0) {
|
if (closestScoreDistance === 0) {
|
||||||
setHighlightedPlayer({ type: 'id', id: closesIndex });
|
setHighlightedPlayer({ type: 'id', id: closesIndex });
|
||||||
@@ -427,16 +431,15 @@ export default function Page() {
|
|||||||
const loadingDirection = Math.sign(closestScore - targetScore);
|
const loadingDirection = Math.sign(closestScore - targetScore);
|
||||||
let targetPlayer: RatingsPlayer;
|
let targetPlayer: RatingsPlayer;
|
||||||
let scoreAcquired = false;
|
let scoreAcquired = false;
|
||||||
let seedingPlayer = closestPlayer as BlitzkriegRatingsLeaderboardEntry;
|
let seedingId = closestId as number;
|
||||||
|
let seedingScore = scores[seedingId];
|
||||||
|
|
||||||
setLoadingProgress([0, closestScoreDistance]);
|
setLoadingProgress([0, closestScoreDistance]);
|
||||||
while (!scoreAcquired) {
|
while (!scoreAcquired) {
|
||||||
const neighbors = await cacheNeighbors(seedingPlayer.id, SEEDING_SIZE);
|
const neighbors = await cacheNeighbors(seedingId, SEEDING_SIZE);
|
||||||
const seedingNeighbor = neighbors.at(loadingDirection === 1 ? -1 : 0)!;
|
const seedingNeighbor = neighbors.at(loadingDirection === 1 ? -1 : 0)!;
|
||||||
seedingPlayer = {
|
seedingId = seedingNeighbor.spa_id;
|
||||||
id: seedingNeighbor.spa_id,
|
seedingScore = scores[seedingId];
|
||||||
score: seedingNeighbor.score,
|
|
||||||
};
|
|
||||||
|
|
||||||
setLoadingProgress([
|
setLoadingProgress([
|
||||||
closestScoreDistance - Math.abs(seedingNeighbor.score - targetScore),
|
closestScoreDistance - Math.abs(seedingNeighbor.score - targetScore),
|
||||||
@@ -444,9 +447,9 @@ export default function Page() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if (loadingDirection === 1) {
|
if (loadingDirection === 1) {
|
||||||
scoreAcquired = seedingPlayer.score <= targetScore;
|
scoreAcquired = seedingScore <= targetScore;
|
||||||
} else {
|
} else {
|
||||||
scoreAcquired = seedingPlayer.score >= targetScore;
|
scoreAcquired = seedingScore >= targetScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scoreAcquired) {
|
if (scoreAcquired) {
|
||||||
@@ -469,9 +472,9 @@ export default function Page() {
|
|||||||
let playerIndex = -1;
|
let playerIndex = -1;
|
||||||
|
|
||||||
for (let index = ratingsInfo.count; index >= 0; index--) {
|
for (let index = ratingsInfo.count; index >= 0; index--) {
|
||||||
if (!(index in players[region][season])) continue;
|
if (!(index in leaderboard[region][season])) continue;
|
||||||
|
|
||||||
if (players[region][season][index].score >= targetScore) {
|
if (scores[leaderboard[region][season][index]] >= targetScore) {
|
||||||
playerIndex = index;
|
playerIndex = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -481,7 +484,7 @@ export default function Page() {
|
|||||||
|
|
||||||
setPage(Math.floor(playerIndex / ROWS_PER_PAGE));
|
setPage(Math.floor(playerIndex / ROWS_PER_PAGE));
|
||||||
|
|
||||||
if (players) {
|
if (leaderboard) {
|
||||||
setHighlightedPlayer({
|
setHighlightedPlayer({
|
||||||
type: 'position',
|
type: 'position',
|
||||||
position: playerIndex,
|
position: playerIndex,
|
||||||
@@ -649,18 +652,22 @@ export default function Page() {
|
|||||||
const newPage = Math.floor(position / ROWS_PER_PAGE);
|
const newPage = Math.floor(position / ROWS_PER_PAGE);
|
||||||
|
|
||||||
setPage(newPage);
|
setPage(newPage);
|
||||||
if (players) {
|
if (leaderboard) {
|
||||||
setHighlightedPlayer({
|
setHighlightedPlayer({
|
||||||
type: 'id',
|
type: 'id',
|
||||||
id: players[region][season][position].id,
|
id: leaderboard[region][season][position],
|
||||||
});
|
});
|
||||||
cacheNeighbors(
|
cacheNeighbors(
|
||||||
players[region][season][position].id,
|
leaderboard[region][season][position],
|
||||||
4 * ROWS_PER_PAGE - 2,
|
4 * ROWS_PER_PAGE - 2,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!ratingsInfo || ratingsInfo.detail || !players)
|
if (
|
||||||
|
!ratingsInfo ||
|
||||||
|
ratingsInfo.detail ||
|
||||||
|
!leaderboard
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const minScore =
|
const minScore =
|
||||||
@@ -673,7 +680,8 @@ export default function Page() {
|
|||||||
index++
|
index++
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
players[region][season][index].score < minScore
|
scores[leaderboard[region][season][index]] <
|
||||||
|
minScore
|
||||||
) {
|
) {
|
||||||
firstPlayerIndex = index;
|
firstPlayerIndex = index;
|
||||||
break;
|
break;
|
||||||
@@ -685,7 +693,7 @@ export default function Page() {
|
|||||||
setPage(Math.floor(firstPlayerIndex / ROWS_PER_PAGE));
|
setPage(Math.floor(firstPlayerIndex / ROWS_PER_PAGE));
|
||||||
setHighlightedPlayer({
|
setHighlightedPlayer({
|
||||||
type: 'id',
|
type: 'id',
|
||||||
id: players[region][season][firstPlayerIndex].id,
|
id: leaderboard[region][season][firstPlayerIndex],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@@ -732,18 +740,15 @@ export default function Page() {
|
|||||||
skip: false;
|
skip: false;
|
||||||
})[];
|
})[];
|
||||||
|
|
||||||
usePlayersCache.setState(
|
useLeaderboardCache.setState(
|
||||||
produce((draft: PlayersCache) => {
|
produce((draft: LeaderboardCache) => {
|
||||||
if (draft) {
|
if (draft) {
|
||||||
values.map((player) => {
|
values.forEach((player) => {
|
||||||
const playerWithTypes =
|
const playerWithTypes =
|
||||||
player as typeof player & { skip: false };
|
player as typeof player & { skip: false };
|
||||||
draft[region][season][
|
draft[region][season][
|
||||||
playerWithTypes.number - 1
|
playerWithTypes.number - 1
|
||||||
] = {
|
] = playerWithTypes.spa_id;
|
||||||
id: playerWithTypes.spa_id,
|
|
||||||
score: 0,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -774,7 +779,7 @@ export default function Page() {
|
|||||||
`https://api.wotblitz.${region}/wotb/account/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${encodedSearch}`,
|
`https://api.wotblitz.${region}/wotb/account/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${encodedSearch}`,
|
||||||
);
|
);
|
||||||
const playerKeys = Object.keys(
|
const playerKeys = Object.keys(
|
||||||
players[region][season],
|
leaderboard[region][season],
|
||||||
);
|
);
|
||||||
|
|
||||||
setSearchResults(
|
setSearchResults(
|
||||||
@@ -784,9 +789,9 @@ export default function Page() {
|
|||||||
number: parseInt(
|
number: parseInt(
|
||||||
playerKeys.find(
|
playerKeys.find(
|
||||||
(indexAsString) =>
|
(indexAsString) =>
|
||||||
players[region][season][
|
leaderboard[region][season][
|
||||||
parseInt(indexAsString)
|
parseInt(indexAsString)
|
||||||
].id === searchedPlayer.account_id,
|
] === searchedPlayer.account_id,
|
||||||
)!,
|
)!,
|
||||||
),
|
),
|
||||||
}))
|
}))
|
||||||
@@ -837,7 +842,7 @@ export default function Page() {
|
|||||||
index++
|
index++
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
players[region][season][index].id ===
|
leaderboard[region][season][index] ===
|
||||||
player.account_id
|
player.account_id
|
||||||
) {
|
) {
|
||||||
playerIndex = index;
|
playerIndex = index;
|
||||||
@@ -923,7 +928,7 @@ export default function Page() {
|
|||||||
ratingsInfo?.detail ? 0 : (ratingsInfo?.count ?? 1) - 1,
|
ratingsInfo?.detail ? 0 : (ratingsInfo?.count ?? 1) - 1,
|
||||||
),
|
),
|
||||||
).map((index) => {
|
).map((index) => {
|
||||||
const id = players[region][season]?.[index]?.id;
|
const id = leaderboard[region][season]?.[index];
|
||||||
const clan = id ? names[region][id]?.clan : undefined;
|
const clan = id ? names[region][id]?.clan : undefined;
|
||||||
const position = index + 1;
|
const position = index + 1;
|
||||||
const highlight = highlightedPlayer
|
const highlight = highlightedPlayer
|
||||||
@@ -997,7 +1002,9 @@ export default function Page() {
|
|||||||
%
|
%
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell align="right">
|
<Table.Cell align="right">
|
||||||
{players[region][season]?.[index]?.score.toLocaleString()}
|
{(leaderboard[region][season]?.[index]
|
||||||
|
? scores[leaderboard[region][season][index]]?.toLocaleString()
|
||||||
|
: undefined) ?? '--'}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user