mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
rename methods
This commit is contained in:
1 parent
ec161addab
commit
5f737d940d
111 files changed
+563
-413
No files matched your search
@@ -135,6 +135,7 @@
|
|||||||
"radix-ui": "^1.6.7",
|
"radix-ui": "^1.6.7",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
|
"react-error-boundary": "^6.1.3",
|
||||||
"react-promise-suspense": "^0.3.4",
|
"react-promise-suspense": "^0.3.4",
|
||||||
"three": "^0.180.0",
|
"three": "^0.180.0",
|
||||||
"three-stdlib": "^2.36.0",
|
"three-stdlib": "^2.36.0",
|
||||||
@@ -2009,6 +2010,8 @@
|
|||||||
|
|
||||||
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||||
|
|
||||||
|
"react-error-boundary": ["[email protected]", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-GnSKpCohFi2nQmJCWwP8O8wub7zexlePvpsejvQr35vS5RTouS1+utTNOmyc540yw5vyOXnSL1rBWsCQDmkyUA=="],
|
||||||
|
|
||||||
"react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="],
|
"react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="],
|
||||||
|
|
||||||
"react-reconciler": ["[email protected]", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="],
|
"react-reconciler": ["[email protected]", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="],
|
||||||
|
|||||||
@@ -12,14 +12,19 @@ import {
|
|||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
|
|
||||||
export abstract class BlitzKitAPI {
|
export abstract class BlitzKitAPI {
|
||||||
abstract skillDefinitions(): Promise<SkillDefinitions>;
|
abstract skills(): Promise<SkillDefinitions>;
|
||||||
abstract provisionDefinitions(): Promise<ProvisionDefinitions>;
|
abstract provisions(): Promise<ProvisionDefinitions>;
|
||||||
abstract consumableDefinitions(): Promise<ConsumableDefinitions>;
|
abstract consumables(): Promise<ConsumableDefinitions>;
|
||||||
abstract equipmentDefinitions(): Promise<EquipmentDefinitions>;
|
abstract equipments(): Promise<EquipmentDefinitions>;
|
||||||
abstract mapDefinitions(): Promise<MapDefinitions>;
|
abstract maps(): Promise<MapDefinitions>;
|
||||||
abstract modelDefinitions(): Promise<ModelDefinitions>;
|
abstract models(): Promise<ModelDefinitions>;
|
||||||
abstract camouflageDefinitions(): Promise<CamouflageDefinitions>;
|
abstract camouflages(): Promise<CamouflageDefinitions>;
|
||||||
abstract tankDefinitions(): Promise<TankDefinitions>;
|
abstract tanks(): Promise<TankDefinitions>;
|
||||||
abstract gameDefinitions(): Promise<GameDefinitions>;
|
abstract game(): Promise<GameDefinitions>;
|
||||||
abstract galleryDefinitions(): Promise<Gallery>;
|
abstract gallery(): Promise<Gallery>;
|
||||||
|
|
||||||
|
async tank(id: number) {
|
||||||
|
const tanks = await this.tanks();
|
||||||
|
return tanks.tanks[id];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,55 +15,55 @@ import {
|
|||||||
import { BlitzKitAPI } from "./base";
|
import { BlitzKitAPI } from "./base";
|
||||||
|
|
||||||
export class ClientBlitzKitAPI extends BlitzKitAPI {
|
export class ClientBlitzKitAPI extends BlitzKitAPI {
|
||||||
gameDefinitions() {
|
game() {
|
||||||
return fetchPB(alias("api", "/definitions/game.pb"), GameDefinitions);
|
return fetchPB(alias("api", "/definitions/game.pb"), GameDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
consumableDefinitions() {
|
consumables() {
|
||||||
return fetchPB(
|
return fetchPB(
|
||||||
alias("api", "/definitions/consumables.pb"),
|
alias("api", "/definitions/consumables.pb"),
|
||||||
ConsumableDefinitions,
|
ConsumableDefinitions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tankDefinitions() {
|
tanks() {
|
||||||
return fetchPB(alias("api", "/definitions/tanks.pb"), TankDefinitions);
|
return fetchPB(alias("api", "/definitions/tanks.pb"), TankDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
camouflageDefinitions() {
|
camouflages() {
|
||||||
return fetchPB(
|
return fetchPB(
|
||||||
alias("api", "/definitions/camouflage.pb"),
|
alias("api", "/definitions/camouflage.pb"),
|
||||||
CamouflageDefinitions,
|
CamouflageDefinitions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
provisionDefinitions() {
|
provisions() {
|
||||||
return fetchPB(
|
return fetchPB(
|
||||||
alias("api", "/definitions/provisions.pb"),
|
alias("api", "/definitions/provisions.pb"),
|
||||||
ProvisionDefinitions,
|
ProvisionDefinitions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
modelDefinitions() {
|
models() {
|
||||||
return fetchPB(alias("api", "/definitions/models.pb"), ModelDefinitions);
|
return fetchPB(alias("api", "/definitions/models.pb"), ModelDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
skillDefinitions() {
|
skills() {
|
||||||
return fetchPB(alias("api", "/definitions/skills.pb"), SkillDefinitions);
|
return fetchPB(alias("api", "/definitions/skills.pb"), SkillDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
equipmentDefinitions() {
|
equipments() {
|
||||||
return fetchPB(
|
return fetchPB(
|
||||||
alias("api", "/definitions/equipment.pb"),
|
alias("api", "/definitions/equipment.pb"),
|
||||||
EquipmentDefinitions,
|
EquipmentDefinitions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
galleryDefinitions() {
|
gallery() {
|
||||||
return fetchPB(alias("api", "/definitions/gallery.pb"), Gallery);
|
return fetchPB(alias("api", "/definitions/gallery.pb"), Gallery);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapDefinitions() {
|
maps() {
|
||||||
return fetchPB(alias("api", "/definitions/maps.pb"), MapDefinitions);
|
return fetchPB(alias("api", "/definitions/maps.pb"), MapDefinitions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { AbstractVFS, BlitzKitAPI } from "@blitzkit/core";
|
||||||
|
|
||||||
|
export async function createDynamicAPI(vfs: AbstractVFS) {
|
||||||
|
let _api: BlitzKitAPI;
|
||||||
|
|
||||||
|
if (import.meta.env.SSR) {
|
||||||
|
const { ServerBlitzKitAPI } = await import(
|
||||||
|
"@blitzkit/core/src/blitzkit/api/server/index"
|
||||||
|
);
|
||||||
|
|
||||||
|
_api = await new ServerBlitzKitAPI(vfs).init();
|
||||||
|
} else {
|
||||||
|
const { ClientBlitzKitAPI } = await import(
|
||||||
|
"@blitzkit/core/src/blitzkit/api/client"
|
||||||
|
);
|
||||||
|
|
||||||
|
_api = new ClientBlitzKitAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _api;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export * from "./base";
|
||||||
|
export * from "./client";
|
||||||
|
export * from "./dynamic";
|
||||||
|
export * from "./server";
|
||||||
@@ -27,11 +27,14 @@ import {
|
|||||||
import { AbstractVFS } from "@blitzkit/core/src/blitzkit/vfs/abstract";
|
import { AbstractVFS } from "@blitzkit/core/src/blitzkit/vfs/abstract";
|
||||||
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
|
import type { extname, parse } from "node:path";
|
||||||
import { parse as parseYaml } from "yaml";
|
import { parse as parseYaml } from "yaml";
|
||||||
import { BlitzKitAPI } from "../base";
|
import { BlitzKitAPI } from "../base";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
|
export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
|
||||||
protected vfs: AbstractVFS;
|
protected vfs: AbstractVFS;
|
||||||
|
protected parsePath?: typeof parse;
|
||||||
|
protected extname?: typeof extname;
|
||||||
|
|
||||||
protected nationSlugDiscriminators = {
|
protected nationSlugDiscriminators = {
|
||||||
china: "cn",
|
china: "cn",
|
||||||
@@ -109,11 +112,18 @@ export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
|
|||||||
|
|
||||||
constructor(vfs: AbstractVFS) {
|
constructor(vfs: AbstractVFS) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.vfs = vfs;
|
this.vfs = vfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
console.log("Initializing virtual file system...");
|
console.log("Initializing virtual file system...");
|
||||||
|
|
||||||
|
const path = await import("node:path");
|
||||||
|
|
||||||
|
this.extname = path.extname;
|
||||||
|
this.parsePath = path.parse;
|
||||||
|
|
||||||
await this.vfs.init();
|
await this.vfs.init();
|
||||||
|
|
||||||
console.log("Fetching game data...");
|
console.log("Fetching game data...");
|
||||||
|
|||||||
+3
-4
@@ -1,12 +1,11 @@
|
|||||||
import { Avatar, fetchGlossary, Gallery } from "@blitzkit/core";
|
import { Avatar, fetchGlossary, Gallery } from "@blitzkit/core";
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import { extname } from "path";
|
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI9 } from "./9_gameDefinitions";
|
import { ServerBlitzKitAPI9 } from "./9_game";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
|
export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async galleryDefinitions() {
|
async gallery() {
|
||||||
const avatars: Record<string, { avatar: Avatar; url: string }> = {};
|
const avatars: Record<string, { avatar: Avatar; url: string }> = {};
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -34,7 +33,7 @@ export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
|
|||||||
avatars[key].avatar.name!.locales[supported.locale] =
|
avatars[key].avatar.name!.locales[supported.locale] =
|
||||||
glossaryEntry.title;
|
glossaryEntry.title;
|
||||||
} else {
|
} else {
|
||||||
const extension = extname(glossaryEntry.image_url);
|
const extension = this.extname!(glossaryEntry.image_url);
|
||||||
|
|
||||||
avatars[key] = {
|
avatars[key] = {
|
||||||
url: glossaryEntry.image_url,
|
url: glossaryEntry.image_url,
|
||||||
+1
-1
@@ -47,7 +47,7 @@ export abstract class ServerBlitzKitAPI1 extends ServerBlitzKitAPI0 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Cache()
|
@Cache()
|
||||||
async tankDefinitions() {
|
async tanks() {
|
||||||
const tankDefinitions = TankDefinitions.create();
|
const tankDefinitions = TankDefinitions.create();
|
||||||
|
|
||||||
const gameModeNativeNames: Record<string, number> = {};
|
const gameModeNativeNames: Record<string, number> = {};
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { CamouflageDefinitions } from "@blitzkit/core";
|
import { CamouflageDefinitions } from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI1 } from "./1_tankDefinitions";
|
import { ServerBlitzKitAPI1 } from "./1_tanks";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 {
|
export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async camouflageDefinitions() {
|
async camouflages() {
|
||||||
const camouflageDefinitions = CamouflageDefinitions.create();
|
const camouflageDefinitions = CamouflageDefinitions.create();
|
||||||
|
|
||||||
for (const camoKey in this.camouflagesXml!.root.camouflages) {
|
for (const camoKey in this.camouflagesXml!.root.camouflages) {
|
||||||
+11
-13
@@ -6,7 +6,6 @@ import {
|
|||||||
EngineDefinitionsList,
|
EngineDefinitionsList,
|
||||||
GunDefinitionsList,
|
GunDefinitionsList,
|
||||||
ModelDefinitions,
|
ModelDefinitions,
|
||||||
ResearchCost,
|
|
||||||
TankParameters,
|
TankParameters,
|
||||||
toUniqueId,
|
toUniqueId,
|
||||||
TurretDefinitionsList,
|
TurretDefinitionsList,
|
||||||
@@ -15,10 +14,9 @@ import {
|
|||||||
VehicleDefinitionList,
|
VehicleDefinitionList,
|
||||||
VehicleDefinitions,
|
VehicleDefinitions,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
|
||||||
import { ServerBlitzKitAPI2 } from "./2_camouflageDefinitions";
|
|
||||||
import { parse as parsePath } from "path";
|
|
||||||
import { Vector3Tuple } from "three";
|
import { Vector3Tuple } from "three";
|
||||||
|
import { Cache } from "./0_base";
|
||||||
|
import { ServerBlitzKitAPI2 } from "./2_camouflages";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
||||||
private vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
private vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
||||||
@@ -42,7 +40,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Cache()
|
@Cache()
|
||||||
async modelDefinitions() {
|
async models() {
|
||||||
const modelDefinitions = ModelDefinitions.create();
|
const modelDefinitions = ModelDefinitions.create();
|
||||||
|
|
||||||
for (const nation of this.nationsDir!) {
|
for (const nation of this.nationsDir!) {
|
||||||
@@ -65,10 +63,6 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
|||||||
for (const tankKey in tankList.root) {
|
for (const tankKey in tankList.root) {
|
||||||
if (this.botPattern.test(tankKey)) continue;
|
if (this.botPattern.test(tankKey)) continue;
|
||||||
|
|
||||||
const gunXps = new Map<number, ResearchCost>();
|
|
||||||
const turretXps = new Map<number, ResearchCost>();
|
|
||||||
const engineXps = new Map<number, ResearchCost>();
|
|
||||||
const trackXps = new Map<number, ResearchCost>();
|
|
||||||
const tank = tankList.root[tankKey];
|
const tank = tankList.root[tankKey];
|
||||||
const tankDefinition = await this.vfs.xml<{ root: VehicleDefinitions }>(
|
const tankDefinition = await this.vfs.xml<{ root: VehicleDefinitions }>(
|
||||||
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
|
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
|
||||||
@@ -181,7 +175,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
|||||||
Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => {
|
Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => {
|
||||||
const turret = tankDefinition.root.turrets0[turretKey];
|
const turret = tankDefinition.root.turrets0[turretKey];
|
||||||
const turretModel = Number(
|
const turretModel = Number(
|
||||||
parsePath(turret.models.undamaged).name.split("_")[1],
|
this.parsePath!(turret.models.undamaged).name.split("_")[1],
|
||||||
);
|
);
|
||||||
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
|
||||||
const turretYaw = (
|
const turretYaw = (
|
||||||
@@ -229,12 +223,16 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
|||||||
bounding_box: {
|
bounding_box: {
|
||||||
min: this.vector3TupleToBlitzkit(
|
min: this.vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
this.parsePath!(
|
||||||
|
turret.hitTester.collisionModel,
|
||||||
|
).name.toLowerCase()
|
||||||
].bbox.min,
|
].bbox.min,
|
||||||
),
|
),
|
||||||
max: this.vector3TupleToBlitzkit(
|
max: this.vector3TupleToBlitzkit(
|
||||||
tankParameters.collision[
|
tankParameters.collision[
|
||||||
parsePath(turret.hitTester.collisionModel).name.toLowerCase()
|
this.parsePath!(
|
||||||
|
turret.hitTester.collisionModel,
|
||||||
|
).name.toLowerCase()
|
||||||
].bbox.max,
|
].bbox.max,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -253,7 +251,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
|
|||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number) as [number, number];
|
.map(Number) as [number, number];
|
||||||
const gunModel = Number(
|
const gunModel = Number(
|
||||||
parsePath(gun.models.undamaged).name.split("_")[1],
|
this.parsePath!(gun.models.undamaged).name.split("_")[1],
|
||||||
);
|
);
|
||||||
const front = gun.extraPitchLimits?.front
|
const front = gun.extraPitchLimits?.front
|
||||||
? gun.extraPitchLimits.front.split(" ").map(Number)
|
? gun.extraPitchLimits.front.split(" ").map(Number)
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { MapDefinitions } from "@blitzkit/core";
|
import { MapDefinitions } from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI3 } from "./3_modelDefinitions";
|
import { ServerBlitzKitAPI3 } from "./3_models";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI4 extends ServerBlitzKitAPI3 {
|
export abstract class ServerBlitzKitAPI4 extends ServerBlitzKitAPI3 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async mapDefinitions() {
|
async maps() {
|
||||||
const mapDefinitions = MapDefinitions.create();
|
const mapDefinitions = MapDefinitions.create();
|
||||||
|
|
||||||
for (const key in this.mapsYaml!.maps) {
|
for (const key in this.mapsYaml!.maps) {
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/core";
|
import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI4 } from "./4_mapDefinitions";
|
import { ServerBlitzKitAPI4 } from "./4_maps";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI5 extends ServerBlitzKitAPI4 {
|
export abstract class ServerBlitzKitAPI5 extends ServerBlitzKitAPI4 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async equipmentDefinitions() {
|
async equipments() {
|
||||||
const equipmentDefinitions = EquipmentDefinitions.create();
|
const equipmentDefinitions = EquipmentDefinitions.create();
|
||||||
|
|
||||||
Object.entries(this.optionalDevices!.root).forEach(
|
Object.entries(this.optionalDevices!.root).forEach(
|
||||||
+2
-2
@@ -4,11 +4,11 @@ import {
|
|||||||
ConsumableDefinitions,
|
ConsumableDefinitions,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI5 } from "./5_equipmentDefinitions";
|
import { ServerBlitzKitAPI5 } from "./5_equipments";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 {
|
export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async consumableDefinitions() {
|
async consumables() {
|
||||||
const consumableDefinitions = ConsumableDefinitions.create();
|
const consumableDefinitions = ConsumableDefinitions.create();
|
||||||
|
|
||||||
Object.entries(this.consumablesCommon).forEach(([key, consumable]) => {
|
Object.entries(this.consumablesCommon).forEach(([key, consumable]) => {
|
||||||
+2
-2
@@ -4,11 +4,11 @@ import {
|
|||||||
ProvisionDefinitions,
|
ProvisionDefinitions,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI6 } from "./6_consumableDefinitions";
|
import { ServerBlitzKitAPI6 } from "./6_consumables";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
|
export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async provisionDefinitions() {
|
async provisions() {
|
||||||
const provisionDefinitions = ProvisionDefinitions.create();
|
const provisionDefinitions = ProvisionDefinitions.create();
|
||||||
|
|
||||||
Object.entries(this.provisionsCommon).forEach(([, provision]) => {
|
Object.entries(this.provisionsCommon).forEach(([, provision]) => {
|
||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
import { BlitzTankClass, SkillDefinitions } from "@blitzkit/core";
|
import { BlitzTankClass, SkillDefinitions } from "@blitzkit/core";
|
||||||
|
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI7 } from "./7_provisionDefinitions";
|
import { ServerBlitzKitAPI7 } from "./7_provisions";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI8 extends ServerBlitzKitAPI7 {
|
export abstract class ServerBlitzKitAPI8 extends ServerBlitzKitAPI7 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async skillDefinitions() {
|
async skills() {
|
||||||
const skillDefinitions = SkillDefinitions.create();
|
const skillDefinitions = SkillDefinitions.create();
|
||||||
|
|
||||||
for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) {
|
for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) {
|
||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
import { AvailableNationsYaml, GameDefinitions } from "@blitzkit/core";
|
import { AvailableNationsYaml, GameDefinitions } from "@blitzkit/core";
|
||||||
|
|
||||||
import { Cache } from "./0_base";
|
import { Cache } from "./0_base";
|
||||||
import { ServerBlitzKitAPI8 } from "./8_skillDefinitions";
|
import { ServerBlitzKitAPI8 } from "./8_skills";
|
||||||
|
|
||||||
export abstract class ServerBlitzKitAPI9 extends ServerBlitzKitAPI8 {
|
export abstract class ServerBlitzKitAPI9 extends ServerBlitzKitAPI8 {
|
||||||
@Cache()
|
@Cache()
|
||||||
async gameDefinitions() {
|
async game() {
|
||||||
const gameDefinitions = GameDefinitions.create();
|
const gameDefinitions = GameDefinitions.create();
|
||||||
|
|
||||||
const consumableNativeNames: Record<string, number> = {};
|
const consumableNativeNames: Record<string, number> = {};
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
import { ServerBlitzKitAPI10 } from "@blitzkit/core/src/blitzkit/api/server/10_galleryDefinitions";
|
import { ServerBlitzKitAPI10 } from "./10_avatars";
|
||||||
|
|
||||||
export class ServerBlitzKitAPI extends ServerBlitzKitAPI10 {}
|
export class ServerBlitzKitAPI extends ServerBlitzKitAPI10 {}
|
||||||
@@ -10,7 +10,7 @@ export interface AverageDefinitionsManifest {
|
|||||||
latest: number;
|
latest: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchAverageDefinitions() {
|
export async function fetchAverage() {
|
||||||
return await fetchPB(staticAsset("averages.pb"), AverageDefinitions);
|
return await fetchPB(staticAsset("averages.pb"), AverageDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export interface DiscoveredIdsDefinitions {
|
|||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchDiscoveredIdsDefinitions() {
|
export async function fetchDiscoveredIds() {
|
||||||
const response = await fetch(staticAsset("ids/manifest.json"));
|
const response = await fetch(staticAsset("ids/manifest.json"));
|
||||||
return response.json() as Promise<DiscoveredIdsDefinitions>;
|
return response.json() as Promise<DiscoveredIdsDefinitions>;
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./alias";
|
export * from "./alias";
|
||||||
|
export * from "./api";
|
||||||
export * from "./assertSecret";
|
export * from "./assertSecret";
|
||||||
export * from "./availableProvisions";
|
export * from "./availableProvisions";
|
||||||
export * from "./averageDefinitions";
|
export * from "./averageDefinitions";
|
||||||
@@ -30,5 +31,6 @@ export * from "./tankNames";
|
|||||||
export * from "./unionBoundingBox";
|
export * from "./unionBoundingBox";
|
||||||
export * from "./uniqueGuns";
|
export * from "./uniqueGuns";
|
||||||
export * from "./unwrapBlitzkitResponse";
|
export * from "./unwrapBlitzkitResponse";
|
||||||
|
export * from "./vfs";
|
||||||
export * from "./votes";
|
export * from "./votes";
|
||||||
export * from "./youtubers";
|
export * from "./youtubers";
|
||||||
@@ -5,8 +5,8 @@ import { I18nString } from "../protos";
|
|||||||
|
|
||||||
export async function fetchTankNames(api: BlitzKitAPI) {
|
export async function fetchTankNames(api: BlitzKitAPI) {
|
||||||
const [tankDefinitions, camouflageDefinitions] = await Promise.all([
|
const [tankDefinitions, camouflageDefinitions] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
api.camouflageDefinitions(),
|
api.camouflages(),
|
||||||
]);
|
]);
|
||||||
const tankDefinitionsArray = Object.values(tankDefinitions.tanks);
|
const tankDefinitionsArray = Object.values(tankDefinitions.tanks);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export * from "./abstract";
|
||||||
|
export * from "./local";
|
||||||
|
export * from "./mixed";
|
||||||
|
export * from "./steam";
|
||||||
|
export * from "./zip";
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
import {
|
import { asset, Reviews, Video, youtubers } from "@blitzkit/core";
|
||||||
asset,
|
|
||||||
fetchTankDefinitions,
|
|
||||||
Reviews,
|
|
||||||
Video,
|
|
||||||
youtubers,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import { google } from "googleapis";
|
import { google } from "googleapis";
|
||||||
import { cloneDeep, uniqBy } from "lodash-es";
|
import { cloneDeep, uniqBy } from "lodash-es";
|
||||||
@@ -22,7 +16,7 @@ const auth = await google.auth.getClient({
|
|||||||
});
|
});
|
||||||
const youtube = google.youtube({ version: "v3", auth });
|
const youtube = google.youtube({ version: "v3", auth });
|
||||||
|
|
||||||
const tankDefinitions = await fetchTankDefinitions();
|
const tankDefinitions = await fetchTank();
|
||||||
const tanks = Object.values(tankDefinitions.tanks);
|
const tanks = Object.values(tankDefinitions.tanks);
|
||||||
|
|
||||||
const tanksSanitized = tanks
|
const tanksSanitized = tanks
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
"radix-ui": "^1.6.7",
|
"radix-ui": "^1.6.7",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
|
"react-error-boundary": "^6.1.3",
|
||||||
"react-promise-suspense": "^0.3.4",
|
"react-promise-suspense": "^0.3.4",
|
||||||
"three": "^0.180.0",
|
"three": "^0.180.0",
|
||||||
"three-stdlib": "^2.36.0",
|
"three-stdlib": "^2.36.0",
|
||||||
|
|||||||
+11
-17
@@ -1,23 +1,18 @@
|
|||||||
import { alias, Avatar } from "@blitzkit/core";
|
import { alias, Avatar } from "@blitzkit/core";
|
||||||
import { Cross1Icon, DownloadIcon } from "@radix-ui/react-icons";
|
import { Cross1Icon, DownloadIcon } from "@radix-ui/react-icons";
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
Flex,
|
|
||||||
IconButton,
|
|
||||||
Link,
|
|
||||||
Skeleton,
|
|
||||||
Text,
|
|
||||||
} from "@radix-ui/themes";
|
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useIntersection } from "../../hooks/useIntersection";
|
import { useIntersection } from "../hooks/useIntersection";
|
||||||
import { useLocale } from "../../hooks/useLocale";
|
import { useLocale } from "../hooks/useLocale";
|
||||||
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
import type { MaybeSkeletonComponentProps } from "../types/maybeSkeletonComponentProps";
|
||||||
|
import { Flex } from "./Flex";
|
||||||
|
import { Skeleton } from "./Skeleton";
|
||||||
|
import { Text } from "./Text";
|
||||||
|
|
||||||
type GalleryCardProps = MaybeSkeletonComponentProps<{
|
type GalleryCardProps = MaybeSkeletonComponentProps<{
|
||||||
avatar: Avatar;
|
avatar: Avatar;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export function GalleryCard(props: GalleryCardProps) {
|
export function AvatarCard(props: GalleryCardProps) {
|
||||||
const src = alias(
|
const src = alias(
|
||||||
"api",
|
"api",
|
||||||
`/gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`,
|
`/gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`,
|
||||||
@@ -31,17 +26,16 @@ export function GalleryCard(props: GalleryCardProps) {
|
|||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<Flex
|
<Flex
|
||||||
direction="column"
|
column
|
||||||
align="center"
|
align="center"
|
||||||
width="6rem"
|
|
||||||
gap="1"
|
gap="1"
|
||||||
ref={card}
|
ref={card}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
{props.skeleton && (
|
{props.skeleton && (
|
||||||
<>
|
<>
|
||||||
<Skeleton width="100%" height="4.57rem" />
|
<Skeleton />
|
||||||
<Skeleton width="100%" height="1em" />
|
<Skeleton />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -58,7 +52,7 @@ export function GalleryCard(props: GalleryCardProps) {
|
|||||||
alt={unwrap(props.avatar.name!)}
|
alt={unwrap(props.avatar.name!)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text size="1" align="center" style={{ maxWidth: "100%" }}>
|
<Text size="minor" align="center" style={{ maxWidth: "100%" }}>
|
||||||
{unwrap(props.avatar.name!)}
|
{unwrap(props.avatar.name!)}
|
||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
+6
-9
@@ -1,19 +1,18 @@
|
|||||||
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
||||||
import { TextField } from "@radix-ui/themes";
|
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useLocale } from "../../hooks/useLocale";
|
import { useLocale } from "../../hooks/useLocale";
|
||||||
import { Gallery } from "../../stores/gallery";
|
import { Gallery } from "../../stores/gallery";
|
||||||
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
||||||
|
import { TextField } from "../TextField";
|
||||||
|
|
||||||
export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) {
|
export function AvatarsSearch({ skeleton }: MaybeSkeletonComponentProps) {
|
||||||
const input = useRef<HTMLInputElement>(null);
|
const input = useRef<HTMLInputElement>(null);
|
||||||
const { strings } = useLocale();
|
const { strings } = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextField.Root
|
<TextField
|
||||||
variant="classic"
|
|
||||||
disabled={skeleton}
|
disabled={skeleton}
|
||||||
placeholder={strings.website.tools.gallery.search.hint}
|
placeholder={strings.website.tools.avatars.search.hint}
|
||||||
ref={input}
|
ref={input}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
Gallery.mutate((draft) => {
|
Gallery.mutate((draft) => {
|
||||||
@@ -22,9 +21,7 @@ export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TextField.Slot>
|
<MagnifyingGlassIcon />
|
||||||
<MagnifyingGlassIcon />
|
</TextField>
|
||||||
</TextField.Slot>
|
|
||||||
</TextField.Root>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Whitespace-only changes.
+9
-8
@@ -1,6 +1,5 @@
|
|||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import { literals } from "@blitzkit/i18n/src/literals";
|
import { literals } from "@blitzkit/i18n/src/literals";
|
||||||
import { Flex, Text } from "@radix-ui/themes";
|
|
||||||
import fuzzysort from "fuzzysort";
|
import fuzzysort from "fuzzysort";
|
||||||
import { times } from "lodash-es";
|
import { times } from "lodash-es";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
@@ -8,20 +7,22 @@ import { api } from "../../core/blitzkit/api";
|
|||||||
import { useLocale } from "../../hooks/useLocale";
|
import { useLocale } from "../../hooks/useLocale";
|
||||||
import { Gallery } from "../../stores/gallery";
|
import { Gallery } from "../../stores/gallery";
|
||||||
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
|
||||||
|
import { AvatarCard } from "../AvatarCard";
|
||||||
|
import { Flex } from "../Flex";
|
||||||
import { InlineSkeleton } from "../InlineSkeleton";
|
import { InlineSkeleton } from "../InlineSkeleton";
|
||||||
import { GalleryCard } from "./Card";
|
import { Text } from "../Text";
|
||||||
|
|
||||||
export interface Avatar {
|
export interface Avatar {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gallery = await api.galleryDefinitions();
|
const gallery = await api.gallery();
|
||||||
|
|
||||||
const DEFAULT_LOADED = 42;
|
const DEFAULT_LOADED = 42;
|
||||||
const PREVIEW_COUNT = 28;
|
const PREVIEW_COUNT = 28;
|
||||||
|
|
||||||
export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
|
export function AvatarsList({ skeleton }: MaybeSkeletonComponentProps) {
|
||||||
const search = Gallery.use((state) => state.search);
|
const search = Gallery.use((state) => state.search);
|
||||||
const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED);
|
const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED);
|
||||||
const { locale, strings } = useLocale();
|
const { locale, strings } = useLocale();
|
||||||
@@ -48,9 +49,9 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
|
|||||||
<>
|
<>
|
||||||
<Text align="center" color="gray">
|
<Text align="center" color="gray">
|
||||||
{skeleton ? (
|
{skeleton ? (
|
||||||
<InlineSkeleton width="7rem" />
|
<InlineSkeleton />
|
||||||
) : (
|
) : (
|
||||||
literals(strings.website.tools.gallery.search.results, {
|
literals(strings.website.tools.avatars.search.results, {
|
||||||
count: filtered.length.toLocaleString(locale),
|
count: filtered.length.toLocaleString(locale),
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
@@ -60,14 +61,14 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
|
|||||||
{!skeleton &&
|
{!skeleton &&
|
||||||
filtered
|
filtered
|
||||||
.slice(0, loadedCards)
|
.slice(0, loadedCards)
|
||||||
.map((avatar) => <GalleryCard key={avatar.id} avatar={avatar} />)}
|
.map((avatar) => <AvatarCard key={avatar.id} avatar={avatar} />)}
|
||||||
|
|
||||||
{times(
|
{times(
|
||||||
skeleton
|
skeleton
|
||||||
? DEFAULT_LOADED + PREVIEW_COUNT
|
? DEFAULT_LOADED + PREVIEW_COUNT
|
||||||
: Math.min(PREVIEW_COUNT, filtered.length - loadedCards),
|
: Math.min(PREVIEW_COUNT, filtered.length - loadedCards),
|
||||||
(index) => (
|
(index) => (
|
||||||
<GalleryCard
|
<AvatarCard
|
||||||
key={index}
|
key={index}
|
||||||
skeleton
|
skeleton
|
||||||
onIntersection={() => setLoadedCards((state) => state + 2)}
|
onIntersection={() => setLoadedCards((state) => state + 2)}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.code {
|
||||||
|
font: inherit;
|
||||||
|
font-family: var(--font-family-mono);
|
||||||
|
|
||||||
|
white-space: pre;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&[data-variant="solid"] {
|
||||||
|
background-color: var(--gray-3);
|
||||||
|
|
||||||
|
border-radius: var(--space-3);
|
||||||
|
|
||||||
|
padding: var(--space-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { classNames } from "../../ui/classNames";
|
||||||
|
import { Text, type TextProps } from "../Text";
|
||||||
|
import styles from "./index.module.css";
|
||||||
|
|
||||||
|
export interface CodeProps extends TextProps {
|
||||||
|
lowContrast?: boolean;
|
||||||
|
variant?: "ghost" | "solid";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Code({ className, variant = "ghost", ...props }: CodeProps) {
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
data-variant={variant}
|
||||||
|
className={classNames(styles.code, className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -39,10 +39,10 @@ const [
|
|||||||
consumableDefinitions,
|
consumableDefinitions,
|
||||||
provisionDefinitions,
|
provisionDefinitions,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
api.skillDefinitions(),
|
api.skill(),
|
||||||
api.equipmentDefinitions(),
|
api.equipment(),
|
||||||
api.consumableDefinitions(),
|
api.consumables(),
|
||||||
api.provisionDefinitions(),
|
api.provisions(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function CompareTable({ stats }: CompareTableProps) {
|
export function CompareTable({ stats }: CompareTableProps) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface ControlsProps {
|
|||||||
onAddTankDialogOpenChange: (open: boolean) => void;
|
onAddTankDialogOpenChange: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function Controls({
|
export function Controls({
|
||||||
addTankDialogOpen,
|
addTankDialogOpen,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ interface TankControlProps {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function TankControl({ index, slug }: TankControlProps) {
|
export function TankControl({ index, slug }: TankControlProps) {
|
||||||
const { locale, strings } = useLocale();
|
const { locale, strings } = useLocale();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface CrewSkillManagerProps {
|
|||||||
onChange?: (skillLevels: Record<string, number>) => void;
|
onChange?: (skillLevels: Record<string, number>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const skillDefinitions = await api.skillDefinitions();
|
const skillDefinitions = await api.skill();
|
||||||
|
|
||||||
export function CrewSkillManager({
|
export function CrewSkillManager({
|
||||||
skillLevels,
|
skillLevels,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const compositeStatsKeysOptions = compositeStatsKeys.map((value) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
|
|
||||||
awaitableAverageDefinitions,
|
awaitableAverageDefinitions,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
.error-display {
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
gap: var(--space-4);
|
||||||
|
padding: var(--space-4);
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100dvw;
|
||||||
|
height: 100dvh;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
background-color: var(--gray-1);
|
||||||
|
|
||||||
|
.info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
max-width: min(100%, var(--page-width));
|
||||||
|
|
||||||
|
.cover {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
width: 25%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background: linear-gradient(90deg, transparent, var(--gray-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import { useState, type ReactNode } from "react";
|
||||||
|
import {
|
||||||
|
ErrorBoundary,
|
||||||
|
getErrorMessage,
|
||||||
|
type FallbackProps,
|
||||||
|
} from "react-error-boundary";
|
||||||
|
import { discordLink } from "../../config/socials";
|
||||||
|
import { Button } from "../Button";
|
||||||
|
import { Code } from "../Code";
|
||||||
|
import { Heading } from "../Heading";
|
||||||
|
import { Link } from "../Link";
|
||||||
|
import { Text } from "../Text";
|
||||||
|
import styles from "./index.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ErrorWrapper({ children }: Props) {
|
||||||
|
return (
|
||||||
|
<ErrorBoundary fallbackRender={(props) => <Fallback {...props} />}>
|
||||||
|
{children}
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Fallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||||
|
const [showError, setShowError] = useState(false);
|
||||||
|
|
||||||
|
let body: string | undefined;
|
||||||
|
|
||||||
|
if (error instanceof Error) {
|
||||||
|
body = error.stack || getErrorMessage(error);
|
||||||
|
} else {
|
||||||
|
body = getErrorMessage(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
body ??= "No error message";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles["error-display"]}>
|
||||||
|
<div className={styles.info}>
|
||||||
|
<Heading size="3">BlitzKit crashed</Heading>
|
||||||
|
<Text lowContrast>Sorry about that! You have a couple of options.</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{showError && (
|
||||||
|
<Code variant="solid" className={styles.error}>
|
||||||
|
{body}
|
||||||
|
<div className={styles.cover} />
|
||||||
|
</Code>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={styles.options}>
|
||||||
|
{!showError && (
|
||||||
|
<Button variant="outline" onClick={() => setShowError(true)}>
|
||||||
|
View error
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showError && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => navigator.clipboard.writeText(body)}
|
||||||
|
>
|
||||||
|
Copy error
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Link href="" underline="never">
|
||||||
|
<Button variant="outline">Hard reload</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Button variant="outline" onClick={resetErrorBoundary}>
|
||||||
|
Soft reset
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Link href={discordLink} target="_blank" underline="never">
|
||||||
|
<Button>Discord server</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ export interface Props {
|
|||||||
locale: string;
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gameDefinitions = await api.gameDefinitions();
|
const gameDefinitions = await api.game();
|
||||||
const environment = assertSecret(import.meta.env.PUBLIC_ENVIRONMENT);
|
const environment = assertSecret(import.meta.env.PUBLIC_ENVIRONMENT);
|
||||||
const { locale } = Astro.props;
|
const { locale } = Astro.props;
|
||||||
const strings = getStrings(locale);
|
const strings = getStrings(locale);
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import { Tankopedia } from "../../stores/tankopedia";
|
|||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
const [modelDefinitions, provisionDefinitions] = await Promise.all([
|
const [modelDefinitions, provisionDefinitions] = await Promise.all([
|
||||||
api.modelDefinitions(),
|
api.models(),
|
||||||
api.provisionDefinitions(),
|
api.provisions(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function GuessBackground() {
|
export function GuessBackground() {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const { go } = fuzzysort;
|
|||||||
|
|
||||||
const [tankNames, tankDefinitions] = await Promise.all([
|
const [tankNames, tankDefinitions] = await Promise.all([
|
||||||
awaitableTankNames,
|
awaitableTankNames,
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ids = Object.keys(tankDefinitions.tanks);
|
const ids = Object.keys(tankDefinitions.tanks);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import { TankCard } from "./TankCard";
|
import { TankCard } from "./TankCard";
|
||||||
|
|
||||||
const [tankDefinitions, popularTanks] = await Promise.all([
|
const [tankDefinitions, popularTanks] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
awaitablePopularTanks,
|
awaitablePopularTanks,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { controlsEnabledEvent } from "../../../core/controlsEnabled";
|
|||||||
import { useModel } from "../../../hooks/useModel";
|
import { useModel } from "../../../hooks/useModel";
|
||||||
import { Mixer } from "../../../stores/mixer";
|
import { Mixer } from "../../../stores/mixer";
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
export function Model() {
|
export function Model() {
|
||||||
const canvas = useThree((state) => state.gl.domElement);
|
const canvas = useThree((state) => state.gl.domElement);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ interface ConsumableButtonProps extends TankComponentButtonProps {
|
|||||||
cooldown?: number;
|
cooldown?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const consumableDefinitions = await api.consumableDefinitions();
|
const consumableDefinitions = await api.consumables();
|
||||||
|
|
||||||
export function ConsumableButton({
|
export function ConsumableButton({
|
||||||
consumable,
|
consumable,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface EquipmentButtonProps extends TankComponentButtonProps {
|
|||||||
equipment: number;
|
equipment: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const equipmentDefinitions = await api.equipmentDefinitions();
|
const equipmentDefinitions = await api.equipment();
|
||||||
|
|
||||||
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
|
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
|
||||||
const { unwrap } = useLocale();
|
const { unwrap } = useLocale();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ interface ProvisionButtonProps extends TankComponentButtonProps {
|
|||||||
provision: number;
|
provision: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
|
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
|
||||||
const { unwrap } = useLocale();
|
const { unwrap } = useLocale();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const PREVIEW_COUNT = 10;
|
|||||||
const DEFAULT_LOADED_ROWS = 25;
|
const DEFAULT_LOADED_ROWS = 25;
|
||||||
|
|
||||||
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
awaitableAverageDefinitions,
|
awaitableAverageDefinitions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import type { MaybeSkeletonComponentProps } from "../types/maybeSkeletonComponen
|
|||||||
import { LinkI18n } from "./LinkI18n";
|
import { LinkI18n } from "./LinkI18n";
|
||||||
import { TankSearchFilters } from "./TankSearchFilters";
|
import { TankSearchFilters } from "./TankSearchFilters";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
const POOL_HEIGHT = "16rem";
|
const POOL_HEIGHT = "16rem";
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ interface Props extends PlaylistEntry {
|
|||||||
index: number;
|
index: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export const PlaylistTankEntry = memo<Props>(
|
export const PlaylistTankEntry = memo<Props>(
|
||||||
({ id, checked, then, now, index }) => {
|
({ id, checked, then, now, index }) => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ interface ProvisionsManagerProps {
|
|||||||
onChange?: (provisions: number[]) => void;
|
onChange?: (provisions: number[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function ProvisionsManager({
|
export function ProvisionsManager({
|
||||||
provisions,
|
provisions,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { TankCardWrapper } from "../TankCardWrapper";
|
|||||||
import { Text } from "../Text";
|
import { Text } from "../Text";
|
||||||
import styles from "./index.module.css";
|
import styles from "./index.module.css";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function RecentlyViewedTanks() {
|
export function RecentlyViewedTanks() {
|
||||||
const filters = TankFilters.use();
|
const filters = TankFilters.use();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type TankCardProps = {
|
|||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export const TankCard = (props: MaybeSkeletonComponentProps<TankCardProps>) => {
|
export const TankCard = (props: MaybeSkeletonComponentProps<TankCardProps>) => {
|
||||||
if (props.skeleton) {
|
if (props.skeleton) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface TankSearchCardProps {
|
|||||||
onSelect?: (tank: TankDefinition) => void;
|
onSelect?: (tank: TankDefinition) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ export type TankSearchProps = MaybeSkeletonComponentProps & {
|
|||||||
|
|
||||||
const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] =
|
const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
api.gameDefinitions(),
|
api.game(),
|
||||||
api.modelDefinitions(),
|
api.models(),
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
awaitableTankNames,
|
awaitableTankNames,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
alias,
|
alias,
|
||||||
GunDefinition,
|
GunDefinition,
|
||||||
ShellType,
|
ShellType,
|
||||||
TANK_CLASSES,
|
TANK_CLASSES,
|
||||||
TANK_TYPES,
|
TANK_TYPES,
|
||||||
TankType,
|
TankType,
|
||||||
TIER_ROMAN_NUMERALS,
|
TIER_ROMAN_NUMERALS,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
import { literals } from "@blitzkit/i18n";
|
import { literals } from "@blitzkit/i18n";
|
||||||
import locales from "@blitzkit/i18n/locales.json";
|
import locales from "@blitzkit/i18n/locales.json";
|
||||||
import {
|
import {
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
LockOpen2Icon,
|
LockOpen2Icon,
|
||||||
ResetIcon,
|
ResetIcon,
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
} from "@radix-ui/react-icons";
|
} from "@radix-ui/react-icons";
|
||||||
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";
|
||||||
@@ -37,10 +37,10 @@ import { Text } from "../Text";
|
|||||||
import { Tooltip } from "../Tooltip";
|
import { Tooltip } from "../Tooltip";
|
||||||
import styles from "./index.module.css";
|
import styles from "./index.module.css";
|
||||||
|
|
||||||
const gameDefinitions = await api.gameDefinitions();
|
const gameDefinitions = await api.game();
|
||||||
const consumableDefinitions = await api.consumableDefinitions();
|
const consumableDefinitions = await api.consumables();
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
const gameModeRoleSets: Record<number, Set<number>> = {};
|
const gameModeRoleSets: Record<number, Set<number>> = {};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { AesonPlug } from "../AesonPlug";
|
|||||||
import { ExperimentIcon } from "../ExperimentIcon";
|
import { ExperimentIcon } from "../ExperimentIcon";
|
||||||
import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants";
|
import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function CalloutsSection() {
|
export function CalloutsSection() {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import { InfoWithDelta } from "./InfoWithDelta";
|
|||||||
import { StatsTableWrapper } from "./StatsTableWrapper";
|
import { StatsTableWrapper } from "./StatsTableWrapper";
|
||||||
import type { StatsAcceptorProps } from "./TraverseVisualizer";
|
import type { StatsAcceptorProps } from "./TraverseVisualizer";
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function Crew({ stats }: StatsAcceptorProps) {
|
export function Crew({ stats }: StatsAcceptorProps) {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import {
|
|||||||
import { Duel } from "../../../../../../../../stores/duel";
|
import { Duel } from "../../../../../../../../stores/duel";
|
||||||
import { ModelChunk } from "./ModelChunk";
|
import { ModelChunk } from "./ModelChunk";
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
export function CanvasContent() {
|
export function CanvasContent() {
|
||||||
const hullWrapper = useRef<Group>(null);
|
const hullWrapper = useRef<Group>(null);
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { jsxTree } from "../../../../../../../../core/blitzkit/jsxTree";
|
|||||||
import { useModel } from "../../../../../../../../hooks/useModel";
|
import { useModel } from "../../../../../../../../hooks/useModel";
|
||||||
import { Duel } from "../../../../../../../../stores/duel";
|
import { Duel } from "../../../../../../../../stores/duel";
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = {
|
const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = {
|
||||||
gun: new MeshBasicMaterial({
|
gun: new MeshBasicMaterial({
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import { FlexibilityCanvas } from "./components/FlexibilityCanvas";
|
|||||||
|
|
||||||
const ANGLE_COEFFICIENT = 1 / 10;
|
const ANGLE_COEFFICIENT = 1 / 10;
|
||||||
|
|
||||||
const modelDefinition = await api.modelDefinitions();
|
const modelDefinition = await api.models();
|
||||||
|
|
||||||
function mag(x: number) {
|
function mag(x: number) {
|
||||||
return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2;
|
return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2;
|
||||||
|
|||||||
+5
-5
@@ -37,11 +37,11 @@ const [
|
|||||||
modelDefinitions,
|
modelDefinitions,
|
||||||
skillDefinitions,
|
skillDefinitions,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
api.provisionDefinitions(),
|
api.provisions(),
|
||||||
api.equipmentDefinitions(),
|
api.equipment(),
|
||||||
api.modelDefinitions(),
|
api.models(),
|
||||||
api.skillDefinitions(),
|
api.skill(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
export const InfoWithDelta = memo<InfoWithDeltaProps>(
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@ import { Maneuverability } from "./components/Maneuverability";
|
|||||||
import { Survivability } from "./components/Survivability";
|
import { Survivability } from "./components/Survivability";
|
||||||
|
|
||||||
const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
|
const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
|
||||||
api.equipmentDefinitions(),
|
api.equipment(),
|
||||||
api.provisionDefinitions(),
|
api.provisions(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
|
export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ import { Duel } from "../../../../stores/duel";
|
|||||||
import { ConsumablesManager } from "../../../ConsumablesManager";
|
import { ConsumablesManager } from "../../../ConsumablesManager";
|
||||||
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
||||||
|
|
||||||
const consumableDefinitions = await api.consumableDefinitions();
|
const consumableDefinitions = await api.consumables();
|
||||||
|
|
||||||
export function Consumables() {
|
export function Consumables() {
|
||||||
const protagonist = Duel.use((state) => state.protagonist);
|
const protagonist = Duel.use((state) => state.protagonist);
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { Duel } from "../../../../stores/duel";
|
|||||||
import { EquipmentManager } from "../../../EquipmentManager";
|
import { EquipmentManager } from "../../../EquipmentManager";
|
||||||
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
||||||
|
|
||||||
const equipmentDefinitions = await api.equipmentDefinitions();
|
const equipmentDefinitions = await api.equipment();
|
||||||
|
|
||||||
export function Equipment() {
|
export function Equipment() {
|
||||||
const protagonist = Duel.use((state) => state.protagonist);
|
const protagonist = Duel.use((state) => state.protagonist);
|
||||||
|
|||||||
+1
-1
@@ -156,7 +156,7 @@ function ModuleButton({
|
|||||||
return <Tooltip content={tooltip}>{node}</Tooltip>;
|
return <Tooltip content={tooltip}>{node}</Tooltip>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function Modules() {
|
export function Modules() {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { Duel } from "../../../../stores/duel";
|
|||||||
import { ProvisionsManager } from "../../../ProvisionsManager";
|
import { ProvisionsManager } from "../../../ProvisionsManager";
|
||||||
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
|
||||||
|
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
|
|
||||||
export function Provisions() {
|
export function Provisions() {
|
||||||
const { tank, gun } = Duel.use((state) => state.protagonist);
|
const { tank, gun } = Duel.use((state) => state.protagonist);
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ import { useLocale } from "../../hooks/useLocale";
|
|||||||
import { Duel } from "../../stores/duel";
|
import { Duel } from "../../stores/duel";
|
||||||
|
|
||||||
const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
|
const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
|
||||||
await Promise.all([
|
await Promise.all([api.game(), api.consumables(), api.provisions()]);
|
||||||
api.gameDefinitions(),
|
|
||||||
api.consumableDefinitions(),
|
|
||||||
api.provisionDefinitions(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
export function GameModeSection() {
|
export function GameModeSection() {
|
||||||
const { unwrap, strings } = useLocale();
|
const { unwrap, strings } = useLocale();
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ const poseDistances: Record<Pose, number> = {
|
|||||||
|
|
||||||
const inspectModeInitialPosition = new Vector3(-8, 2, -13);
|
const inspectModeInitialPosition = new Vector3(-8, 2, -13);
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
interface ControlsProps {
|
interface ControlsProps {
|
||||||
autoRotate?: boolean;
|
autoRotate?: boolean;
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { api } from "../../../../../../core/blitzkit/api";
|
|||||||
import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform";
|
import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform";
|
||||||
import { Duel } from "../../../../../../stores/duel";
|
import { Duel } from "../../../../../../stores/duel";
|
||||||
|
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
export function InitialAligner() {
|
export function InitialAligner() {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { Options } from "./components/Options";
|
|||||||
import { TankSandbox } from "./components/TankSandbox";
|
import { TankSandbox } from "./components/TankSandbox";
|
||||||
import { Title } from "./components/TankSandbox/Title";
|
import { Title } from "./components/TankSandbox/Title";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
||||||
const equalize = Duel.use((state) => state.equalize);
|
const equalize = Duel.use((state) => state.equalize);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type NodeProps = MaybeSkeletonComponentProps & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
const [tankDefinitions, averageDefinitions] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
awaitableAverageDefinitions,
|
awaitableAverageDefinitions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { Node } from "./components/Node";
|
|||||||
|
|
||||||
type Line = number[];
|
type Line = number[];
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10];
|
export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10];
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface TierListRowProps {
|
|||||||
index: number;
|
index: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function TierListRow({ index }: TierListRowProps) {
|
export function TierListRow({ index }: TierListRowProps) {
|
||||||
const tanks = TierList.use((state) => state.rows[index].tanks);
|
const tanks = TierList.use((state) => state.rows[index].tanks);
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import { api } from "../../core/blitzkit/api";
|
|||||||
import { filterTanks } from "../../core/blitzkit/filterTanks";
|
import { filterTanks } from "../../core/blitzkit/filterTanks";
|
||||||
import { TankFilters } from "../../stores/tankFilters";
|
import { TankFilters } from "../../stores/tankFilters";
|
||||||
import { TierList } from "../../stores/tierList";
|
import { TierList } from "../../stores/tierList";
|
||||||
import { TankCardWrapper } from "../TankCardWrapper";
|
|
||||||
import { TankCardSkeleton } from "../TankCardSkeleton";
|
import { TankCardSkeleton } from "../TankCardSkeleton";
|
||||||
|
import { TankCardWrapper } from "../TankCardWrapper";
|
||||||
import { TierListTile } from "./Tile";
|
import { TierListTile } from "./Tile";
|
||||||
|
|
||||||
const [tankDefinitions, gameDefinitions] = await Promise.all([
|
const [tankDefinitions, gameDefinitions] = await Promise.all([
|
||||||
api.tankDefinitions(),
|
api.tanks(),
|
||||||
api.gameDefinitions(),
|
api.game(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tanks = Object.values(tankDefinitions.tanks);
|
const tanks = Object.values(tankDefinitions.tanks);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { api } from "../../core/blitzkit/api";
|
|||||||
import { generateTierListParams } from "../../core/blitzkit/generateTierListParams";
|
import { generateTierListParams } from "../../core/blitzkit/generateTierListParams";
|
||||||
import { TierList } from "../../stores/tierList";
|
import { TierList } from "../../stores/tierList";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function URLManager() {
|
export function URLManager() {
|
||||||
const rows = TierList.use((state) => state.rows);
|
const rows = TierList.use((state) => state.rows);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export const discordLink = "https://discord.gg/nDt7AjGJQH";
|
||||||
@@ -1,3 +1 @@
|
|||||||
import { fetchAverageDefinitions } from '@blitzkit/core';
|
export const awaitableAverageDefinitions = fetchAverage();
|
||||||
|
|
||||||
export const awaitableAverageDefinitions = fetchAverageDefinitions();
|
|
||||||
@@ -1,4 +1 @@
|
|||||||
import { fetchDiscoveredIdsDefinitions } from '@blitzkit/core';
|
export const awaitableDiscoveredIdsDefinitions = fetchDiscoveredIds();
|
||||||
|
|
||||||
export const awaitableDiscoveredIdsDefinitions =
|
|
||||||
fetchDiscoveredIdsDefinitions();
|
|
||||||
@@ -1,20 +1,4 @@
|
|||||||
import type { BlitzKitAPI } from "@blitzkit/core/src/blitzkit/api/base";
|
import { createDynamicAPI } from "@blitzkit/core";
|
||||||
|
import { vfs } from "./vfs";
|
||||||
|
|
||||||
let _api: BlitzKitAPI;
|
export const api = await createDynamicAPI(vfs);
|
||||||
|
|
||||||
if (import.meta.env.SSR) {
|
|
||||||
const { ServerBlitzKitAPI } = await import(
|
|
||||||
"@blitzkit/core/src/blitzkit/api/server/index"
|
|
||||||
);
|
|
||||||
const { vfs } = await import("./vfs");
|
|
||||||
|
|
||||||
_api = await new ServerBlitzKitAPI(vfs).init();
|
|
||||||
} else {
|
|
||||||
const { ClientBlitzKitAPI } = await import(
|
|
||||||
"@blitzkit/core/src/blitzkit/api/client"
|
|
||||||
);
|
|
||||||
|
|
||||||
_api = new ClientBlitzKitAPI();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const api = _api;
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
const modelDefinitions = await api.modelDefinitions();
|
const modelDefinitions = await api.models();
|
||||||
|
|
||||||
const tanks = Object.values(tankDefinitions.tanks).filter((tank) => {
|
const tanks = Object.values(tankDefinitions.tanks).filter((tank) => {
|
||||||
const tankModel = modelDefinitions.models[tank.id];
|
const tankModel = modelDefinitions.models[tank.id];
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import { api } from "./api";
|
|||||||
|
|
||||||
const SHELLS = times(3, (index) => index);
|
const SHELLS = times(3, (index) => index);
|
||||||
|
|
||||||
const consumableDefinitions = await api.consumableDefinitions();
|
const consumableDefinitions = await api.consumables();
|
||||||
const provisionDefinitions = await api.provisionDefinitions();
|
const provisionDefinitions = await api.provisions();
|
||||||
const gameDefinitions = await api.gameDefinitions();
|
const gameDefinitions = await api.game();
|
||||||
|
|
||||||
export async function filterTank(
|
export async function filterTank(
|
||||||
filters: TankFilters,
|
filters: TankFilters,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { TankFilters } from "../../stores/tankFilters";
|
|||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
import { filterTanks } from "./filterTanks";
|
import { filterTanks } from "./filterTanks";
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
const tanks = Object.values(tankDefinitions.tanks);
|
const tanks = Object.values(tankDefinitions.tanks);
|
||||||
|
|
||||||
export async function generatePlaylist() {
|
export async function generatePlaylist() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { EquipmentMatrix } from "../../stores/duel";
|
import type { EquipmentMatrix } from "../../stores/duel";
|
||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
|
|
||||||
const equipmentDefinitions = await api.equipmentDefinitions();
|
const equipmentDefinitions = await api.equipment();
|
||||||
|
|
||||||
export function hasEquipment(
|
export function hasEquipment(
|
||||||
id: number,
|
id: number,
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { ErrorWrapper } from "../components/ErrorWrapper";
|
||||||
|
|
||||||
|
export function withErrorWrapper<Props extends object>(
|
||||||
|
Component: (props: Props) => ReactNode,
|
||||||
|
) {
|
||||||
|
return function (props: Props) {
|
||||||
|
return (
|
||||||
|
<ErrorWrapper>
|
||||||
|
<Component {...props} />
|
||||||
|
</ErrorWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { LocaleProvider } from "../hooks/useLocale";
|
||||||
|
|
||||||
|
interface WithLocaleProps {
|
||||||
|
locale: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withLocale<Props extends object>(
|
||||||
|
Component: (props: Props) => ReactNode,
|
||||||
|
) {
|
||||||
|
return function ({ locale, ...props }: Props & WithLocaleProps) {
|
||||||
|
return (
|
||||||
|
<LocaleProvider locale={locale}>
|
||||||
|
<Component {...(props as Props)} />
|
||||||
|
</LocaleProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { use } from "react";
|
||||||
|
|
||||||
|
const cache = new Map<string, Promise<unknown>>();
|
||||||
|
|
||||||
|
export function useAwait<Type>(
|
||||||
|
creator: () => Promise<Type>,
|
||||||
|
discriminator: string,
|
||||||
|
) {
|
||||||
|
let promise;
|
||||||
|
|
||||||
|
if (cache.has(discriminator)) {
|
||||||
|
promise = cache.get(discriminator) as Promise<Type>;
|
||||||
|
} else {
|
||||||
|
promise = creator();
|
||||||
|
cache.set(discriminator, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
return use(promise);
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ export enum UseEccentricityMode {
|
|||||||
Class,
|
Class,
|
||||||
}
|
}
|
||||||
|
|
||||||
const tankDefinitions = await api.tankDefinitions();
|
const tankDefinitions = await api.tanks();
|
||||||
|
|
||||||
export function useEccentricity(mode: UseEccentricityMode) {
|
export function useEccentricity(mode: UseEccentricityMode) {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useMemo } from "react";
|
|||||||
import { api } from "../core/blitzkit/api";
|
import { api } from "../core/blitzkit/api";
|
||||||
import { Duel } from "../stores/duel";
|
import { Duel } from "../stores/duel";
|
||||||
|
|
||||||
const equipmentDefinitions = await api.equipmentDefinitions();
|
const equipmentDefinitions = await api.equipment();
|
||||||
|
|
||||||
export function useEquipment(id: number, antagonist = false) {
|
export function useEquipment(id: number, antagonist = false) {
|
||||||
const member = Duel.use(
|
const member = Duel.use(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { api } from "../core/blitzkit/api";
|
import { api } from "../core/blitzkit/api";
|
||||||
|
|
||||||
const equipmentDefinitions = await api.equipmentDefinitions();
|
const equipmentDefinitions = await api.equipment();
|
||||||
|
|
||||||
export function useEquipmentPreset(preset: string) {
|
export function useEquipmentPreset(preset: string) {
|
||||||
return equipmentDefinitions.presets[preset];
|
return equipmentDefinitions.presets[preset];
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.camouflageDefinitions();
|
const definitions = await api.camouflage();
|
||||||
const bytes = CamouflageDefinitions.encode(definitions).finish();
|
const bytes = CamouflageDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.consumableDefinitions();
|
const definitions = await api.consumables();
|
||||||
const bytes = ConsumableDefinitions.encode(definitions).finish();
|
const bytes = ConsumableDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.equipmentDefinitions();
|
const definitions = await api.equipment();
|
||||||
const bytes = EquipmentDefinitions.encode(definitions).finish();
|
const bytes = EquipmentDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.galleryDefinitions();
|
const definitions = await api.gallery();
|
||||||
const bytes = Gallery.encode(definitions).finish();
|
const bytes = Gallery.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.gameDefinitions();
|
const definitions = await api.game();
|
||||||
const bytes = GameDefinitions.encode(definitions).finish();
|
const bytes = GameDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.mapDefinitions();
|
const definitions = await api.map();
|
||||||
const bytes = MapDefinitions.encode(definitions).finish();
|
const bytes = MapDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.modelDefinitions();
|
const definitions = await api.models();
|
||||||
const bytes = ModelDefinitions.encode(definitions).finish();
|
const bytes = ModelDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.provisionDefinitions();
|
const definitions = await api.provisions();
|
||||||
const bytes = ProvisionDefinitions.encode(definitions).finish();
|
const bytes = ProvisionDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.skillDefinitions();
|
const definitions = await api.skill();
|
||||||
const bytes = SkillDefinitions.encode(definitions).finish();
|
const bytes = SkillDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
|
|||||||
export { getStaticPaths } from "../_index";
|
export { getStaticPaths } from "../_index";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const definitions = await api.tankDefinitions();
|
const definitions = await api.tanks();
|
||||||
const bytes = TankDefinitions.encode(definitions).finish();
|
const bytes = TankDefinitions.encode(definitions).finish();
|
||||||
|
|
||||||
return new Response(bytes);
|
return new Response(bytes);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { mixStaticPaths } from "../../../../core/blitzkit/mixStaticPaths";
|
|||||||
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||||
|
|
||||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||||
const tanks = await api.tankDefinitions();
|
const tanks = await api.tanks();
|
||||||
|
|
||||||
return Object.values(tanks.tanks).map((tank) => ({
|
return Object.values(tanks.tanks).map((tank) => ({
|
||||||
params: { id: tank.id },
|
params: { id: tank.id },
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { GalleryList } from "../../../../components/Gallery/List";
|
import { AvatarsSearch } from "../../../../components/Avatars/Search";
|
||||||
import { GallerySearch } from "../../../../components/Gallery/Search";
|
import { AvatarsList } from "../../../../components/AvatarsList";
|
||||||
import { PageWrapper } from "../../../../components/PageWrapper";
|
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
LocaleProvider,
|
||||||
type LocaleAcceptorProps,
|
type LocaleAcceptorProps,
|
||||||
@@ -20,9 +19,9 @@ export function Page({
|
|||||||
|
|
||||||
function Content({ skeleton }: MaybeSkeletonComponentProps) {
|
function Content({ skeleton }: MaybeSkeletonComponentProps) {
|
||||||
return (
|
return (
|
||||||
<PageWrapper maxWidth="80rem" color="gold">
|
<>
|
||||||
<GallerySearch skeleton={skeleton} />
|
<AvatarsSearch skeleton={skeleton} />
|
||||||
<GalleryList skeleton={skeleton} />
|
<AvatarsList skeleton={skeleton} />
|
||||||
</PageWrapper>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Loaded 100 of 111 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user