mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: useAwait
This commit is contained in:
1 parent
42cada1811
commit
4033e8618f
6 files changed
+90
-27
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { TankAttributeChange_AttributeName } from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||
|
||||
enum CharacteristicsGroup {
|
||||
export enum CharacteristicsGroup {
|
||||
Firepower,
|
||||
Maneuverability,
|
||||
Survivability,
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
import { TankCatalogComponent } from "@protos/blitz_static_tank_component";
|
||||
import { AbstractAPI } from "./abstract";
|
||||
|
||||
export class ClientAPI extends AbstractAPI {}
|
||||
export class ClientAPI extends AbstractAPI {
|
||||
async tank(id: string) {
|
||||
const response = await fetch(`/api/tanks/${id}.pb`);
|
||||
const buffer = await response.arrayBuffer();
|
||||
const array = new Uint8Array(buffer);
|
||||
|
||||
return TankCatalogComponent.decode(array);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { TankCatalogComponent } from "@protos/blitz_static_tank_component";
|
||||
import type { APIContext, GetStaticPaths } from "astro";
|
||||
import { api } from "../../../core/api/dynamic";
|
||||
|
||||
export const getStaticPaths = (async () => {
|
||||
const { tanks } = await api.tanks();
|
||||
|
||||
return tanks.map(({ id }) => ({ params: { id } }));
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
export async function GET({ params }: APIContext<never, { id: string }>) {
|
||||
const tank = await api.tank(params.id);
|
||||
return new Response(TankCatalogComponent.encode(tank).finish());
|
||||
}
|
||||
@@ -2,45 +2,66 @@ import {
|
||||
TankAttributeChange_AttributeName,
|
||||
TankAttributeChange_Modifier,
|
||||
} from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||
import { use } from "react";
|
||||
import { Suspense, useMemo } from "react";
|
||||
import {
|
||||
CharacteristicsGroup,
|
||||
characteristicsOrder,
|
||||
} from "../../../constants/characteristicsOrder";
|
||||
import { api } from "../../../core/api/dynamic";
|
||||
import { useAwait } from "../../../hooks/useAwait";
|
||||
import { Tankopedia } from "../../../stores/tankopedia";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
export function Page({ id }: { id: string }) {
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<Content id={id} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
export function Page({ id }: Props) {
|
||||
const tank = use(api.tank(id));
|
||||
function Content({ id }: { id: string }) {
|
||||
const tank = useAwait(() => api.tank(id), `tank-${id}`);
|
||||
|
||||
const stage = Tankopedia.use((state) => state.stage);
|
||||
|
||||
const attributes = useMemo(() => {
|
||||
const attributes: Partial<
|
||||
Record<TankAttributeChange_AttributeName, number>
|
||||
> = {};
|
||||
|
||||
for (const { attribute_name, value, modifier } of tank.base_stats!
|
||||
.attributes) {
|
||||
if (modifier !== TankAttributeChange_Modifier.MODIFIER_OVERRIDE) {
|
||||
throw new Error(
|
||||
`Unexpected modifier ${TankAttributeChange_Modifier[modifier]}`
|
||||
);
|
||||
}
|
||||
|
||||
attributes[attribute_name] = value;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}, [stage]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>{tank.name?.value}</h1>
|
||||
|
||||
<h2>Base stats</h2>
|
||||
<h2>Characteristics</h2>
|
||||
|
||||
{tank.base_stats!.attributes.map((attribute) => (
|
||||
<p>
|
||||
{TankAttributeChange_AttributeName[attribute.attribute_name]}:{" "}
|
||||
{attribute.value} ({TankAttributeChange_Modifier[attribute.modifier]})
|
||||
</p>
|
||||
))}
|
||||
|
||||
<h2>Upgrades</h2>
|
||||
|
||||
{tank.upgrade_stages.map((stage, index) => (
|
||||
{characteristicsOrder.map((group) => (
|
||||
<>
|
||||
<h3>Stage {index}</h3>
|
||||
<h2>{CharacteristicsGroup[group.group]}</h2>
|
||||
|
||||
{stage.attributes.map((attribute) => (
|
||||
<p>
|
||||
{TankAttributeChange_AttributeName[attribute.attribute_name]}:{" "}
|
||||
{attribute.value} (
|
||||
{TankAttributeChange_Modifier[attribute.modifier]})
|
||||
</p>
|
||||
))}
|
||||
{group.attributes.map(
|
||||
(attribute) =>
|
||||
attribute.name in attributes && (
|
||||
<p>
|
||||
{TankAttributeChange_AttributeName[attribute.name]}:{" "}
|
||||
{attributes[attribute.name]}
|
||||
</p>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
|
||||
@@ -15,4 +15,4 @@ export const getStaticPaths = (async () => {
|
||||
const { id } = Astro.props;
|
||||
---
|
||||
|
||||
<Page {id} />
|
||||
<Page {id} client:load />
|
||||
Reference in new issue
Block a user