mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: faster tankopedia
This commit is contained in:
1 parent
0a836826c2
commit
d86af7e7ab
6 files changed
+35
-75
No files matched your search
@@ -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
@@ -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>
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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}>
|
||||
|
||||
@@ -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>(() => ({
|
||||
|
||||
Reference in new issue
Block a user