update (3)

This commit is contained in:
tresabhi committed 2026-08-01 14:54:40 -05:00
1 parent d41d45abae
commit ed92440b94
14 files changed
+61 -94

No files matched your search

@@ -1,7 +0,0 @@
import { fetchPB } from '../protobuf';
import { CamouflageDefinitions } from '../protos';
import { asset } from './asset';
export function fetchCamouflageDefinitions() {
return fetchPB(asset('definitions/camouflages.pb'), CamouflageDefinitions);
}
+1
View File
@@ -23,6 +23,7 @@ export * from "./romanize";
export * from "./sluggify"; export * from "./sluggify";
export * from "./staticAsset"; export * from "./staticAsset";
export * from "./sum"; export * from "./sum";
export * from "./tankDefinitions";
export * from "./tankIcon"; export * from "./tankIcon";
export * from "./tankNames"; export * from "./tankNames";
export * from "./unionBoundingBox"; export * from "./unionBoundingBox";
@@ -0,0 +1 @@
export * from "./constants";
+4 -5
View File
@@ -1,13 +1,12 @@
import { BlitzKitAPI } from "@blitzkit/core";
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import { deburr } from "lodash-es"; import { deburr } from "lodash-es";
import { I18nString } from "../protos"; import { I18nString } from "../protos";
import { fetchCamouflageDefinitions } from "./camouflageDefinitions";
import { fetchTankDefinitions } from "./tankDefinitions";
export async function fetchTankNames() { export async function fetchTankNames(api: BlitzKitAPI) {
const [tankDefinitions, camouflageDefinitions] = await Promise.all([ const [tankDefinitions, camouflageDefinitions] = await Promise.all([
fetchTankDefinitions(), api.tankDefinitions(),
fetchCamouflageDefinitions(), api.camouflageDefinitions(),
]); ]);
const tankDefinitionsArray = Object.values(tankDefinitions.tanks); const tankDefinitionsArray = Object.values(tankDefinitions.tanks);
@@ -1,12 +1,8 @@
import { import { asset, TankType, type TankDefinition } from "@blitzkit/core";
asset,
fetchTankDefinitions,
TankType,
type TankDefinition,
} from "@blitzkit/core";
import { Flex, Text, type TextProps } from "@radix-ui/themes"; import { Flex, Text, type TextProps } from "@radix-ui/themes";
import { uniq } from "lodash-es"; import { uniq } from "lodash-es";
import { forwardRef, type ReactNode } from "react"; import { forwardRef, type ReactNode } from "react";
import { api } from "../../core/blitzkit/api";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { TankopediaPersistent } from "../../stores/tankopediaPersistent"; import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
import { classIcons } from "../ClassIcon"; import { classIcons } from "../ClassIcon";
@@ -21,7 +17,7 @@ type TankCardProps = TextProps & {
noLink?: boolean; noLink?: boolean;
}; };
const tankDefinitions = await fetchTankDefinitions(); const tankDefinitions = await api.tankDefinitions();
export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>( export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>(
( (
@@ -5,7 +5,7 @@ import {
type TankDefinition, type TankDefinition,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { useMemo } from "react"; import { useMemo } from "react";
import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions"; import { api } from "../../../core/blitzkit/api";
import { resolveReload } from "../../../core/blitzkit/resolveReload"; import { resolveReload } from "../../../core/blitzkit/resolveReload";
import { TankSort } from "../../../stores/tankopediaSort"; import { TankSort } from "../../../stores/tankopediaSort";
import { TankCard } from "../../TankCard"; import { TankCard } from "../../TankCard";
@@ -15,7 +15,7 @@ interface TankSearchCardProps {
onSelect?: (tank: TankDefinition) => void; onSelect?: (tank: TankDefinition) => void;
} }
const modelDefinitions = await awaitableModelDefinitions; const modelDefinitions = await api.modelDefinitions();
export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
const by = TankSort.use((state) => state.by); const by = TankSort.use((state) => state.by);
@@ -1,5 +1,4 @@
import { import {
asset,
GunDefinition, GunDefinition,
ShellType, ShellType,
TANK_CLASSES, TANK_CLASSES,
@@ -27,10 +26,7 @@ import {
} from "@radix-ui/themes"; } from "@radix-ui/themes";
import { times } from "lodash-es"; import { times } from "lodash-es";
import { Fragment, type ComponentProps, type ReactNode } from "react"; import { Fragment, type ComponentProps, type ReactNode } from "react";
import { awaitableConsumableDefinitions } from "../../../core/awaitables/consumableDefinitions"; import { api } from "../../../core/blitzkit/api";
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
import { awaitableProvisionDefinitions } from "../../../core/awaitables/provisionDefinitions";
import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions";
import { useLocale } from "../../../hooks/useLocale"; import { useLocale } from "../../../hooks/useLocale";
import { App } from "../../../stores/app"; import { App } from "../../../stores/app";
import { TankFilters, type CaseType } from "../../../stores/tankFilters"; import { TankFilters, type CaseType } from "../../../stores/tankFilters";
@@ -43,10 +39,10 @@ import { ResearchedIcon } from "../../ResearchedIcon";
import { ScienceIcon } from "../../ScienceIcon"; import { ScienceIcon } from "../../ScienceIcon";
import { ScienceOffIcon } from "../../ScienceOffIcon"; import { ScienceOffIcon } from "../../ScienceOffIcon";
const gameDefinitions = await awaitableGameDefinitions; const gameDefinitions = await api.gameDefinitions();
const consumableDefinitions = await awaitableConsumableDefinitions; const consumableDefinitions = await api.consumableDefinitions();
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
const tankDefinitions = await awaitableTankDefinitions; const tankDefinitions = await api.tankDefinitions();
const gameModeRoleSets: Record<number, Set<number>> = {}; const gameModeRoleSets: Record<number, Set<number>> = {};
@@ -313,7 +309,7 @@ function NationsFilter() {
width: "1.25em", width: "1.25em",
height: "1.25em", height: "1.25em",
}} }}
src={asset(`flags/circle/${nation}.webp`)} src={`/api/flags/circle/${nation}.webp`}
/> />
))} ))}
</Flex> </Flex>
@@ -350,9 +346,7 @@ function NationsFilter() {
right="0" right="0"
mr="-2" mr="-2"
style={{ style={{
backgroundImage: `url(${asset( backgroundImage: `url(${`/api/flags/scratched/${nation}.webp`})`,
`flags/scratched/${nation}.webp`,
)})`,
backgroundSize: "100%", backgroundSize: "100%",
backgroundRepeat: "no-repeat", backgroundRepeat: "no-repeat",
backgroundPosition: "5rem center", backgroundPosition: "5rem center",
@@ -685,11 +679,9 @@ function IndividualShellFilter({
{shells[index] !== null && ( {shells[index] !== null && (
<img <img
style={{ width: "1em", height: "1em" }} style={{ width: "1em", height: "1em" }}
src={asset( src={`/api/icons/shells/${shellTypeIcons[shells[index]]}${
`icons/shells/${shellTypeIcons[shells[index]]}${ premium ? "_premium" : ""
premium ? "_premium" : "" }.webp`}
}.webp`,
)}
/> />
)} )}
</IconButton> </IconButton>
@@ -720,11 +712,9 @@ function IndividualShellFilter({
color={selected ? undefined : "gray"} color={selected ? undefined : "gray"}
> >
<img <img
src={asset( src={`/api/icons/shells/${shellTypeIcons[shellType]}${
`icons/shells/${shellTypeIcons[shellType]}${ premium ? "_premium" : ""
premium ? "_premium" : "" }.webp`}
}.webp`,
)}
style={{ width: "1.25em", height: "1.25em" }} style={{ width: "1.25em", height: "1.25em" }}
/> />
@@ -893,7 +883,7 @@ function ConsumablesFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/consumables/${consumable}.webp`)} src={`/api/icons/consumables/${consumable}.webp`}
/> />
))} ))}
@@ -938,7 +928,7 @@ function ConsumablesFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/consumables/${consumable}.webp`)} src={`/api/icons/consumables/${consumable}.webp`}
/> />
{unwrap(consumableDefinition.name!)} {unwrap(consumableDefinition.name!)}
@@ -987,7 +977,7 @@ function ProvisionsFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/provisions/${provision}.webp`)} src={`/api/icons/provisions/${provision}.webp`}
/> />
))} ))}
@@ -1032,7 +1022,7 @@ function ProvisionsFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/provisions/${provision}.webp`)} src={`/api/icons/provisions/${provision}.webp`}
/> />
{unwrap(provisionDefinition.name!)} {unwrap(provisionDefinition.name!)}
@@ -1075,8 +1065,8 @@ function GameModeAbilitiesFilter() {
: rawPowers; : rawPowers;
const icons = [ const icons = [
...abilities.map((ability) => `icons/consumables/${ability}.webp`), ...abilities.map((ability) => `api/icons/consumables/${ability}.webp`),
...powers.map((power) => `icons/provisions/${power}.webp`), ...powers.map((power) => `api/icons/provisions/${power}.webp`),
]; ];
return ( return (
@@ -1094,7 +1084,7 @@ function GameModeAbilitiesFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(icon)} src={icon}
/> />
))} ))}
@@ -1161,7 +1151,7 @@ function GameModeAbilitiesFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/consumables/${consumable}.webp`)} src={`/api/icons/consumables/${consumable}.webp`}
/> />
{unwrap(abilityDefinition.name!)} {unwrap(abilityDefinition.name!)}
@@ -1210,7 +1200,7 @@ function GameModeAbilitiesFilter() {
height: "1.25em", height: "1.25em",
objectFit: "contain", objectFit: "contain",
}} }}
src={asset(`icons/provisions/${provision}.webp`)} src={`/api/icons/provisions/${provision}.webp`}
/> />
{unwrap(powerDefinition.name!)} {unwrap(powerDefinition.name!)}
@@ -1,3 +0,0 @@
import { fetchConsumableDefinitions } from '@blitzkit/core';
export const awaitableConsumableDefinitions = fetchConsumableDefinitions();
@@ -1,3 +0,0 @@
import { fetchModelDefinitions } from '@blitzkit/core';
export const awaitableModelDefinitions = fetchModelDefinitions();
@@ -1,3 +0,0 @@
import { fetchProvisionDefinitions } from '@blitzkit/core';
export const awaitableProvisionDefinitions = fetchProvisionDefinitions();
@@ -1,3 +0,0 @@
import { fetchTankDefinitions } from '@blitzkit/core';
export const awaitableTankDefinitions = fetchTankDefinitions();
@@ -1,3 +1,4 @@
import { fetchTankNames } from "@blitzkit/core"; import { fetchTankNames } from "@blitzkit/core";
import { api } from "../blitzkit/api";
export const awaitableTankNames = fetchTankNames(); export const awaitableTankNames = fetchTankNames(api);
@@ -1,21 +1,19 @@
import type { TankDefinition } from "@blitzkit/core"; import type { TankDefinition } from "@blitzkit/core";
import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity"; import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity";
import { times } from "lodash-es"; import { times } from "lodash-es";
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions";
import type { TankFilters } from "../../stores/tankFilters"; import type { TankFilters } from "../../stores/tankFilters";
import { awaitableGameDefinitions } from "../awaitables/gameDefinitions"; import { api } from "./api";
import { awaitableProvisionDefinitions } from "../awaitables/provisionDefinitions";
const SHELLS = times(3, (index) => index); const SHELLS = times(3, (index) => index);
const consumableDefinitions = await awaitableConsumableDefinitions; const consumableDefinitions = await api.consumableDefinitions();
const provisionDefinitions = await awaitableProvisionDefinitions; const provisionDefinitions = await api.provisionDefinitions();
const gameDefinitions = await awaitableGameDefinitions; const gameDefinitions = await api.gameDefinitions();
export async function filterTank( export async function filterTank(
filters: TankFilters, filters: TankFilters,
tank: TankDefinition, tank: TankDefinition,
owned: number[] = [] owned: number[] = [],
) { ) {
return ( return (
((filters.showOwned && owned.includes(tank.id)) || ((filters.showOwned && owned.includes(tank.id)) ||
@@ -29,15 +27,15 @@ export async function filterTank(
(filters.gunType.length === 0 || (filters.gunType.length === 0 ||
(filters.gunType.includes("regular") && (filters.gunType.includes("regular") &&
tank.turrets.some((turret) => tank.turrets.some((turret) =>
turret.guns.some((gun) => gun.gun_type!.$case === "regular") turret.guns.some((gun) => gun.gun_type!.$case === "regular"),
)) || )) ||
(filters.gunType.includes("auto_loader") && (filters.gunType.includes("auto_loader") &&
tank.turrets.some((turret) => tank.turrets.some((turret) =>
turret.guns.some((gun) => gun.gun_type!.$case === "auto_loader") turret.guns.some((gun) => gun.gun_type!.$case === "auto_loader"),
)) || )) ||
(filters.gunType.includes("auto_reloader") && (filters.gunType.includes("auto_reloader") &&
tank.turrets.some((turret) => tank.turrets.some((turret) =>
turret.guns.some((gun) => gun.gun_type!.$case === "auto_reloader") turret.guns.some((gun) => gun.gun_type!.$case === "auto_reloader"),
))) && ))) &&
tank.turrets.some((turret) => tank.turrets.some((turret) =>
turret.guns.some((gun) => turret.guns.some((gun) =>
@@ -45,9 +43,9 @@ export async function filterTank(
(index) => (index) =>
filters.shells[index] === null || filters.shells[index] === null ||
gun.shells[index] === undefined || gun.shells[index] === undefined ||
gun.shells[index].type === filters.shells[index] gun.shells[index].type === filters.shells[index],
) ),
) ),
) && ) &&
(filters.consumables.length === 0 || (filters.consumables.length === 0 ||
filters.consumables.every((consumable) => filters.consumables.every((consumable) =>
@@ -56,10 +54,10 @@ export async function filterTank(
checkConsumableProvisionInclusivity( checkConsumableProvisionInclusivity(
consumableDefinitions.consumables[consumable], consumableDefinitions.consumables[consumable],
tank, tank,
gun gun,
) ),
) ),
) ),
)) && )) &&
(filters.provisions.length === 0 || (filters.provisions.length === 0 ||
filters.provisions.every((provision) => filters.provisions.every((provision) =>
@@ -68,22 +66,22 @@ export async function filterTank(
checkConsumableProvisionInclusivity( checkConsumableProvisionInclusivity(
provisionDefinitions.provisions[provision], provisionDefinitions.provisions[provision],
tank, tank,
gun gun,
) ),
) ),
) ),
)) && )) &&
(filters.abilities.length === 0 || (filters.abilities.length === 0 ||
Object.values(tank.roles).some((id) => Object.values(tank.roles).some((id) =>
gameDefinitions.roles[id as unknown as number].consumables.some( gameDefinitions.roles[id as unknown as number].consumables.some(
(consumable) => filters.abilities.includes(consumable) (consumable) => filters.abilities.includes(consumable),
) ),
)) && )) &&
(filters.powers.length === 0 || (filters.powers.length === 0 ||
Object.values(tank.roles).some((id) => Object.values(tank.roles).some((id) =>
gameDefinitions.roles[id as unknown as number].provisions.some( gameDefinitions.roles[id as unknown as number].provisions.some(
(consumable) => filters.powers.includes(consumable) (consumable) => filters.powers.includes(consumable),
) ),
)) ))
); );
} }
@@ -1,7 +1,7 @@
--- ---
import ToolOpenGraph from "../../../components/ToolOpenGraph.astro"; import ToolOpenGraph from "../../../../components/ToolOpenGraph.astro";
import { tools } from "../../../constants/tools"; import { tools } from "../../../../constants/tools";
import BaseLayout from "../../../layouts/BaseLayout.astro"; import BaseLayout from "../../../../layouts/BaseLayout.astro";
import type { getStaticPaths } from "../index.astro"; import type { getStaticPaths } from "../index.astro";
import { Page } from "./_index"; import { Page } from "./_index";