feat: faster tankopedia

This commit is contained in:
TrèsAbhi committed 2024-07-10 19:16:00 -05:00
1 parent 0a836826c2
commit d86af7e7ab
6 files changed
+35 -75

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
import { Flex, Spinner } from '@radix-ui/themes';
export function PageLoader() {
return (
<Flex align="center" justify="center" flexGrow="1">
<Spinner />
</Flex>
);
}
+2 -10
View File
@@ -7,11 +7,11 @@ import { Roboto_Flex } from 'next/font/google';
import { usePathname } from 'next/navigation';
import { ReactNode, Suspense } from 'react';
import { Footer } from '../components/Footer';
import { Loader } from '../components/Loader';
import Navbar, { NAVBAR_HEIGHT } from '../components/Navbar';
import { Party3 } from '../components/Party3';
import * as App from '../stores/app';
import { Checks } from './components/Checks';
import { PageLoader } from './components/PageLoader';
import './layout.css';
config();
@@ -75,15 +75,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
<Checks />
<Suspense
fallback={
<div style={{ flex: 1 }}>
<Loader />
</div>
}
>
{children}
</Suspense>
<Suspense fallback={<PageLoader />}>{children}</Suspense>
{!isEmbed && <Footer />}
</Flex>
+10 -2
View File
@@ -1,7 +1,9 @@
import { ReactNode } from 'react';
import { provisionDefinitions } from '../../../../core/blitzkit/provisionDefinitions';
import { tankDefinitions } from '../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../core/blitzkit/tankDefinitions/constants';
import { tankIcon } from '../../../../core/blitzkit/tankIcon';
import { useAwait } from '../../../../hooks/useAwait';
import strings from '../../../../lang/en-US.json';
import * as Duel from '../../../../stores/duel';
@@ -18,10 +20,16 @@ export default async function Layout({
const title = `${tank.name} - Tier ${TIER_ROMAN_NUMERALS[tank.tier]} ${
(strings.common.nations_adjectives as Record<string, string>)[tank.nation]
} ${strings.common.tank_class_short[tank.class]}`;
const description = `Statistics, armor profiles, and equipment for ${tank.name}`;
const description = `Statistics, armor, and equipment for ${tank.name}`;
const awaitedProvisionDefinitions = useAwait(provisionDefinitions);
return (
<Duel.Provider data={id}>
<Duel.Provider
data={{
tank: awaitedTankDefinitions[id],
provisionDefinitions: awaitedProvisionDefinitions,
}}
>
<title>{title}</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
-41
View File
@@ -1,41 +0,0 @@
import { blackA } from '@radix-ui/colors';
import { Flex, Spinner, Text } from '@radix-ui/themes';
import { theme } from '../stitches.config';
const NAV_HEIGHT = 52.65;
interface LoaderProps {
naked?: boolean;
progress?: number;
}
export function Loader({ naked, progress }: LoaderProps) {
const animation = (
<Flex align="center" gap="2">
<Spinner />
{progress !== undefined && (
<Text color="gray">{Math.round(progress * 100)}%</Text>
)}
</Flex>
);
if (naked) return animation;
return (
<Flex
style={{
backgroundColor: blackA.blackA10,
position: 'fixed',
top: NAV_HEIGHT,
left: 0,
width: '100%',
height: `calc(100% - ${NAV_HEIGHT}px)`,
padding: theme.spaces.paddingMajor,
}}
align="center"
justify="center"
>
{animation}
</Flex>
);
}
+5 -15
View File
@@ -1,12 +1,5 @@
import { Draft, produce } from 'immer';
import {
createContext,
ReactNode,
useContext,
useMemo,
use as useReact,
useRef,
} from 'react';
import { createContext, ReactNode, useContext, useRef } from 'react';
import { StoreApi, useStore as useStoreZustand } from 'zustand';
type StoreProviderProps<InitData> = {
@@ -21,7 +14,7 @@ type ExtractState<S> = S extends {
: never;
export function createNextSafeStore<Store extends StoreApi<unknown>, InitData>(
initialize: (data: InitData) => Store | Promise<Store>,
initialize: (data: InitData) => Store,
) {
type Type = Store extends StoreApi<infer T> ? T : never;
@@ -29,12 +22,9 @@ export function createNextSafeStore<Store extends StoreApi<unknown>, InitData>(
function Provider(props: StoreProviderProps<InitData>) {
const storeRef = useRef<Store>();
const storePromise = useMemo(
async () => await initialize((props as { data: InitData }).data),
[],
);
const awaitedStore = useReact(storePromise);
if (!storeRef.current) storeRef.current = awaitedStore;
if (!storeRef.current) {
storeRef.current = initialize((props as { data: InitData }).data);
}
return (
<Context.Provider value={storeRef.current}>
+9 -7
View File
@@ -2,13 +2,12 @@
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
import { provisionDefinitions } from '../../core/blitzkit/provisionDefinitions';
import { ProvisionDefinitions } from '../../core/blitzkit/provisionDefinitions';
import {
EngineDefinition,
GunDefinition,
ShellDefinition,
TankDefinition,
tankDefinitions,
TrackDefinition,
TurretDefinition,
} from '../../core/blitzkit/tankDefinitions';
@@ -50,11 +49,14 @@ export interface Duel {
}
export const { Provider, use, useMutation, useStore } = createNextSafeStore(
async (id: number) => {
const awaitedTankDefinitions = await tankDefinitions;
const awaitedProvisionDefinitions = await provisionDefinitions;
const tank = awaitedTankDefinitions[id];
const protagonist = tankToDuelMember(tank, awaitedProvisionDefinitions);
({
tank,
provisionDefinitions,
}: {
tank: TankDefinition;
provisionDefinitions: ProvisionDefinitions;
}) => {
const protagonist = tankToDuelMember(tank, provisionDefinitions);
return create<Duel>()(
subscribeWithSelector<Duel>(() => ({