From 3d69d464f5825b7bfd9d9fd614c1a94d216f5ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 1 Oct 2025 22:41:23 -0500 Subject: [PATCH] feat: start on amending slugs --- .vscode/settings.json | 1 + packages/bot/src/commands/auction.ts | 144 ------------------ packages/bot/src/commands/inactive.tsx | 56 +++---- packages/i18n/src/literals.ts | 13 +- .../[...locale]/tanks/[slug]/index.astro | 1 - 5 files changed, 38 insertions(+), 177 deletions(-) delete mode 100644 packages/bot/src/commands/auction.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 0cf60033b..b23034e77 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -86,6 +86,7 @@ "Fullscreen", "fullstats", "fuzzysort", + "gamemode", "gameplay", "glsl", "GLTF", diff --git a/packages/bot/src/commands/auction.ts b/packages/bot/src/commands/auction.ts deleted file mode 100644 index 5c5e06ba5..000000000 --- a/packages/bot/src/commands/auction.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { - BlitzTankClass, - Region, - regionToRegionSubdomain, -} from '@blitzkit/core'; -import { literals } from '@blitzkit/i18n'; -import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises'; -import { chunkLines } from '../core/discord/chunkLines'; -import { createLocalizedCommand } from '../core/discord/createLocalizedCommand'; -import { translator } from '../core/localization/translator'; -import { CommandRegistry } from '../events/interactionCreate'; - -type Auction = null | { - count: number; - has_next: boolean; - results: Result[]; -}; - -type Result = - | { - id?: number; - type: 'vehicle'; - countable?: boolean; - entity?: Entity; - initial_count: number; - current_count: number; - saleable?: boolean; - available_from?: Date; - available_before?: Date; - price?: Price; - next_price: Price | null; - available: true; - display?: boolean; - next_price_datetime: Date; - next_price_timestamp: number; - } - | { - available: false; - type: 'vehicle'; - }; - -interface Entity { - id: number; - name: string; - nation: string; - subnation: string; - use_subnation_flag: boolean; - type_slug: BlitzTankClass; - level: number; - roman_level: string; - user_string: string; - image_url: string; - preview_image_url: string; - is_premium: boolean; - is_collectible: boolean; -} - -interface Price { - currency: Currency; - value: number; -} - -interface Currency { - name: 'gold'; - count: number; - title: 'Gold'; - image_url: string; - sizes: unknown; - type: 'currency'; -} - -const WARNING_COUNT = 500; - -export const auctionCommand = new Promise((resolve) => { - resolve({ - command: createLocalizedCommand('auction'), - - async handler(interaction) { - const { strings } = translator(interaction.locale); - const awaitedTankDefinitions = await tankDefinitions; - const region: Region = 'com'; - const pageSize = 80; - const saleable = true; - const data = await fetch( - `https://${regionToRegionSubdomain( - region, - )}.wotblitz.com/en/api/events/items/auction/?page_size=${ - pageSize - }&type[]=vehicle&saleable=${saleable}`, - ).then((response) => response.json() as Promise); - - if (data === null) { - return strings.bot.commands.auction.errors.no_auction; - } - - const saleableTanks = data.results.filter((result) => result.available); - const nextPricesTimestamp = saleableTanks[0].next_price_timestamp; - - const title = `# ${strings.bot.commands.auction.body.title}`; - const subtitle = `${literals(strings.bot.commands.auction.body.subtitle, [ - `${saleableTanks.length} / ${data.results.length}`, - ``, - '', - ])}`; - const body = saleableTanks.map((data, index) => { - const tank = awaitedTankDefinitions.tanks[data.entity!.id]; - - if (!tank) return ''; - - const name = `[${tank.name}]()`; - const next = - data.next_price === null - ? '' - : `\n-# ${literals(strings.bot.commands.auction.body.next, [ - `<:gold:1317173197082333244> ${data.next_price.value.toLocaleString( - interaction.locale, - )}`, - ])}`; - const available = literals( - strings.bot.commands.auction.body.available, - [ - data.current_count.toLocaleString(interaction.locale), - data.initial_count.toLocaleString(interaction.locale), - ], - ); - const isOut = data.current_count === 0; - const outString = isOut ? '~~' : ''; - const isLow = data.current_count <= WARNING_COUNT; - - return `${index + 1}. ${ - outString - }${name} <:gold:1317173197082333244> ${data.price!.value.toLocaleString( - interaction.locale, - )}${outString}\n-#${isLow ? ' ‼️ ' : ' '}${available}${isOut ? '' : next}`; - }); - const header = `${title}\n${subtitle}`; - const lines = [header, ...body]; - - return chunkLines(lines, '\n\n'); - }, - }); -}); diff --git a/packages/bot/src/commands/inactive.tsx b/packages/bot/src/commands/inactive.tsx index ad3f49415..0493af830 100644 --- a/packages/bot/src/commands/inactive.tsx +++ b/packages/bot/src/commands/inactive.tsx @@ -1,44 +1,44 @@ -import { getAccountInfo, getClanInfo } from '@blitzkit/core'; -import { literals } from '@blitzkit/i18n'; -import { Locale } from 'discord.js'; -import { CommandWrapper } from '../components/CommandWrapper'; -import { GenericStats } from '../components/GenericStats'; -import { NoData } from '../components/NoData'; -import { TitleBar } from '../components/TitleBar'; -import { addClanChoices } from '../core/discord/addClanChoices'; -import { autocompleteClan } from '../core/discord/autocompleteClan'; -import { createLocalizedCommand } from '../core/discord/createLocalizedCommand'; -import { localizationObject } from '../core/discord/localizationObject'; -import { resolveClanFromCommand } from '../core/discord/resolveClanFromCommand'; -import { translator } from '../core/localization/translator'; -import { CommandRegistry } from '../events/interactionCreate'; +import { getAccountInfo, getClanInfo } from "@blitzkit/core"; +import { literals } from "@blitzkit/i18n"; +import { Locale } from "discord.js"; +import { CommandWrapper } from "../components/CommandWrapper"; +import { GenericStats } from "../components/GenericStats"; +import { NoData } from "../components/NoData"; +import { TitleBar } from "../components/TitleBar"; +import { addClanChoices } from "../core/discord/addClanChoices"; +import { autocompleteClan } from "../core/discord/autocompleteClan"; +import { createLocalizedCommand } from "../core/discord/createLocalizedCommand"; +import { localizationObject } from "../core/discord/localizationObject"; +import { resolveClanFromCommand } from "../core/discord/resolveClanFromCommand"; +import { translator } from "../core/localization/translator"; +import { CommandRegistry } from "../events/interactionCreate"; const DEFAULT_THRESHOLD = 7; export const inactiveCommand = new Promise((resolve) => { resolve({ - command: createLocalizedCommand('inactive') + command: createLocalizedCommand("inactive") .addStringOption(addClanChoices) .addNumberOption((option) => { const { strings } = translator(Locale.EnglishUS); return option - .setName('threshold') + .setName("threshold") .setNameLocalizations( localizationObject( (strings) => strings.bot.commands.inactive.options.threshold.name, undefined, - true, - ), + true + ) ) .setDescription( - strings.bot.commands.inactive.options.threshold.description, + strings.bot.commands.inactive.options.threshold.description ) .setDescriptionLocalizations( localizationObject( (strings) => - strings.bot.commands.inactive.options.threshold.description, - ), + strings.bot.commands.inactive.options.threshold.description + ) ) .setMinValue(0); }), @@ -47,7 +47,7 @@ export const inactiveCommand = new Promise((resolve) => { const { strings } = translator(interaction.locale); const { region, id } = await resolveClanFromCommand(interaction); const threshold = - interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD; + interaction.options.getNumber("threshold")! ?? DEFAULT_THRESHOLD; const time = new Date().getTime() / 1000; const clanInfo = await getClanInfo(region, id); const accountInfo = await getAccountInfo(region, clanInfo.members_ids); @@ -57,7 +57,7 @@ export const inactiveCommand = new Promise((resolve) => { [ account.nickname, (time - account.last_battle_time) / 60 / 60 / 24, - ] as [string, number], + ] as [string, number] ) .filter(([, inactiveDays]) => inactiveDays >= threshold) .sort((a, b) => b[1] - a[1]) @@ -65,10 +65,10 @@ export const inactiveCommand = new Promise((resolve) => { ([name, days]) => [ name, - literals(strings.bot.commands.inactive.body.listing, [ - days.toFixed(0), - ]), - ] as [string, string], + literals(strings.bot.commands.inactive.body.listing, { + days: days.toFixed(0), + }), + ] as [string, string] ); const hasInactiveMembers = inactive.length > 0; @@ -79,7 +79,7 @@ export const inactiveCommand = new Promise((resolve) => { image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`} description={`${literals( strings.bot.commands.inactive.body.subtitle, - [`${threshold}`], + { days: threshold } )} • ${new Date().toLocaleDateString(interaction.locale)}`} /> diff --git a/packages/i18n/src/literals.ts b/packages/i18n/src/literals.ts index 357e350ac..a467675ce 100644 --- a/packages/i18n/src/literals.ts +++ b/packages/i18n/src/literals.ts @@ -1,5 +1,10 @@ -export function literals(string: string, literals: string[]) { - return literals.reduce((accumulator, literal, index) => { - return accumulator.replace(`%s${index + 1}`, literal); - }, string); +export function literals( + string: string, + literals?: Record +) { + for (const key in literals) { + string = string.replaceAll(`{${key}}`, `${literals[key]}`); + } + + return string; } diff --git a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro index c556079e9..96f299674 100644 --- a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro +++ b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro @@ -57,7 +57,6 @@ const title = literals(strings.website.tools.tankopedia.tank_seo_title, [ ], 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;