feat: tier sorting

This commit is contained in:
TrèsAbhi committed 2026-04-27 19:34:06 -05:00
1 parent b4936bf13b
commit 385cc3b6d2
8 files changed
+64 -7

No files matched your search

@@ -9,6 +9,7 @@ import type { PopularTanks } from "@protos/blitzkit/popular_tanks";
import type { Tank } from "@protos/blitzkit/tank"; import type { Tank } from "@protos/blitzkit/tank";
import type { TankList } from "@protos/blitzkit/tank_list"; import type { TankList } from "@protos/blitzkit/tank_list";
import type { Tanks } from "@protos/blitzkit/tanks"; import type { Tanks } from "@protos/blitzkit/tanks";
import type { Tiers } from "@protos/blitzkit/tiers";
export abstract class AbstractAPI { export abstract class AbstractAPI {
abstract tankList(): Promise<TankList>; abstract tankList(): Promise<TankList>;
@@ -16,6 +17,8 @@ export abstract class AbstractAPI {
abstract tanks(): Promise<Tanks>; abstract tanks(): Promise<Tanks>;
abstract popularTanks(): Promise<PopularTanks>; abstract popularTanks(): Promise<PopularTanks>;
abstract tiers(): Promise<Tiers>;
abstract strings(locale: string): Promise<Strings>; abstract strings(locale: string): Promise<Strings>;
abstract gameStrings(locale: string): Promise<Record<string, string>>; abstract gameStrings(locale: string): Promise<Record<string, string>>;
protected abstract _groupedGameStrings( protected abstract _groupedGameStrings(
@@ -4,6 +4,7 @@ import { Avatars } from "@protos/blitzkit/avatars";
import { PopularTanks } from "@protos/blitzkit/popular_tanks"; import { PopularTanks } from "@protos/blitzkit/popular_tanks";
import { TankList } from "@protos/blitzkit/tank_list"; import { TankList } from "@protos/blitzkit/tank_list";
import { Tanks } from "@protos/blitzkit/tanks"; import { Tanks } from "@protos/blitzkit/tanks";
import { Tiers } from "@protos/blitzkit/tiers";
import { AbstractAPI, Cache } from "./abstract"; import { AbstractAPI, Cache } from "./abstract";
const rejected = Promise.reject("Not implemented on client"); const rejected = Promise.reject("Not implemented on client");
@@ -30,6 +31,11 @@ export class ClientAPI extends AbstractAPI {
return fetchPB("/api/tanks/popular.pb", PopularTanks); return fetchPB("/api/tanks/popular.pb", PopularTanks);
} }
@Cache()
tiers() {
return fetchPB("/api/tiers.pb", Tiers);
}
@Cache() @Cache()
async strings(locale: string) { async strings(locale: string) {
const response = await fetch(`/api/strings/${locale}.json`); const response = await fetch(`/api/strings/${locale}.json`);
@@ -8,6 +8,7 @@ import type { PopularTanks } from "@protos/blitzkit/popular_tanks";
import type { Tank } from "@protos/blitzkit/tank"; import type { Tank } from "@protos/blitzkit/tank";
import type { TankListEntry } from "@protos/blitzkit/tank_list"; import type { TankListEntry } from "@protos/blitzkit/tank_list";
import type { Tanks } from "@protos/blitzkit/tanks"; import type { Tanks } from "@protos/blitzkit/tanks";
import type { Tiers } from "@protos/blitzkit/tiers";
import type { RemoteStorageComponent } from "@protos/game/proto/legacy/blitz_static_remote_storage_component"; import type { RemoteStorageComponent } from "@protos/game/proto/legacy/blitz_static_remote_storage_component";
import { existsSync } from "fs"; import { existsSync } from "fs";
import { mkdir, readFile, writeFile } from "fs/promises"; import { mkdir, readFile, writeFile } from "fs/promises";
@@ -173,6 +174,18 @@ export class ServerAPI extends AbstractAPI {
return JSON.parse(data) as PopularTanks; return JSON.parse(data) as PopularTanks;
} }
@Cache()
async tiers() {
const group = this.metadata.group("TankTierEntity");
const tiers: Tiers = { tiers: {} };
for (const item of group) {
tiers.tiers[item.name] = item.TankTier();
}
return tiers;
}
@Cache() @Cache()
async strings(locale: string) { async strings(locale: string) {
const localized = (await globbedStrings[ const localized = (await globbedStrings[
@@ -0,0 +1,17 @@
import { api } from "../core/api/dynamic";
import { useAwait } from "./useAwait";
export function useTierCompare() {
const tiers = useAwait(() => api.tiers(), "tiers");
function compare(a: string, b: string) {
const [, tierNameA] = a.split(".");
const [, tierNameB] = b.split(".");
const tierA = tiers.tiers[tierNameA];
const tierB = tiers.tiers[tierNameB];
return tierB.carousel_level - tierA.carousel_level;
}
return compare;
}
@@ -1,8 +1,10 @@
import { useMemo } from "react";
import { TankCard } from "../../../components/TankCard"; import { TankCard } from "../../../components/TankCard";
import { TankCards } from "../../../components/TankCards"; import { TankCards } from "../../../components/TankCards";
import { api } from "../../../core/api/dynamic"; import { api } from "../../../core/api/dynamic";
import { useAwait } from "../../../hooks/useAwait"; import { useAwait } from "../../../hooks/useAwait";
import { LocaleProvider } from "../../../hooks/useLocale"; import { LocaleProvider } from "../../../hooks/useLocale";
import { useTierCompare } from "../../../hooks/useTierCompare";
interface PageProps { interface PageProps {
locale: string; locale: string;
@@ -17,11 +19,21 @@ export function Page({ locale, ...props }: PageProps) {
} }
function Content() { function Content() {
const tankList = useAwait(() => api.tankList(), "tank-list"); const tanks = useAwait(() => api.tanks(), "tanks");
const compareTiers = useTierCompare();
const tanksOrdered = useMemo(() => {
let list = Object.values(tanks.tanks);
list = list.sort((a, b) =>
compareTiers(a.tank!.tier_catalog_id, b.tank!.tier_catalog_id),
);
return list;
}, []);
return ( return (
<TankCards> <TankCards>
{tankList.list.slice(0, 32).map(({ id }) => ( {tanksOrdered.slice(0, 32).map(({ id }) => (
<TankCard key={id} id={id} /> <TankCard key={id} id={id} />
))} ))}
</TankCards> </TankCards>
@@ -19,8 +19,4 @@ const tankList = await api.tankList();
<Section> <Section>
<Page {locale} client:load /> <Page {locale} client:load />
</Section> </Section>
<!-- {
} -->
</BaseLayout> </BaseLayout>
@@ -0,0 +1,10 @@
import { Tiers } from "@protos/blitzkit/tiers";
import { api } from "../../core/api/dynamic";
/**
* Woah!
*/
export async function GET() {
const tiers = await api.tiers();
return new Response(Tiers.encode(tiers).finish());
}