This commit is contained in:
tresabhi committed 2026-08-05 13:01:51 -05:00
1 parent 851a1108d2
commit bc2b9f1267
10 files changed
+174 -15

No files matched your search

+2 -2
View File
@@ -4,8 +4,8 @@ import type { BlitzGlossary } from "../types";
export async function fetchGlossary(locale: string) {
const response = await fetch(
`${assertSecret(
import.meta.env.WOTB_GLOSSARY_DOMAIN
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`
import.meta.env.WOTB_GLOSSARY_DOMAIN,
)}/${locale}${assertSecret(import.meta.env.WOTB_GLOSSARY_PATH)}`,
);
return (await response.json()) as BlitzGlossary;
}
+2
View File
@@ -2,6 +2,7 @@ import {
CamouflageDefinitions,
ConsumableDefinitions,
EquipmentDefinitions,
Gallery,
GameDefinitions,
MapDefinitions,
ModelDefinitions,
@@ -20,4 +21,5 @@ export abstract class BlitzKitAPI {
abstract camouflageDefinitions(): Promise<CamouflageDefinitions>;
abstract tankDefinitions(): Promise<TankDefinitions>;
abstract gameDefinitions(): Promise<GameDefinitions>;
abstract galleryDefinitions(): Promise<Gallery>;
}
+5
View File
@@ -3,6 +3,7 @@ import {
CamouflageDefinitions,
ConsumableDefinitions,
EquipmentDefinitions,
Gallery,
GameDefinitions,
ModelDefinitions,
ProvisionDefinitions,
@@ -43,4 +44,8 @@ export class ClientBlitzKitAPI extends BlitzKitAPI {
equipmentDefinitions() {
return fetchPB("/api/definitions/equipment.pb", EquipmentDefinitions);
}
galleryDefinitions() {
return fetchPB("/api/definitions/gallery.pb", Gallery);
}
}
@@ -0,0 +1,67 @@
import { Avatar, fetchGlossary, Gallery } from "@blitzkit/core";
import { ServerBlitzKitAPI9 } from "@blitzkit/core/src/blitzkit/api/server/9_gameDefinitions";
import locales from "@blitzkit/i18n/locales.json";
import { extname } from "path";
import { Cache } from "./0_base";
export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
@Cache()
async galleryDefinitions() {
const avatars: Record<string, { avatar: Avatar; url: string }> = {};
await Promise.all(
locales.supported.map(async (supported) => {
const glossary = await fetchGlossary(
supported.blitz ?? supported.locale,
);
console.log(
`Found ${Object.keys(glossary).length} things for ${supported.locale}`,
);
for (const key in glossary) {
const glossaryEntry = glossary[key];
if (
!key.startsWith("avatar") ||
key.endsWith("_part") ||
glossaryEntry.image_url === null
) {
continue;
}
if (key in avatars) {
avatars[key].avatar.name!.locales[supported.locale] =
glossaryEntry.title;
} else {
const extension = extname(glossaryEntry.image_url);
avatars[key] = {
url: glossaryEntry.image_url,
avatar: {
id: key,
name: { locales: { [supported.locale]: glossaryEntry.title } },
extension,
},
};
}
}
}),
);
const gallery: Gallery = { avatars: [] };
await Promise.all(
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
if (!(locales.default in avatars[key].avatar.name!.locales)) {
console.warn(`Avatar ${key} has no ${locales.default} name`);
return;
}
gallery.avatars.push(avatar);
}),
);
return gallery;
}
}
@@ -1,3 +1,3 @@
import { ServerBlitzKitAPI9 } from "./9_gameDefinitions";
import { ServerBlitzKitAPI10 } from "@blitzkit/core/src/blitzkit/api/server/10_galleryDefinitions";
export class ServerBlitzKitAPI extends ServerBlitzKitAPI9 {}
export class ServerBlitzKitAPI extends ServerBlitzKitAPI10 {}
@@ -1,4 +1,4 @@
import { asset, Avatar } from "@blitzkit/core";
import { Avatar } from "@blitzkit/core";
import { Cross1Icon, DownloadIcon } from "@radix-ui/react-icons";
import {
Dialog,
@@ -18,9 +18,7 @@ type GalleryCardProps = MaybeSkeletonComponentProps<{
}>;
export function GalleryCard(props: GalleryCardProps) {
const src = asset(
`gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`,
);
const src = `/api/gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`;
const card = useRef<HTMLDivElement>(null!);
const { unwrap } = useLocale();
@@ -4,7 +4,7 @@ import { Flex, Text } from "@radix-ui/themes";
import fuzzysort from "fuzzysort";
import { times } from "lodash-es";
import { useMemo, useState } from "react";
import { awaitableGallery } from "../../core/awaitables/gallery";
import { api } from "../../core/blitzkit/api";
import { useLocale } from "../../hooks/useLocale";
import { Gallery } from "../../stores/gallery";
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
@@ -16,7 +16,7 @@ export interface Avatar {
id: string;
}
const gallery = await awaitableGallery;
const gallery = await api.galleryDefinitions();
const DEFAULT_LOADED = 42;
const PREVIEW_COUNT = 28;
@@ -35,7 +35,7 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
.go(search, gallery.avatars, {
keys: [
...locales.supported.map(
(supported) => `name.locales.${supported.locale}`
(supported) => `name.locales.${supported.locale}`,
),
"id",
],
@@ -72,7 +72,7 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
skeleton
onIntersection={() => setLoadedCards((state) => state + 2)}
/>
)
),
)}
</Flex>
</>
@@ -1,3 +0,0 @@
import { fetchGallery } from "@blitzkit/core";
export const awaitableGallery = fetchGallery();
@@ -0,0 +1,11 @@
import { Gallery } from "@blitzkit/core";
import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index";
export async function GET() {
const definitions = await api.galleryDefinitions();
const bytes = Gallery.encode(definitions).finish();
return new Response(bytes);
}
@@ -0,0 +1,79 @@
import { fetchGlossary, type Avatar } from "@blitzkit/core";
import locales from "@blitzkit/i18n/locales.json";
import type { APIContext, GetStaticPathsItem } from "astro";
import { extname } from "path";
import { mixStaticPaths } from "../../../../core/blitzkit/mixStaticPaths";
import { getStaticPaths as _getStaticPaths } from "../../_index";
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
const paths: GetStaticPathsItem[] = [];
const avatars: Record<string, { avatar: Avatar; url: string }> = {};
await Promise.all(
locales.supported.map(async (supported) => {
const glossary = await fetchGlossary(supported.blitz ?? supported.locale);
console.log(
`Found ${Object.keys(glossary).length} things for ${supported.locale}`,
);
for (const key in glossary) {
const glossaryEntry = glossary[key];
if (
!key.startsWith("avatar") ||
key.endsWith("_part") ||
glossaryEntry.image_url === null
) {
continue;
}
if (key in avatars) {
avatars[key].avatar.name!.locales[supported.locale] =
glossaryEntry.title;
} else {
const extension = extname(glossaryEntry.image_url);
avatars[key] = {
url: glossaryEntry.image_url,
avatar: {
id: key,
name: { locales: { [supported.locale]: glossaryEntry.title } },
extension,
},
};
}
}
}),
);
await Promise.all(
Object.entries(avatars).map(async ([key, { url, avatar }]) => {
if (!(locales.default in avatars[key].avatar.name!.locales)) {
console.warn(`Avatar ${key} has no ${locales.default} name`);
return;
}
const name = `${key}${avatar.extension}`;
paths.push({
params: { name },
props: { url },
});
}),
);
return paths;
});
export async function GET({ props }: APIContext<{ url: string }>) {
if (import.meta.env.DEV) {
return Response.redirect(props.url);
}
const response = await fetch(props.url);
const buffer = await response.arrayBuffer();
return new Response(buffer);
}