mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: jump to league for current season
This commit is contained in:
1 parent
212aee0373
commit
d08949c597
3 files changed
+105
-108
No files matched your search
@@ -58,6 +58,7 @@ export default function Page() {
|
|||||||
const usernameCache = useUsernameCache();
|
const usernameCache = useUsernameCache();
|
||||||
const clanCache = useClanCache();
|
const clanCache = useClanCache();
|
||||||
const [region, setRegion] = useState<Region>('com');
|
const [region, setRegion] = useState<Region>('com');
|
||||||
|
const leaguePositionCache = useRef<Record<number, number>>({});
|
||||||
// null being the latest season
|
// null being the latest season
|
||||||
const [season, setSeason] = useState<null | number>(null);
|
const [season, setSeason] = useState<null | number>(null);
|
||||||
const { data: ratingsInfo } = useSWR(
|
const { data: ratingsInfo } = useSWR(
|
||||||
@@ -110,39 +111,36 @@ export default function Page() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// league caching
|
// league caching
|
||||||
if (season === null) {
|
if (season === null) {
|
||||||
Promise.all(
|
(async () => {
|
||||||
range(0, 4).map(async (league: number) => {
|
const newUsernameCache: Record<number, string> = {};
|
||||||
const leaguePlayers = await getRatingsLeague(region, league);
|
const newClanCache: Record<number, string> = {};
|
||||||
useUsernameCache.setState(
|
const results = await Promise.all(
|
||||||
produce((draft: UsernameCache) => {
|
range(0, 5).map(async (league: number) => {
|
||||||
leaguePlayers.result.forEach((player) => {
|
const leaguePlayers = await getRatingsLeague(region, league);
|
||||||
draft[region][player.spa_id] = player.nickname;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
useClanCache.setState(
|
|
||||||
produce((draft: ClanCache) => {
|
|
||||||
leaguePlayers.result.forEach((player) => {
|
|
||||||
draft[region][player.spa_id] = player.clan_tag;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return leaguePlayers.result.reduce<
|
leaguePositionCache.current[league] =
|
||||||
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
leaguePlayers.result[0].number - 1;
|
||||||
>(
|
|
||||||
(accumulator, player) => ({
|
|
||||||
...accumulator,
|
|
||||||
|
|
||||||
[player.number - 1]: {
|
leaguePlayers.result.forEach((player) => {
|
||||||
id: player.spa_id,
|
newUsernameCache[player.spa_id] = player.nickname;
|
||||||
score: player.score,
|
newClanCache[player.spa_id] = player.clan_tag;
|
||||||
} satisfies BlitzkriegRatingsLeaderboardEntry,
|
});
|
||||||
}),
|
|
||||||
{},
|
return leaguePlayers.result.reduce<
|
||||||
);
|
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
||||||
}),
|
>(
|
||||||
).then((results) => {
|
(accumulator, player) => ({
|
||||||
|
...accumulator,
|
||||||
|
|
||||||
|
[player.number - 1]: {
|
||||||
|
id: player.spa_id,
|
||||||
|
score: player.score,
|
||||||
|
} satisfies BlitzkriegRatingsLeaderboardEntry,
|
||||||
|
}),
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
const newPlayers = results.reduce<
|
const newPlayers = results.reduce<
|
||||||
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
Record<number, BlitzkriegRatingsLeaderboardEntry>
|
||||||
>(
|
>(
|
||||||
@@ -154,13 +152,59 @@ export default function Page() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
setPlayers(newPlayers);
|
setPlayers(newPlayers);
|
||||||
});
|
useUsernameCache.setState((old) => ({
|
||||||
|
...old,
|
||||||
|
[region]: { ...old[region], ...newUsernameCache },
|
||||||
|
}));
|
||||||
|
useClanCache.setState((old) => ({
|
||||||
|
...old,
|
||||||
|
[region]: { ...old[region], ...newClanCache },
|
||||||
|
}));
|
||||||
|
})();
|
||||||
} else {
|
} else {
|
||||||
getArchivedRatingsLeaderboard(region, season).then((result) =>
|
getArchivedRatingsLeaderboard(region, season).then((result) =>
|
||||||
setPlayers({ ...result }),
|
setPlayers({ ...result }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
async function cacheNeighbors(id: number, size: number) {
|
||||||
|
const { neighbors } = await getRatingsNeighbors(region, id, size);
|
||||||
|
|
||||||
|
setPlayers(
|
||||||
|
produce((draft) => {
|
||||||
|
draft = draft ?? {};
|
||||||
|
|
||||||
|
neighbors.forEach((neighbor) => {
|
||||||
|
draft![neighbor.number - 1] = {
|
||||||
|
id: neighbor.spa_id,
|
||||||
|
score: neighbor.score,
|
||||||
|
} satisfies BlitzkriegRatingsLeaderboardEntry;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
useUsernameCache.setState(
|
||||||
|
produce((draft: UsernameCache) => {
|
||||||
|
neighbors.forEach((neighbor) => {
|
||||||
|
if (neighbor.nickname) {
|
||||||
|
draft[region][neighbor.spa_id] = neighbor.nickname;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
useClanCache.setState(
|
||||||
|
produce((draft: ClanCache) => {
|
||||||
|
neighbors.forEach((neighbor) => {
|
||||||
|
if (neighbor.clan_tag) {
|
||||||
|
draft[region][neighbor.spa_id] = neighbor.clan_tag;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// TODO: caches twice on initial load
|
// TODO: caches twice on initial load
|
||||||
if (!players || !ratingsInfo || ratingsInfo?.detail) return;
|
if (!players || !ratingsInfo || ratingsInfo?.detail) return;
|
||||||
@@ -172,42 +216,7 @@ export default function Page() {
|
|||||||
|
|
||||||
const middleId = players[middleIndex].id;
|
const middleId = players[middleIndex].id;
|
||||||
|
|
||||||
getRatingsNeighbors(region, middleId, rowsPerPage * 3).then(
|
cacheNeighbors(middleId, rowsPerPage * 3);
|
||||||
({ neighbors }) => {
|
|
||||||
setPlayers(
|
|
||||||
produce((draft) => {
|
|
||||||
draft = draft ?? {};
|
|
||||||
|
|
||||||
neighbors.forEach((neighbor) => {
|
|
||||||
draft![neighbor.number - 1] = {
|
|
||||||
id: neighbor.spa_id,
|
|
||||||
score: neighbor.score,
|
|
||||||
} satisfies BlitzkriegRatingsLeaderboardEntry;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
useUsernameCache.setState(
|
|
||||||
produce((draft: UsernameCache) => {
|
|
||||||
neighbors.forEach((neighbor) => {
|
|
||||||
if (neighbor.nickname) {
|
|
||||||
draft[region][neighbor.spa_id] = neighbor.nickname;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
useClanCache.setState(
|
|
||||||
produce((draft: ClanCache) => {
|
|
||||||
neighbors.forEach((neighbor) => {
|
|
||||||
if (neighbor.clan_tag) {
|
|
||||||
draft[region][neighbor.spa_id] = neighbor.clan_tag;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const ids = range(
|
const ids = range(
|
||||||
Math.max(0, (page - 1) * rowsPerPage),
|
Math.max(0, (page - 1) * rowsPerPage),
|
||||||
@@ -244,7 +253,7 @@ export default function Page() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [page, players]);
|
}, [page]);
|
||||||
|
|
||||||
const handleJumpToPosition = () => {
|
const handleJumpToPosition = () => {
|
||||||
if (!players || !ratingsInfo || ratingsInfo?.detail) return;
|
if (!players || !ratingsInfo || ratingsInfo?.detail) return;
|
||||||
@@ -509,34 +518,18 @@ export default function Page() {
|
|||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (season === null) {
|
if (season === null) {
|
||||||
// that's already done
|
const position =
|
||||||
const leaguePlayers = await getRatingsLeague(
|
leaguePositionCache.current[jumpToLeague];
|
||||||
region,
|
const newPage = Math.floor(position / rowsPerPage);
|
||||||
jumpToLeague,
|
|
||||||
);
|
|
||||||
|
|
||||||
useUsernameCache.setState(
|
setPage(newPage);
|
||||||
produce((draft: UsernameCache) => {
|
if (players) {
|
||||||
leaguePlayers.result.forEach((player) => {
|
setHighlightedPlayerId(players[position].id);
|
||||||
draft[region][player.spa_id] = player.nickname;
|
cacheNeighbors(
|
||||||
});
|
players[position].id,
|
||||||
}),
|
rowsPerPage * 3,
|
||||||
);
|
);
|
||||||
useClanCache.setState(
|
}
|
||||||
produce((draft: ClanCache) => {
|
|
||||||
leaguePlayers.result.forEach((player) => {
|
|
||||||
draft[region][player.spa_id] = player.clan_tag;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
leaguePlayers.result.map(
|
|
||||||
(player) =>
|
|
||||||
({
|
|
||||||
id: player.spa_id,
|
|
||||||
score: player.score,
|
|
||||||
}) satisfies BlitzkriegRatingsLeaderboardEntry,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
if (!ratingsInfo || ratingsInfo.detail || !players)
|
if (!ratingsInfo || ratingsInfo.detail || !players)
|
||||||
return;
|
return;
|
||||||
@@ -663,7 +656,7 @@ export default function Page() {
|
|||||||
: `Loading player...`
|
: `Loading player...`
|
||||||
}
|
}
|
||||||
position={index + 1}
|
position={index + 1}
|
||||||
score={players![index]?.score ?? 0}
|
score={players![index]?.score}
|
||||||
clan={
|
clan={
|
||||||
players![index]
|
players![index]
|
||||||
? clanCache[region][players![index].id]
|
? clanCache[region][players![index].id]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { theme } from '../../../stitches.config';
|
|||||||
export interface ItemProps extends ComponentProps<'div'> {
|
export interface ItemProps extends ComponentProps<'div'> {
|
||||||
position: number;
|
position: number;
|
||||||
deltaPosition?: number;
|
deltaPosition?: number;
|
||||||
score: number;
|
score?: number;
|
||||||
deltaScore?: number;
|
deltaScore?: number;
|
||||||
reward?: RatingsReward;
|
reward?: RatingsReward;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
@@ -188,16 +188,18 @@ export function Item({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span
|
{score !== undefined && (
|
||||||
style={{
|
<span
|
||||||
color: highlight
|
style={{
|
||||||
? theme.colors.textHighContrast_blue
|
color: highlight
|
||||||
: theme.colors.textHighContrast,
|
? theme.colors.textHighContrast_blue
|
||||||
fontSize: 16,
|
: theme.colors.textHighContrast,
|
||||||
}}
|
fontSize: 16,
|
||||||
>
|
}}
|
||||||
{score.toLocaleString()}
|
>
|
||||||
</span>
|
{score.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,4 +4,6 @@ export function withCORSProxy(url: string) {
|
|||||||
return context === 'website'
|
return context === 'website'
|
||||||
? `https://corsproxy.io/?${encodeURIComponent(url)}`
|
? `https://corsproxy.io/?${encodeURIComponent(url)}`
|
||||||
: url;
|
: url;
|
||||||
|
|
||||||
|
// `https://api.allorigins.win/raw?url=${encodeURIComponent(url)}`;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user