From 2cfc65a9900f8907ff64e687c0a6028142223f89 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Fri, 16 May 2025 22:11:01 -0500 Subject: [PATCH] feat: migrate tanks --- packages/i18n/strings/en.json | 5 +- .../scripts/src/buildAssets/definitions.ts | 8 +- .../tools/{tankopedia.webp => tanks.webp} | Bin .../src/components/LegacyRedirect.astro | 19 --- packages/website/src/constants/tools.ts | 3 +- packages/website/src/layouts/BaseLayout.astro | 2 + .../website/src/layouts/LegacyRedirect.astro | 45 +++++++ packages/website/src/pages/404.astro | 30 +++-- .../[id] => tanks/[slug]}/_index.tsx | 34 +++--- .../[...locale]/tanks/[slug]/index.astro | 114 ++++++++++++++++++ .../[...locale]/tools/compare/index.astro | 2 +- .../tools/embed/[embed]/index.astro | 2 +- .../pages/[...locale]/tools/embed/index.astro | 2 +- .../[...locale]/tools/gallery/index.astro | 2 +- .../[...locale]/tools/performance/index.astro | 2 +- .../[...locale]/tools/session/index.astro | 2 +- .../tools/tankopedia/[id]/index.astro | 95 +-------------- .../[...locale]/tools/tankopedia/index.astro | 2 +- .../[...locale]/tools/tier-list/index.astro | 2 +- 19 files changed, 216 insertions(+), 155 deletions(-) rename packages/website/public/assets/images/tools/{tankopedia.webp => tanks.webp} (100%) delete mode 100644 packages/website/src/components/LegacyRedirect.astro create mode 100644 packages/website/src/layouts/LegacyRedirect.astro rename packages/website/src/pages/[...locale]/{tools/tankopedia/[id] => tanks/[slug]}/_index.tsx (52%) create mode 100644 packages/website/src/pages/[...locale]/tanks/[slug]/index.astro diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json index f902cddbd..caa25ce0f 100644 --- a/packages/i18n/strings/en.json +++ b/packages/i18n/strings/en.json @@ -741,7 +741,10 @@ }, "website": { - "redirect": "Redirecting to %s1... Didn't happen automatically? Click here.", + "redirect": { + "title": "301: moved permanently", + "body": "This page has moved. Redirecting..." + }, "settings": { "dev_mode": "Development mode", diff --git a/packages/scripts/src/buildAssets/definitions.ts b/packages/scripts/src/buildAssets/definitions.ts index 0c5fe74a6..f794d50cf 100644 --- a/packages/scripts/src/buildAssets/definitions.ts +++ b/packages/scripts/src/buildAssets/definitions.ts @@ -892,7 +892,13 @@ export async function definitions() { const hullArmor: Armor = { spaced: [], thickness: {} }; const equipment = tankDefinition.root.optDevicePreset; tankStringIdMap[`${nation}:${tankKey}`] = tankId; - const slug = slugs.get(tank.id)!; + const slug = slugs.get(tankId); + + if (slug === undefined) { + throw new Error( + `Could not find slug for ${nation}/${tankKey} (${tankId})`, + ); + } if (tank.sellPrice) { tankPrice = { diff --git a/packages/website/public/assets/images/tools/tankopedia.webp b/packages/website/public/assets/images/tools/tanks.webp similarity index 100% rename from packages/website/public/assets/images/tools/tankopedia.webp rename to packages/website/public/assets/images/tools/tanks.webp diff --git a/packages/website/src/components/LegacyRedirect.astro b/packages/website/src/components/LegacyRedirect.astro deleted file mode 100644 index 54fd64165..000000000 --- a/packages/website/src/components/LegacyRedirect.astro +++ /dev/null @@ -1,19 +0,0 @@ ---- -import { literals } from '@blitzkit/i18n'; -import { getStrings } from '../core/i18n/getStrings'; - -export interface Props { - path: string; -} - -const { path } = Astro.props; -const { locale } = Astro.params; - -const strings = getStrings(locale); -const url = `/${locale === undefined ? '' : `${locale}/`}${path}`; ---- - - - - {literals(strings.website.redirect, [url])} - diff --git a/packages/website/src/constants/tools.ts b/packages/website/src/constants/tools.ts index 395fe9604..b7b548ae0 100644 --- a/packages/website/src/constants/tools.ts +++ b/packages/website/src/constants/tools.ts @@ -15,7 +15,8 @@ export interface Tool { } export const tankopediaTool: Tool = { - id: 'tankopedia', + id: 'tanks', + stringsId: 'tankopedia', button: { color: 'purple', }, diff --git a/packages/website/src/layouts/BaseLayout.astro b/packages/website/src/layouts/BaseLayout.astro index b7cabe664..78e278099 100644 --- a/packages/website/src/layouts/BaseLayout.astro +++ b/packages/website/src/layouts/BaseLayout.astro @@ -54,6 +54,8 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE; : `/${bestLocale}${window.location.pathname}`; } + + diff --git a/packages/website/src/layouts/LegacyRedirect.astro b/packages/website/src/layouts/LegacyRedirect.astro new file mode 100644 index 000000000..b2137be42 --- /dev/null +++ b/packages/website/src/layouts/LegacyRedirect.astro @@ -0,0 +1,45 @@ +--- +import { DiscordLogoIcon, PaperPlaneIcon } from '@radix-ui/react-icons'; +import { Button, Flex, Heading, Link, Text } from '@radix-ui/themes'; +import { PageWrapper } from '../components/PageWrapper'; +import { getStrings } from '../core/i18n/getStrings'; +import BaseLayout from '../layouts/BaseLayout.astro'; + +export interface Props { + path: string; +} + +const { path } = Astro.props; +const { locale } = Astro.params; + +const strings = getStrings(locale); +const resolvedPath = `/${locale === undefined ? '' : `${locale}/`}${path}`; +--- + + + + + + + {strings.website.redirect.title} + {strings.website.redirect.body} + + + + + + + + + + + + diff --git a/packages/website/src/pages/404.astro b/packages/website/src/pages/404.astro index 304a32bf7..4252fca60 100644 --- a/packages/website/src/pages/404.astro +++ b/packages/website/src/pages/404.astro @@ -9,23 +9,21 @@ const { locale } = Astro.params; --- - - - 404: page not found - Where would you like to go? + + 404: page not found + Where would you like to go? - - - - - - - - + + + + + + + diff --git a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx b/packages/website/src/pages/[...locale]/tanks/[slug]/_index.tsx similarity index 52% rename from packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx rename to packages/website/src/pages/[...locale]/tanks/[slug]/_index.tsx index 660b97de4..933d53c8d 100644 --- a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/_index.tsx +++ b/packages/website/src/pages/[...locale]/tanks/[slug]/_index.tsx @@ -1,24 +1,24 @@ import { TankType } from '@blitzkit/core'; -import { PageWrapper } from '../../../../../components/PageWrapper'; -import { CalloutsSection } from '../../../../../components/Tankopedia/CalloutsSection'; -import { CharacteristicsSection } from '../../../../../components/Tankopedia/CharacteristicsSection'; -import { GameModeSection } from '../../../../../components/Tankopedia/GameModeSection'; -import { HeroSection } from '../../../../../components/Tankopedia/HeroSection'; -import { MetaSection } from '../../../../../components/Tankopedia/MetaSection'; -import { TechTreeSection } from '../../../../../components/Tankopedia/TechTreeSection'; -import { VideoSection } from '../../../../../components/Tankopedia/VideoSection'; -import { awaitableModelDefinitions } from '../../../../../core/awaitables/modelDefinitions'; -import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions'; -import { awaitableTankDefinitions } from '../../../../../core/awaitables/tankDefinitions'; +import { PageWrapper } from '../../../../components/PageWrapper'; +import { CalloutsSection } from '../../../../components/Tankopedia/CalloutsSection'; +import { CharacteristicsSection } from '../../../../components/Tankopedia/CharacteristicsSection'; +import { GameModeSection } from '../../../../components/Tankopedia/GameModeSection'; +import { HeroSection } from '../../../../components/Tankopedia/HeroSection'; +import { MetaSection } from '../../../../components/Tankopedia/MetaSection'; +import { TechTreeSection } from '../../../../components/Tankopedia/TechTreeSection'; +import { VideoSection } from '../../../../components/Tankopedia/VideoSection'; +import { awaitableModelDefinitions } from '../../../../core/awaitables/modelDefinitions'; +import { awaitableProvisionDefinitions } from '../../../../core/awaitables/provisionDefinitions'; +import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions'; import { LocaleProvider, type LocaleAcceptorProps, -} from '../../../../../hooks/useLocale'; -import { App } from '../../../../../stores/app'; -import { Duel } from '../../../../../stores/duel'; -import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral'; -import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent'; -import type { MaybeSkeletonComponentProps } from '../../../../../types/maybeSkeletonComponentProps'; +} from '../../../../hooks/useLocale'; +import { App } from '../../../../stores/app'; +import { Duel } from '../../../../stores/duel'; +import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral'; +import { TankopediaPersistent } from '../../../../stores/tankopediaPersistent'; +import type { MaybeSkeletonComponentProps } from '../../../../types/maybeSkeletonComponentProps'; type PageProps = MaybeSkeletonComponentProps & LocaleAcceptorProps & { diff --git a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro new file mode 100644 index 000000000..11f8567f1 --- /dev/null +++ b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro @@ -0,0 +1,114 @@ +--- +import { AstroSeo } from '@astrolib/seo'; +import { + asset, + createDefaultProvisions, + createDefaultSkills, + fetchEquipmentDefinitions, + fetchModelDefinitions, + fetchProvisionDefinitions, + fetchSkillDefinitions, + fetchTankDefinitions, + TIER_ROMAN_NUMERALS, +} from '@blitzkit/core'; +import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n'; +import { literals } from '@blitzkit/i18n/src/literals'; +import type { GetStaticPaths } from 'astro'; +import { tankCharacteristics } from '../../../../core/blitzkit/tankCharacteristics'; +import { getStrings } from '../../../../core/i18n/getStrings'; +import BaseLayout from '../../../../layouts/BaseLayout.astro'; +import { genericDefaultEquipmentMatrix } from '../../../../stores/duel/constants'; +import { getStaticPaths as parentGetStaticPaths } from '../index.astro'; +import { Page } from './_index'; + +export const getStaticPaths = (async () => { + const tankDefinitions = await fetchTankDefinitions(); + const parentPaths = parentGetStaticPaths(); + + return Object.values(tankDefinitions.tanks) + .map((tank) => + parentPaths.map((parent) => ({ + params: { ...parent.params, slug: tank.slug }, + props: { id: tank.id }, + })), + ) + .flat(); +}) satisfies GetStaticPaths; + +const { id } = Astro.props; +const locale = Astro.params.locale ?? DEFAULT_LOCALE; +const strings = getStrings(locale); +const tankDefinitions = await fetchTankDefinitions(); +const skillDefinitions = await fetchSkillDefinitions(); +const provisionDefinitions = await fetchProvisionDefinitions(); +const equipmentDefinitions = await fetchEquipmentDefinitions(); +const tankModelDefinitions = await fetchModelDefinitions(); +const tank = tankDefinitions.tanks[id]; +const tankModelDefinition = tankModelDefinitions.models[tank.id]; +const unwrap = unwrapper(locale); +const title = literals(strings.website.tools.tankopedia.tank_seo_title, [ + unwrap(tank.name), + TIER_ROMAN_NUMERALS[tank.tier], + strings.common.nations_adjectives[ + tank.nation as keyof typeof strings.common.nations_adjectives + ], + strings.common.tank_class_short[tank.class], + 'BlitzKit', + strings.common.nations[tank.nation as keyof typeof strings.common.nations], +]); +const url = import.meta.env.SITE + Astro.url.pathname; +const icon = asset(`icons/tanks/big/${id}.webp`); +const turret = tank.turrets.at(-1)!; +const gun = turret.guns.at(-1)!; +const characteristics = tankCharacteristics( + { + tank, + applyDynamicArmor: false, + applyReactiveArmor: false, + applySpallLiner: false, + camouflage: true, + consumables: [], + crewSkills: createDefaultSkills(skillDefinitions), + engine: tank.engines.at(-1)!, + equipmentMatrix: genericDefaultEquipmentMatrix, + turret, + gun, + provisions: createDefaultProvisions(tank, gun, provisionDefinitions), + shell: gun.gun_type!.value.base.shells[0], + stockEngine: tank.engines[0], + stockGun: tank.turrets[0].guns[0], + stockTurret: tank.turrets[0], + stockTrack: tank.tracks[0], + track: tank.tracks.at(-1)!, + }, + { equipmentDefinitions, provisionDefinitions, tankModelDefinition }, +); +const description = literals( + strings.website.tools.tankopedia.tank_seo_description, + [ + unwrap(tank.name), + Math.round(characteristics.dpm).toLocaleString(locale), + Math.round(characteristics.damage).toLocaleString(locale), + Math.round(characteristics.penetration).toLocaleString(locale), + Math.round(characteristics.speedForwards).toLocaleString(locale), + Math.round(characteristics.health).toLocaleString(locale), + ], +); +--- + + + + + + + + + + + + + diff --git a/packages/website/src/pages/[...locale]/tools/compare/index.astro b/packages/website/src/pages/[...locale]/tools/compare/index.astro index c2d4c623f..79bd4bf49 100644 --- a/packages/website/src/pages/[...locale]/tools/compare/index.astro +++ b/packages/website/src/pages/[...locale]/tools/compare/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/embed/[embed]/index.astro b/packages/website/src/pages/[...locale]/tools/embed/[embed]/index.astro index 887b2bdb1..607f5651f 100644 --- a/packages/website/src/pages/[...locale]/tools/embed/[embed]/index.astro +++ b/packages/website/src/pages/[...locale]/tools/embed/[embed]/index.astro @@ -1,7 +1,7 @@ --- import type { GetStaticPaths } from 'astro'; -import LegacyRedirect from '../../../../../components/LegacyRedirect.astro'; import { embedConfigurations } from '../../../../../constants/embeds'; +import LegacyRedirect from '../../../../../layouts/LegacyRedirect.astro'; import { getStaticPaths as parentGetStaticPaths } from '../index.astro'; export const getStaticPaths = (() => { diff --git a/packages/website/src/pages/[...locale]/tools/embed/index.astro b/packages/website/src/pages/[...locale]/tools/embed/index.astro index f249f55c3..ebbc3a0d9 100644 --- a/packages/website/src/pages/[...locale]/tools/embed/index.astro +++ b/packages/website/src/pages/[...locale]/tools/embed/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/gallery/index.astro b/packages/website/src/pages/[...locale]/tools/gallery/index.astro index 9638626f5..1d94adf84 100644 --- a/packages/website/src/pages/[...locale]/tools/gallery/index.astro +++ b/packages/website/src/pages/[...locale]/tools/gallery/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/performance/index.astro b/packages/website/src/pages/[...locale]/tools/performance/index.astro index 39880ab6d..739130147 100644 --- a/packages/website/src/pages/[...locale]/tools/performance/index.astro +++ b/packages/website/src/pages/[...locale]/tools/performance/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/session/index.astro b/packages/website/src/pages/[...locale]/tools/session/index.astro index 5d3a3e22a..a45bf8368 100644 --- a/packages/website/src/pages/[...locale]/tools/session/index.astro +++ b/packages/website/src/pages/[...locale]/tools/session/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/index.astro b/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/index.astro index 5b17aaa8c..c5b181e2f 100644 --- a/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/index.astro +++ b/packages/website/src/pages/[...locale]/tools/tankopedia/[id]/index.astro @@ -1,25 +1,8 @@ --- -import { AstroSeo } from '@astrolib/seo'; -import { - asset, - createDefaultProvisions, - createDefaultSkills, - fetchEquipmentDefinitions, - fetchModelDefinitions, - fetchProvisionDefinitions, - fetchSkillDefinitions, - fetchTankDefinitions, - TIER_ROMAN_NUMERALS, -} from '@blitzkit/core'; -import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n'; -import { literals } from '@blitzkit/i18n/src/literals'; +import { fetchTankDefinitions } from '@blitzkit/core'; import type { GetStaticPaths } from 'astro'; -import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics'; -import { getStrings } from '../../../../../core/i18n/getStrings'; -import BaseLayout from '../../../../../layouts/BaseLayout.astro'; -import { genericDefaultEquipmentMatrix } from '../../../../../stores/duel/constants'; +import LegacyRedirect from '../../../../../layouts/LegacyRedirect.astro'; import { getStaticPaths as parentGetStaticPaths } from '../index.astro'; -import { Page } from './_index'; export const getStaticPaths = (async () => { const tankDefinitions = await fetchTankDefinitions(); @@ -35,80 +18,8 @@ export const getStaticPaths = (async () => { }) satisfies GetStaticPaths; const { id } = Astro.params; -const locale = Astro.params.locale ?? DEFAULT_LOCALE; -const strings = getStrings(locale); const tankDefinitions = await fetchTankDefinitions(); -const skillDefinitions = await fetchSkillDefinitions(); -const provisionDefinitions = await fetchProvisionDefinitions(); -const equipmentDefinitions = await fetchEquipmentDefinitions(); -const tankModelDefinitions = await fetchModelDefinitions(); const tank = tankDefinitions.tanks[id]; -const tankModelDefinition = tankModelDefinitions.models[tank.id]; -const name = tank.name_full ?? tank.name; -const unwrap = unwrapper(locale); -const title = literals(strings.website.tools.tankopedia.tank_seo_title, [ - unwrap(name), - TIER_ROMAN_NUMERALS[tank.tier], - strings.common.nations_adjectives[ - tank.nation as keyof typeof strings.common.nations_adjectives - ], - strings.common.tank_class_short[tank.class], - 'BlitzKit', - strings.common.nations[tank.nation as keyof typeof strings.common.nations], -]); -const url = import.meta.env.SITE + Astro.url.pathname; -const icon = asset(`icons/tanks/big/${id}.webp`); -const turret = tank.turrets.at(-1)!; -const gun = turret.guns.at(-1)!; -const characteristics = tankCharacteristics( - { - tank, - applyDynamicArmor: false, - applyReactiveArmor: false, - applySpallLiner: false, - camouflage: true, - consumables: [], - crewSkills: createDefaultSkills(skillDefinitions), - engine: tank.engines.at(-1)!, - equipmentMatrix: genericDefaultEquipmentMatrix, - turret, - gun, - provisions: createDefaultProvisions(tank, gun, provisionDefinitions), - shell: gun.gun_type!.value.base.shells[0], - stockEngine: tank.engines[0], - stockGun: tank.turrets[0].guns[0], - stockTurret: tank.turrets[0], - stockTrack: tank.tracks[0], - track: tank.tracks.at(-1)!, - }, - { equipmentDefinitions, provisionDefinitions, tankModelDefinition }, -); -const description = literals( - strings.website.tools.tankopedia.tank_seo_description, - [ - unwrap(name), - Math.round(characteristics.dpm).toLocaleString(locale), - Math.round(characteristics.damage).toLocaleString(locale), - Math.round(characteristics.penetration).toLocaleString(locale), - Math.round(characteristics.speedForwards).toLocaleString(locale), - Math.round(characteristics.health).toLocaleString(locale), - ], -); --- - - - - - - - - - - - - + diff --git a/packages/website/src/pages/[...locale]/tools/tankopedia/index.astro b/packages/website/src/pages/[...locale]/tools/tankopedia/index.astro index 9c50a9722..e26a09adf 100644 --- a/packages/website/src/pages/[...locale]/tools/tankopedia/index.astro +++ b/packages/website/src/pages/[...locale]/tools/tankopedia/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; --- diff --git a/packages/website/src/pages/[...locale]/tools/tier-list/index.astro b/packages/website/src/pages/[...locale]/tools/tier-list/index.astro index 22a2f78bd..3ec94e268 100644 --- a/packages/website/src/pages/[...locale]/tools/tier-list/index.astro +++ b/packages/website/src/pages/[...locale]/tools/tier-list/index.astro @@ -1,5 +1,5 @@ --- -import LegacyRedirect from '../../../../components/LegacyRedirect.astro'; +import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro'; export { getStaticPaths } from '../../index.astro'; ---