feat: flesh out popular tanks

This commit is contained in:
TrèsAbhi committed 2026-03-15 22:37:46 -05:00
1 parent b6c4c4e852
commit 406ad52c8d
10 files changed
+85 -30

No files matched your search

+1
View File
@@ -2,6 +2,7 @@
<PropertyGroup>
<RootNamespace>BlitzKit.Game</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NodeApiAssemblyJSModuleType>esm</NodeApiAssemblyJSModuleType>
+1 -1
View File
@@ -1 +1 @@
export * from "../bin/Debug/net9.0/game";
export * from "../bin/Debug/net9.0/win-x64/game";
@@ -2,9 +2,8 @@
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Scroller } from "./Scroller";
import { HomeTanksPopular } from "./HomeTanksPopular";
import { Section } from "./Section";
import { TankCard } from "./TankCard";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
@@ -13,37 +12,19 @@ interface Props {
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
const popular = (await api.popularTanks()).tanks.slice(0, 8);
console.log(popular.length);
---
<style>
.title {
margin-bottom: var(--space-3);
}
.tanks {
z-index: 1;
.content {
display: flex;
gap: 2rem;
}
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.tanks}</Heading>
<Scroller client:load className="tanks">
<div class="content">
{popular.map((tank) => <TankCard {...tank} />)}
</div>
</Scroller>
<HomeTanksPopular {locale} client:load />
<ToolCard gradient {locale} tool={tools.tanks} />
@@ -0,0 +1,9 @@
.tanks {
z-index: 1;
.content {
display: flex;
gap: 2rem;
}
}
@@ -0,0 +1,32 @@
import { api } from "../../core/api/dynamic";
import { useAwait } from "../../hooks/useAwait";
import {
LocaleProvider,
type LocaleAcceptorProps,
} from "../../hooks/useLocale";
import { Scroller } from "../Scroller";
import { TankCard } from "../TankCard";
import styles from "./index.module.css";
export function HomeTanksPopular({ locale }: LocaleAcceptorProps) {
return (
<LocaleProvider locale={locale}>
<Content />
</LocaleProvider>
);
}
function Content() {
const popular = useAwait(() => api.popularTanks(), "popular-tanks");
const trimmed = popular.tanks.slice(0, 32);
return (
<Scroller className={styles.tanks}>
<div className={styles.content}>
{trimmed.map((tank) => (
<TankCard key={tank.id} {...tank} />
))}
</div>
</Scroller>
);
}
@@ -2,7 +2,10 @@
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-2);
gap: var(--space-4);
overflow: hidden;
min-width: min-content;
.icon-wrapper {
position: relative;
@@ -20,12 +23,19 @@
}
.icon {
width: 7rem;
aspect-ratio: 4 / 3;
width: 13rem;
height: 8rem;
position: relative;
background-size: 150%;
background-position: center;
background-size: 140%;
background-position: 40% center;
}
}
.name {
white-space: nowrap;
overflow: hidden;
max-width: 100%;
text-overflow: ellipsis;
}
}
@@ -1,8 +1,14 @@
import { api } from "../../core/api/dynamic";
import { useAwait } from "../../hooks/useAwait";
import { useGameStrings } from "../../hooks/useGameStrings";
import type { PopularTank } from "../../protos/popular_tanks";
import { Text } from "../Text";
import styles from "./index.module.css";
export function TankCard({ id }: PopularTank) {
const tank = useAwait(() => api.tank(id), `tank-${id}`);
const gameStrings = useGameStrings("TankEntity");
return (
<div className={styles["tank-card"]}>
<div className={styles["icon-wrapper"]}>
@@ -21,7 +27,7 @@ export function TankCard({ id }: PopularTank) {
/>
</div>
<Text className={styles.name}>{id}</Text>
<Text className={styles.name}>{gameStrings[tank.tank!.name!.value]}</Text>
</div>
);
}
+10 -1
View File
@@ -1,9 +1,10 @@
import { fetchPB } from "@blitzkit/core";
import type { Strings } from "@blitzkit/i18n";
import { Avatars } from "../../protos/avatars";
import { PopularTanks } from "../../protos/popular_tanks";
import { Tank } from "../../protos/tank";
import { AbstractAPI } from "./abstract";
//@ts-expect-error
export class ClientAPI extends AbstractAPI {
protected _avatars() {
return fetchPB("/api/avatars/all.pb", Avatars);
@@ -24,4 +25,12 @@ export class ClientAPI extends AbstractAPI {
const json = (await response.json()) as Strings;
return json;
}
protected _popularTanks() {
return fetchPB("/api/tanks/popular.pb", PopularTanks);
}
protected _tank(id: string) {
return fetchPB(`/api/tanks/${id}.pb`, Tank);
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { GameInterface } from "@blitzkit/game";
export const game = new GameInterface(
"/mnt/c/Program Files (x86)/Steam/steamapps/common/World of Tanks Blitz Playtest",
"C:/Program Files (x86)/Steam/steamapps/common/World of Tanks Blitz Playtest",
);
@@ -0,0 +1,7 @@
import { api } from "../../../core/api/dynamic";
import { PopularTanks } from "../../../protos/popular_tanks";
export async function GET() {
const popular = await api.popularTanks();
return new Response(PopularTanks.encode(popular).finish());
}