diff --git a/packages/bot/src/commands/breakdown/render.tsx b/packages/bot/src/commands/breakdown/render.tsx index 401c89aed..c62869b4e 100644 --- a/packages/bot/src/commands/breakdown/render.tsx +++ b/packages/bot/src/commands/breakdown/render.tsx @@ -7,6 +7,7 @@ import { getWN8Percentile, TankDefinition, } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { Locale } from 'discord.js'; import { chunk } from 'lodash-es'; import * as Breakdown from '../../components/Breakdown'; @@ -32,7 +33,7 @@ export async function renderBreakdown( filters: StatFilters, locale: Locale, ) { - const { t, translate, unwrap } = translator(locale); + const { strings, unwrap } = translator(locale); const awaitedTankDefinitions = await tankDefinitions; const awaitedTankAverages = await blitzStarsTankAverages; const statsInPeriod = await getStatsInPeriod(region, id, start, end, locale); @@ -48,7 +49,7 @@ export async function renderBreakdown( const orderedCareerWN8Full: (number | undefined)[] = []; if (tankStats === null) { - throw new UserError(t`bot.common.errors.no_tank_stats`); + throw new UserError(strings.bot.common.errors.no_tank_stats); } filteredOrder.forEach((id) => { @@ -136,21 +137,21 @@ export async function renderBreakdown( ((resolve) => { ), async handler(interaction) { - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const { id, region } = await resolvePlayerFromCommand(interaction); const discordId = BigInt(interaction.user.id); const accountInfo = await getAccountInfo(region, id); @@ -120,9 +120,9 @@ export const verifyCommand = new Promise((resolve) => { height: 16, }} /> - {t`bot.commands.link.body.accounts_linked`} + + {strings.bot.commands.link.body.accounts_linked} +
((resolve) => { {clanAccountInfo?.clan ? `[${clanAccountInfo?.clan?.tag}] • ` : ''} - {translate(`common.regions.normal.${region}`)} + {strings.common.regions.normal[region]}
@@ -185,8 +185,8 @@ export const verifyCommand = new Promise((resolve) => { , embedInfo( - t`bot.commands.link.embed.title`, - t`bot.commands.link.embed.description`, + strings.bot.commands.link.embed.title, + strings.bot.commands.link.embed.description, ), ]; }, diff --git a/packages/bot/src/commands/ownedTanks.tsx b/packages/bot/src/commands/ownedTanks.tsx index 18b79eb0a..af67a00ad 100644 --- a/packages/bot/src/commands/ownedTanks.tsx +++ b/packages/bot/src/commands/ownedTanks.tsx @@ -6,6 +6,7 @@ import { getAccountInfo, getTankStats, } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import markdownEscape from 'markdown-escape'; import { gameDefinitions, @@ -27,14 +28,14 @@ export const ownedTanksCommand = new Promise((resolve) => { .addStringOption(addUsernameChoices), async handler(interaction) { - const { t, translate, unwrap } = translator(interaction.locale); + const { strings, unwrap } = translator(interaction.locale); const tier = Number(interaction.options.getString('tier')); const { id, region } = await resolvePlayerFromCommand(interaction); const accountInfo = await getAccountInfo(region, id); const tankStats = await getTankStats(region, id); if (tankStats === null) { - return t`bot.common.errors.no_tank_stats`; + return strings.bot.common.errors.no_tank_stats; } const filteredTanks = ( @@ -59,7 +60,7 @@ export const ownedTanksCommand = new Promise((resolve) => { const awaitedTankDefinitions = await tankDefinitions; const awaitedGameDefinitions = await gameDefinitions; - const title = translate('bot.commands.owned_tanks.body.title', [ + const title = literals(strings.bot.commands.owned_tanks.body.title, [ markdownEscape(accountInfo.nickname), TIER_ROMAN_NUMERALS[tier], ]); diff --git a/packages/bot/src/commands/permissions.ts b/packages/bot/src/commands/permissions.ts index 9afd85be9..8dad1039a 100644 --- a/packages/bot/src/commands/permissions.ts +++ b/packages/bot/src/commands/permissions.ts @@ -1,3 +1,4 @@ +import { literals } from '@blitzkit/i18n'; import { createLocalizedCommand } from '../core/discord/createLocalizedCommand'; import { translator } from '../core/localization/translator'; import { CommandRegistry } from '../events/interactionCreate'; @@ -7,26 +8,26 @@ export const permissionsCommand = new Promise((resolve) => { command: createLocalizedCommand('permissions'), async handler(interaction) { - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); // friday the 13th permissions easter egg const isFridayThe13th = new Date().getDay() === 5 && new Date().getDate() === 13; const permissions = [ [ interaction.appPermissions?.has('ViewChannel'), - t`bot.commands.permissions.body.view_channels`, + strings.bot.commands.permissions.body.view_channels, ], [ interaction.appPermissions?.has('ReadMessageHistory'), - t`bot.commands.permissions.body.read_message_history`, + strings.bot.commands.permissions.body.read_message_history, ], [ interaction.appPermissions?.has('AttachFiles'), - t`bot.commands.permissions.body.attach_files`, + strings.bot.commands.permissions.body.attach_files, ], [ interaction.appPermissions?.has('UseExternalEmojis'), - t`bot.commands.permissions.body.external_emojis`, + strings.bot.commands.permissions.body.external_emojis, ], ]; const body = permissions @@ -39,7 +40,7 @@ export const permissionsCommand = new Promise((resolve) => { }) .join('\n'); - return translate('bot.commands.permissions.body.title', [body]); + return literals(strings.bot.commands.permissions.body.title, [body]); }, }); }); diff --git a/packages/bot/src/commands/ping.ts b/packages/bot/src/commands/ping.ts index 1823f3a33..fcf896313 100644 --- a/packages/bot/src/commands/ping.ts +++ b/packages/bot/src/commands/ping.ts @@ -1,3 +1,4 @@ +import { literals } from '@blitzkit/i18n'; import { createLocalizedCommand } from '../core/discord/createLocalizedCommand'; import { translator } from '../core/localization/translator'; import { CommandRegistry } from '../events/interactionCreate'; @@ -12,19 +13,19 @@ export const pingCommand = new Promise((resolve) => { ]), async handler(interaction) { - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const subcommand = interaction.options.getSubcommand(); const executionStart = Date.now(); if (subcommand === 'blitzkit') { - await interaction.editReply(t`bot.commands.ping.body.pong`); + await interaction.editReply(strings.bot.commands.ping.body.pong); } else { await fetch('https://api.wotblitz.com/'); } const executionTime = Date.now() - executionStart; interaction.editReply( - translate('bot.commands.ping.body.pong_with_time', [ + literals(strings.bot.commands.ping.body.pong_with_time, [ `${Math.round(executionTime)}`, ]), ); diff --git a/packages/bot/src/commands/playerInfo.ts b/packages/bot/src/commands/playerInfo.ts index cdb7d7d72..5d4be9776 100644 --- a/packages/bot/src/commands/playerInfo.ts +++ b/packages/bot/src/commands/playerInfo.ts @@ -1,4 +1,5 @@ import { getAccountInfo } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import markdownEscape from 'markdown-escape'; import { addUsernameChoices } from '../core/discord/addUsernameChoices'; import { autocompleteUsername } from '../core/discord/autocompleteUsername'; @@ -15,27 +16,27 @@ export const playerInfoCommand = new Promise((resolve) => { createLocalizedCommand('player-info').addStringOption(addUsernameChoices), async handler(interaction) { - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const account = await resolvePlayerFromCommand(interaction); const { id, region: region } = account; const accountInfo = await getAccountInfo(region, id); return embedInfo( - translate('bot.commands.player_info.body.title', [ + literals(strings.bot.commands.player_info.body.title, [ markdownEscape(accountInfo.nickname), ]), markdownTable([ [ - t`bot.commands.player_info.body.nickname`, + strings.bot.commands.player_info.body.nickname, `${accountInfo.nickname}`, ], [ - t`bot.commands.player_info.body.battles`, + strings.bot.commands.player_info.body.battles, `${accountInfo.statistics.all.battles}`, ], [ - t`bot.commands.player_info.body.winrate`, + strings.bot.commands.player_info.body.winrate, `${( 100 * (accountInfo.statistics.all.wins / @@ -44,17 +45,17 @@ export const playerInfoCommand = new Promise((resolve) => { ], [], [ - t`bot.commands.player_info.body.account_id`, + strings.bot.commands.player_info.body.account_id, `${accountInfo.account_id}`, ], [ - t`bot.commands.player_info.body.created`, + strings.bot.commands.player_info.body.created, new Date(accountInfo.created_at * 1000).toLocaleDateString( interaction.locale, ), ], [ - t`bot.commands.player_info.body.last_battle`, + strings.bot.commands.player_info.body.last_battle, new Date(accountInfo.last_battle_time * 1000).toLocaleDateString( interaction.locale, ), diff --git a/packages/bot/src/commands/rating.tsx b/packages/bot/src/commands/rating.tsx index 1188c3706..eb0a38613 100644 --- a/packages/bot/src/commands/rating.tsx +++ b/packages/bot/src/commands/rating.tsx @@ -9,6 +9,7 @@ import { getRatingNeighbors, imgur, } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { SlashCommandSubcommandBuilder } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow'; @@ -53,7 +54,7 @@ export const ratingCommand = new Promise((resolve) => { const subcommand = interaction.options.getSubcommand(true) as | 'season' | 'today'; - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const { id, region } = await resolvePlayerFromCommand(interaction); const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan; const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined; @@ -89,7 +90,7 @@ export const ratingCommand = new Promise((resolve) => { const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors; if (statsB2Array === undefined) { - return translate('bot.commands.rating.errors.no_participation', [ + return literals(strings.bot.commands.rating.errors.no_participation, [ markdownEscape(accountInfo.nickname), ]); } @@ -98,10 +99,10 @@ export const ratingCommand = new Promise((resolve) => { const league = getLeagueFromScore(statsB2.score); if (!statsA) { - return t`bot.commands.rating.errors.unrecorded_stats`; + return strings.bot.commands.rating.errors.unrecorded_stats; } if (!statsB1) { - return translate('bot.commands.rating.errors.no_participation', [ + return literals(strings.bot.commands.rating.errors.no_participation, [ markdownEscape(accountInfo.nickname), ]); } @@ -139,9 +140,9 @@ export const ratingCommand = new Promise((resolve) => {
( ); function addOptions(option: SlashCommandSubcommandBuilder) { - const { t, translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); return option .addIntegerOption((option) => option - .setName(t`bot.commands.rating_leaderboard.options.limit`) + .setName(strings.bot.commands.rating_leaderboard.options.limit.$) .setNameLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.limit', + (strings) => + strings.bot.commands.rating_leaderboard.options.limit.$, undefined, true, ), ) .setDescription( - translate( - 'bot.commands.rating_leaderboard.options.limit.description', + literals( + strings.bot.commands.rating_leaderboard.options.limit + .description, [`${DEFAULT_LIMIT}`], ), ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.limit.description', + (strings) => + strings.bot.commands.rating_leaderboard.options.limit + .description, [`${DEFAULT_LIMIT}`], ), ) @@ -85,22 +90,24 @@ export const ratingLeaderboardCommand = new Promise( ) .addStringOption((option) => option - .setName(t`bot.commands.rating_leaderboard.options.season`) + .setName(strings.bot.commands.rating_leaderboard.options.season.$) .setNameLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.season', + (strings) => + strings.bot.commands.rating_leaderboard.options.season.$, undefined, true, ), ) .setDescription( - translate( - 'bot.commands.rating_leaderboard.options.season.description', - ), + strings.bot.commands.rating_leaderboard.options.season + .description, ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.season.description', + (strings) => + strings.bot.commands.rating_leaderboard.options.season + .description, ), ) .setRequired(false) @@ -112,15 +119,18 @@ export const ratingLeaderboardCommand = new Promise( return { name: current - ? translate( - 'bot.commands.rating_leaderboard.options.season.choices.current', + ? literals( + strings.bot.commands.rating_leaderboard.options.season + .choices.current, [`${number}`], ) : `${number}`, value: `${number}`, name_localizations: current ? localizationObject( - 'bot.commands.rating_leaderboard.options.season.choices.current', + (strings) => + strings.bot.commands.rating_leaderboard.options + .season.choices.current, [`${number}`], ) : undefined, @@ -145,35 +155,45 @@ export const ratingLeaderboardCommand = new Promise( modify(option: SlashCommandSubcommandBuilder) { option .addStringOption((option) => { - const { t, translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); return option - .setName(t`bot.commands.rating_leaderboard.options.league`) + .setName( + strings.bot.commands.rating_leaderboard.options.league.$, + ) .setNameLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.league', + (strings) => + strings.bot.commands.rating_leaderboard.options.league + .$, undefined, true, ), ) .setDescription( - translate( - 'bot.commands.rating_leaderboard.options.league.description', - ), + strings.bot.commands.rating_leaderboard.options.league + .description, ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.rating_leaderboard.options.league.description', + (strings) => + strings.bot.commands.rating_leaderboard.options.league + .description, ), ) .addChoices( ...LEAGUES.map( ({ name }, value) => ({ - name: translate(`common.leagues.${name}`), + name: ( + strings.common.leagues as Record + )[name], value: `${value}`, name_localizations: localizationObject( - `common.leagues.${name}`, + (strings) => + ( + strings.common.leagues as Record + )[name], ), }) satisfies APIApplicationCommandOptionChoice, ), @@ -189,7 +209,7 @@ export const ratingLeaderboardCommand = new Promise( // BIG TODO: title seems to be in english async handler(interaction) { - const { t, translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const subcommand = interaction.options.getSubcommand(true) as | 'league' | 'neighbors'; @@ -223,7 +243,8 @@ export const ratingLeaderboardCommand = new Promise( regionRatingInfo !== null && regionRatingInfo.detail !== undefined ) { - return t`bot.commands.rating_leaderboard.body.no_ongoing_season`; + return strings.bot.commands.rating_leaderboard.body + .no_ongoing_season; } const result = isCurrentSeason @@ -268,8 +289,9 @@ export const ratingLeaderboardCommand = new Promise( clan: clanData[player.id]?.clan?.tag, nickname: clanData[index]?.account_name ?? - translate( - 'bot.commands.rating_leaderboard.body.deleted_player', + literals( + strings.bot.commands.rating_leaderboard.body + .deleted_player, [`${player.id}`], ), }) satisfies SimplifiedPlayer, @@ -289,12 +311,14 @@ export const ratingLeaderboardCommand = new Promise( : regionRatingInfo.count) - result[result.length - 1].position; titleName = `${ leagueInfo - ? translate(`common.leagues.${LEAGUES[leagueInfo.index].name}`) + ? (strings.common.leagues as Record)[ + LEAGUES[leagueInfo.index].name + ] : '' - } - ${translate(`common.regions.short.${region}`)}`; + } - ${strings.common.regions.short[region]}`; titleImage = imgur(leagueInfo.icon); - titleDescription = translate( - 'bot.commands.rating_leaderboard.body.top_players', + titleDescription = literals( + strings.bot.commands.rating_leaderboard.body.top_players, [`${limit}`], ); } else { @@ -307,7 +331,8 @@ export const ratingLeaderboardCommand = new Promise( regionRatingInfo !== null && regionRatingInfo.detail !== undefined ) { - return t`bot.commands.rating_leaderboard.body.no_ongoing_season`; + return strings.bot.commands.rating_leaderboard.body + .no_ongoing_season; } const accountInfo = await getAccountInfo(region, id); @@ -334,8 +359,9 @@ export const ratingLeaderboardCommand = new Promise( if (playerIndex === -1) { throw new UserError( - translate( - 'bot.commands.rating_leaderboard.body.no_participation', + literals( + strings.bot.commands.rating_leaderboard.body + .no_participation, [markdownEscape(accountInfo.nickname), `${season}`], ), ); @@ -373,7 +399,8 @@ export const ratingLeaderboardCommand = new Promise( ? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clan.emblem_set_id}.png` : undefined; titleName = neighbors ? accountInfo.nickname : ''; - titleDescription = t`bot.commands.rating_leaderboard.body.neighbors`; + titleDescription = + strings.bot.commands.rating_leaderboard.body.neighbors; playersAfter = (regionRatingInfo === null ? archivedLeaderboard.version!.value.entries.length @@ -422,8 +449,8 @@ export const ratingLeaderboardCommand = new Promise( {items} {playersAfter > 0 && ( diff --git a/packages/bot/src/commands/research.tsx b/packages/bot/src/commands/research.tsx index 4826ba516..2aa1c4663 100644 --- a/packages/bot/src/commands/research.tsx +++ b/packages/bot/src/commands/research.tsx @@ -9,6 +9,7 @@ import { TankType, TIER_ROMAN_NUMERALS, } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { escapeMarkdown, Locale } from 'discord.js'; import { CommandWrapper } from '../components/CommandWrapper'; import { TitleBar } from '../components/TitleBar'; @@ -28,26 +29,27 @@ import { CommandRegistry } from '../events/interactionCreate'; import { theme } from '../stitches.config'; export const researchCommand = new Promise((resolve) => { - const { t } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); resolve({ command: createLocalizedCommand('research') .addStringOption((option) => option - .setName(t`bot.commands.research.options.target_tank`) + .setName(strings.bot.commands.research.options.target_tank.$) .setNameLocalizations( localizationObject( - 'bot.commands.research.options.target_tank', + (strings) => strings.bot.commands.research.options.target_tank.$, undefined, true, ), ) .setDescription( - t`bot.commands.research.options.target_tank.description`, + strings.bot.commands.research.options.target_tank.description, ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.research.options.target_tank.description', + (strings) => + strings.bot.commands.research.options.target_tank.description, ), ) .setAutocomplete(true) @@ -55,20 +57,22 @@ export const researchCommand = new Promise((resolve) => { ) .addStringOption((option) => option - .setName(t`bot.commands.research.options.starting_tank`) + .setName(strings.bot.commands.research.options.starting_tank.$) .setNameLocalizations( localizationObject( - 'bot.commands.research.options.starting_tank', + (strings) => + strings.bot.commands.research.options.starting_tank.$, undefined, true, ), ) .setDescription( - t`bot.commands.research.options.starting_tank.description`, + strings.bot.commands.research.options.starting_tank.description, ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.research.options.starting_tank.description', + (strings) => + strings.bot.commands.research.options.starting_tank.description, ), ) .setAutocomplete(true) @@ -77,7 +81,7 @@ export const researchCommand = new Promise((resolve) => { .addStringOption(addUsernameChoices), async handler(interaction) { - const { t, translate, unwrap } = translator(interaction.locale); + const { strings, unwrap } = translator(interaction.locale); const awaitedTankDefinitions = await tankDefinitions; const targetTankId = await resolveTankId( interaction.options.getString('target-tank', true), @@ -98,15 +102,16 @@ export const researchCommand = new Promise((resolve) => { ); if (targetTankId === startingTankId) { - return translate('bot.commands.research.errors.start_end_equal', [ - escapeMarkdown(unwrap(targetTank.name)), - ]); + return literals( + strings.bot.commands.research.errors.start_end_equal, + [escapeMarkdown(unwrap(targetTank.name))], + ); } const startingTank = awaitedTankDefinitions.tanks[startingTankId]; if (startingTank.tier > targetTank.tier) { - return translate('bot.commands.research.errors.unordered', [ + return literals(strings.bot.commands.research.errors.unordered, [ escapeMarkdown(unwrap(startingTank.name)), escapeMarkdown(unwrap(targetTank.name)), escapeMarkdown(unwrap(targetTank.name)), @@ -114,20 +119,23 @@ export const researchCommand = new Promise((resolve) => { } if (!targetTankAncestry.includes(startingTankId)) { - return translate('bot.commands.research.errors.tanks_not_on_line', [ - escapeMarkdown(unwrap(targetTank.name)), - escapeMarkdown(unwrap(startingTank.name)), - ]); + return literals( + strings.bot.commands.research.errors.tanks_not_on_line, + [ + escapeMarkdown(unwrap(targetTank.name)), + escapeMarkdown(unwrap(startingTank.name)), + ], + ); } } else { if (targetTank.type !== TankType.RESEARCHABLE) { - return translate('bot.commands.research.errors.non_tech_tree', [ + return literals(strings.bot.commands.research.errors.non_tech_tree, [ escapeMarkdown(unwrap(targetTank.name)), ]); } if (targetTank.tier === 1) { - return translate('bot.commands.research.errors.tier_1', [ + return literals(strings.bot.commands.research.errors.tier_1, [ escapeMarkdown(unwrap(targetTank.name)), ]); } @@ -135,13 +143,14 @@ export const researchCommand = new Promise((resolve) => { const tankStats = await getTankStats(region, id); if (tankStats === null) { - return t`bot.common.errors.no_tank_stats`; + return strings.bot.common.errors.no_tank_stats; } if (tankStats.some(({ tank_id }) => tank_id === targetTankId)) { - return translate('bot.commands.research.errors.already_researched', [ - escapeMarkdown(unwrap(targetTank.name)), - ]); + return literals( + strings.bot.commands.research.errors.already_researched, + [escapeMarkdown(unwrap(targetTank.name))], + ); } const foundAncestor = targetTankAncestry.find( @@ -255,7 +264,7 @@ export const researchCommand = new Promise((resolve) => { @@ -292,7 +301,7 @@ export const researchCommand = new Promise((resolve) => { color: theme.colors.textHighContrast, }} > - {t`bot.commands.research.body.total`} + {strings.bot.commands.research.body.total}
@@ -497,11 +506,14 @@ export const researchCommand = new Promise((resolve) => { color: theme.colors.textHighContrast, }} > - {translate('bot.commands.research.body.research', [ - `${costs[index].research?.toLocaleString( - interaction.locale, - )}`, - ])} + {literals( + strings.bot.commands.research.body.research, + [ + `${costs[index].research?.toLocaleString( + interaction.locale, + )}`, + ], + )} @@ -527,9 +539,10 @@ export const researchCommand = new Promise((resolve) => { color: theme.colors.textHighContrast, }} > - {translate('bot.commands.research.body.upgrades', [ - costs[index].upgrades.toLocaleString(), - ])} + {literals( + strings.bot.commands.research.body.upgrades, + [costs[index].upgrades.toLocaleString()], + )} )} @@ -555,11 +568,14 @@ export const researchCommand = new Promise((resolve) => { color: theme.colors.textHighContrast, }} > - {translate('bot.commands.research.body.purchase', [ - costs[index].purchase.toLocaleString( - interaction.locale, - ), - ])} + {literals( + strings.bot.commands.research.body.purchase, + [ + costs[index].purchase.toLocaleString( + interaction.locale, + ), + ], + )} @@ -584,11 +600,14 @@ export const researchCommand = new Promise((resolve) => { color: theme.colors.textHighContrast, }} > - {translate('bot.commands.research.body.equipment', [ - costs[index].equipment.toLocaleString( - interaction.locale, - ), - ])} + {literals( + strings.bot.commands.research.body.equipment, + [ + costs[index].equipment.toLocaleString( + interaction.locale, + ), + ], + )} @@ -602,7 +621,7 @@ export const researchCommand = new Promise((resolve) => { return startingTankRaw ? image - : [t`bot.commands.research.body.estimation`, image]; + : [strings.bot.commands.research.body.estimation, image]; }, autocomplete(interaction) { diff --git a/packages/bot/src/commands/searchClans.ts b/packages/bot/src/commands/searchClans.ts index 03229ded0..f3a8502b7 100644 --- a/packages/bot/src/commands/searchClans.ts +++ b/packages/bot/src/commands/searchClans.ts @@ -1,4 +1,5 @@ import { ClanList, fetchBlitz, Region } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { Locale } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { addClanChoices } from '../core/discord/addClanChoices'; @@ -19,25 +20,27 @@ export const searchClansCommand = new Promise((resolve) => { addClanChoices(option).setAutocomplete(false), ) .addIntegerOption((option) => { - const { t, translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); return option - .setName(t`bot.commands.search_clans.options.limit`) + .setName(strings.bot.commands.search_clans.options.limit.$) .setNameLocalizations( localizationObject( - 'bot.commands.search_clans.options.limit', + (strings) => strings.bot.commands.search_clans.options.limit.$, undefined, true, ), ) .setDescription( - translate('bot.commands.search_clans.options.limit.description', [ - `${DEFAULT_LIMIT}`, - ]), + literals( + strings.bot.commands.search_clans.options.limit.description, + [`${DEFAULT_LIMIT}`], + ), ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.search_clans.options.limit.description', + (strings) => + strings.bot.commands.search_clans.options.limit.description, [`${DEFAULT_LIMIT}`], ), ) @@ -46,7 +49,7 @@ export const searchClansCommand = new Promise((resolve) => { }), async handler(interaction) { - const { translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const region = interaction.options.getString('region') as Region; const clan = interaction.options.getString('clan')!; const limit = interaction.options.getInteger('limit') ?? DEFAULT_LIMIT; @@ -56,12 +59,12 @@ export const searchClansCommand = new Promise((resolve) => { }); return embedInfo( - translate('bot.commands.search_clans.body.title', [ + literals(strings.bot.commands.search_clans.body.title, [ markdownEscape(clan), - translate(`common.regions.normal.${region}`), + strings.common.regions.normal[region], ]), clanList.length === 0 - ? translate('bot.commands.search_clans.body.no_results') + ? strings.bot.commands.search_clans.body.no_results : `\`\`\`\n${clanList .map((clan) => `${clan.name} [${clan.tag}]`) .join('\n')}\n\`\`\``, diff --git a/packages/bot/src/commands/searchPlayers.ts b/packages/bot/src/commands/searchPlayers.ts index 4efa80c3c..636ea636f 100644 --- a/packages/bot/src/commands/searchPlayers.ts +++ b/packages/bot/src/commands/searchPlayers.ts @@ -4,6 +4,7 @@ import { Region, usernamePattern, } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { Locale } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { addRegionChoices } from '../core/discord/addRegionChoices'; @@ -17,7 +18,7 @@ import { CommandRegistry } from '../events/interactionCreate'; const DEFAULT_LIMIT = 25; export const searchPlayersCommand = new Promise((resolve) => { - const { t, translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); resolve({ command: createLocalizedCommand('search-players') @@ -27,22 +28,24 @@ export const searchPlayersCommand = new Promise((resolve) => { ) .addIntegerOption((option) => option - .setName(t`bot.commands.search_players.options.limit`) + .setName(strings.bot.commands.search_players.options.limit.$) .setNameLocalizations( localizationObject( - 'bot.commands.search_players.options.limit', + (strings) => strings.bot.commands.search_players.options.limit.$, undefined, true, ), ) .setDescription( - translate('bot.commands.search_players.options.limit.description', [ - `${DEFAULT_LIMIT}`, - ]), + literals( + strings.bot.commands.search_players.options.limit.description, + [`${DEFAULT_LIMIT}`], + ), ) .setDescriptionLocalizations( localizationObject( - 'bot.commands.search_players.options.limit.description', + (strings) => + strings.bot.commands.search_players.options.limit.description, [`${DEFAULT_LIMIT}`], ), ) @@ -51,7 +54,7 @@ export const searchPlayersCommand = new Promise((resolve) => { ), async handler(interaction) { - const { translate } = translator(interaction.locale); + const { strings } = translator(interaction.locale); const region = interaction.options.getString('region') as Region; const name = interaction.options.getString('username')!; const limit = interaction.options.getInteger('limit') ?? 25; @@ -64,13 +67,13 @@ export const searchPlayersCommand = new Promise((resolve) => { : []; return embedInfo( - translate('bot.commands.search_players.body.title', [ + literals(strings.bot.commands.search_players.body.title, [ markdownEscape(trimmedSearch), - translate(`common.regions.normal.${region}`), + strings.common.regions.normal[region], ]), `\`\`\`${ players.length === 0 - ? translate('bot.commands.search_players.body.no_results') + ? strings.bot.commands.search_players.body.no_results : players.map((player) => player.nickname).join('\n') }\`\`\``, ); diff --git a/packages/bot/src/components/AllStatsOverview/index.tsx b/packages/bot/src/components/AllStatsOverview/index.tsx index c7eccb958..6783c4b5e 100644 --- a/packages/bot/src/components/AllStatsOverview/index.tsx +++ b/packages/bot/src/components/AllStatsOverview/index.tsx @@ -32,7 +32,7 @@ export function AllStatsOverview({ locale, supplementaryStats, }: AllStatsOverviewProps) { - const { t, translate } = translator(locale); + const { strings } = translator(locale); const percentile = typeof supplementaryStats.WN8 === 'number' ? getWN8Percentile(supplementaryStats.WN8) @@ -63,18 +63,18 @@ export function AllStatsOverview({ }} > @@ -90,7 +90,7 @@ export function AllStatsOverview({ @@ -103,25 +103,25 @@ export function AllStatsOverview({ }} > diff --git a/packages/bot/src/components/NoData/index.tsx b/packages/bot/src/components/NoData/index.tsx index cf2d46004..7fa7227aa 100644 --- a/packages/bot/src/components/NoData/index.tsx +++ b/packages/bot/src/components/NoData/index.tsx @@ -12,7 +12,7 @@ interface NoDataProps { } export function NoData({ type, locale }: NoDataProps) { - const { translate } = translator(locale); + const { strings } = translator(locale); return (
- {translate(`bot.common.no_data.${type}`)} + {strings.bot.common.no_data[type]}
); diff --git a/packages/bot/src/core/blitz/resolveTankId.ts b/packages/bot/src/core/blitz/resolveTankId.ts index 01d2034be..55ba19c17 100644 --- a/packages/bot/src/core/blitz/resolveTankId.ts +++ b/packages/bot/src/core/blitz/resolveTankId.ts @@ -1,3 +1,4 @@ +import { literals } from '@blitzkit/i18n'; import { Locale } from 'discord.js'; import { go } from 'fuzzysort'; import markdownEscape from 'markdown-escape'; @@ -11,7 +12,7 @@ export async function resolveTankId( locale: Locale, techTreeOnly = false, ) { - const { translate } = translator(locale); + const { strings } = translator(locale); const number = typeof tank === 'string' ? Number(tank) : tank; if (Number.isNaN(number)) { @@ -26,7 +27,7 @@ export async function resolveTankId( if (searchResult.length === 0) { throw new UserError( - translate('bot.common.errors.tank_name_not_found', [ + literals(strings.bot.common.errors.tank_name_not_found, [ markdownEscape(`${tank}`), ]), ); @@ -40,7 +41,7 @@ export async function resolveTankId( return number; } else { throw new UserError( - translate('bot.common.errors.tank_id_not_found', [`${number}`]), + literals(strings.bot.common.errors.tank_id_not_found, [`${number}`]), ); } } diff --git a/packages/bot/src/core/blitzkit/filtersToDescription.ts b/packages/bot/src/core/blitzkit/filtersToDescription.ts index f022a9006..fcc4aa837 100644 --- a/packages/bot/src/core/blitzkit/filtersToDescription.ts +++ b/packages/bot/src/core/blitzkit/filtersToDescription.ts @@ -1,4 +1,5 @@ import { fetchTankDefinitions, TIER_ROMAN_NUMERALS } from '@blitzkit/core'; +import { literals } from '@blitzkit/i18n'; import { Locale } from 'discord.js'; import { StatFilters } from '../blitzstars/filterStats'; import { translator } from '../localization/translator'; @@ -7,22 +8,21 @@ export async function filtersToDescription( { nation, tier, type, class: tankClass, tank }: StatFilters, locale: Locale, ) { - const { translate } = translator(locale); + const { strings } = translator(locale); const awaitedTankDefinitions = await fetchTankDefinitions(); const info: string[] = []; // TODO: somehow localize tank names? if (tank) return awaitedTankDefinitions.tanks[tank].name; - if (nation) info.push(translate(`common.nations.${nation}`)); + if (nation) + info.push((strings.common.nations as Record)[nation]); if (tier) { info.push( - translate('bot.common.filters.tier', [TIER_ROMAN_NUMERALS[tier]]), + literals(strings.bot.common.filters.tier, [TIER_ROMAN_NUMERALS[tier]]), ); } - if (tankClass) info.push(translate(`common.tank_class_short.${tankClass}`)); - if (type) info.push(translate(`common.tree_type.${type}`)); + if (tankClass) info.push(strings.common.tank_class_short[tankClass]); + if (type) info.push(strings.common.tree_type[type]); - return info.length === 0 - ? translate('bot.common.filters.none') - : info.join(', '); + return info.length === 0 ? strings.bot.common.filters.none : info.join(', '); } diff --git a/packages/bot/src/core/discord/addClanChoices.ts b/packages/bot/src/core/discord/addClanChoices.ts index f1d2f6ea7..e12944dce 100644 --- a/packages/bot/src/core/discord/addClanChoices.ts +++ b/packages/bot/src/core/discord/addClanChoices.ts @@ -3,16 +3,22 @@ import { translator } from '../localization/translator'; import { localizationObject } from './localizationObject'; export function addClanChoices(option: SlashCommandStringOption) { - const { translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); return option .setName('clan') .setNameLocalizations( - localizationObject('bot.common.options.clan', undefined, true), + localizationObject( + (strings) => strings.bot.common.options.clan.$, + undefined, + true, + ), ) - .setDescription(translate('bot.common.options.clan.description')) + .setDescription(strings.bot.common.options.clan.description) .setDescriptionLocalizations( - localizationObject('bot.common.options.clan.description'), + localizationObject( + (strings) => strings.bot.common.options.clan.description, + ), ) .setAutocomplete(true) .setMinLength(2) diff --git a/packages/bot/src/core/discord/addFilterOptions.ts b/packages/bot/src/core/discord/addFilterOptions.ts index e1a91121c..4a3ae7e94 100644 --- a/packages/bot/src/core/discord/addFilterOptions.ts +++ b/packages/bot/src/core/discord/addFilterOptions.ts @@ -17,34 +17,40 @@ import { localizationObject } from './localizationObject'; export function addFilterOptions< Option extends SlashCommandBuilder | SlashCommandSubcommandBuilder, >(option: Option, nations: string[]) { - const { translate } = translator(Locale.EnglishUS); + const { strings } = translator(Locale.EnglishUS); return ( option .addStringOption((option) => option - .setName(translate('bot.common.options.filters.nation')) + .setName(strings.bot.common.options.filters.nation.$) .setNameLocalizations( localizationObject( - 'bot.common.options.filters.nation', + (strings) => strings.bot.common.options.filters.nation.$, undefined, true, ), ) - .setDescription( - translate('bot.common.options.filters.nation.description'), - ) + .setDescription(strings.bot.common.options.filters.nation.description) .setDescriptionLocalizations( - localizationObject('bot.common.options.filters.nation.description'), + localizationObject( + (strings) => + strings.bot.common.options.filters.nation.description, + ), ) .addChoices( ...nations.map( (nation) => ({ value: nation, - name: translate(`common.nations.${nation}`), + name: (strings.common.nations as Record)[ + nation + ], name_localizations: localizationObject( - `common.nations.${nation}`, + (strings) => + (strings.common.nations as Record)[ + nation + ], ), }) satisfies APIApplicationCommandOptionChoice, ), @@ -54,28 +60,28 @@ export function addFilterOptions< .addStringOption((option) => addTierChoices(option).setRequired(false)) .addStringOption((option) => option - .setName(translate('bot.common.options.filters.class')) + .setName(strings.bot.common.options.filters.class.$) .setNameLocalizations( localizationObject( - 'bot.common.options.filters.class', + (strings) => strings.bot.common.options.filters.class.$, undefined, true, ), ) - .setDescription( - translate('bot.common.options.filters.class.description'), - ) + .setDescription(strings.bot.common.options.filters.class.description) .setDescriptionLocalizations( - localizationObject('bot.common.options.filters.class.description'), + localizationObject( + (strings) => strings.bot.common.options.filters.class.description, + ), ) .addChoices( ...TANK_CLASSES.map( (tankType) => ({ value: `${tankType}`, - name: translate(`common.tank_class_short.${tankType}`), + name: strings.common.tank_class_short[tankType], name_localizations: localizationObject( - `common.tank_class_short.${tankType}`, + (strings) => strings.common.tank_class_short[tankType], ), }) satisfies APIApplicationCommandOptionChoice, ), @@ -84,28 +90,28 @@ export function addFilterOptions< ) .addStringOption((option) => option - .setName(translate('bot.common.options.filters.type')) + .setName(strings.bot.common.options.filters.type.$) .setNameLocalizations( localizationObject( - 'bot.common.options.filters.type', + (strings) => strings.bot.common.options.filters.type.$, undefined, true, ), ) - .setDescription( - translate('bot.common.options.filters.type.description'), - ) + .setDescription(strings.bot.common.options.filters.type.description) .setDescriptionLocalizations( - localizationObject('bot.common.options.filters.type.description'), + localizationObject( + (strings) => strings.bot.common.options.filters.type.description, + ), ) .addChoices( ...TANK_TYPES.map( (treeType) => ({ value: TANK_TYPE_COMMAND_NAMES[treeType], - name: translate(`common.tree_type.${treeType}`), + name: strings.common.tree_type[treeType], name_localizations: localizationObject( - `common.tree_type.${treeType}`, + (strings) => strings.common.tree_type[treeType], ), }) satisfies APIApplicationCommandOptionChoice, ),