mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
feat: update bot chunk 1
This commit is contained in:
1 parent
bb557a7dd7
commit
d2b24fc953
42 files changed
+368
-387
No files matched your search
@@ -3,6 +3,7 @@ import {
|
|||||||
Region,
|
Region,
|
||||||
regionToRegionSubdomain,
|
regionToRegionSubdomain,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
||||||
import { chunkLines } from '../core/discord/chunkLines';
|
import { chunkLines } from '../core/discord/chunkLines';
|
||||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||||
@@ -75,7 +76,7 @@ export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
command: createLocalizedCommand('auction'),
|
command: createLocalizedCommand('auction'),
|
||||||
|
|
||||||
async handler(interaction) {
|
async handler(interaction) {
|
||||||
const { t, translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
const awaitedTankDefinitions = await tankDefinitions;
|
||||||
const region: Region = 'com';
|
const region: Region = 'com';
|
||||||
const pageSize = 80;
|
const pageSize = 80;
|
||||||
@@ -90,13 +91,13 @@ export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
const saleableTanks = data.results.filter((result) => result.available);
|
const saleableTanks = data.results.filter((result) => result.available);
|
||||||
|
|
||||||
if (saleableTanks.length === 0) {
|
if (saleableTanks.length === 0) {
|
||||||
return t`bot.commands.auction.errors.no_auction`;
|
return strings.bot.commands.auction.errors.no_auction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextPricesTimestamp = saleableTanks[0].next_price_timestamp;
|
const nextPricesTimestamp = saleableTanks[0].next_price_timestamp;
|
||||||
|
|
||||||
const title = `# ${t`bot.commands.auction.body.title`}`;
|
const title = `# ${strings.bot.commands.auction.body.title}`;
|
||||||
const subtitle = `${translate('bot.commands.auction.body.subtitle', [
|
const subtitle = `${literals(strings.bot.commands.auction.body.subtitle, [
|
||||||
`${saleableTanks.length} / ${data.results.length}`,
|
`${saleableTanks.length} / ${data.results.length}`,
|
||||||
`<t:${nextPricesTimestamp}:R>`,
|
`<t:${nextPricesTimestamp}:R>`,
|
||||||
'<https://wotblitz.com/auction/>',
|
'<https://wotblitz.com/auction/>',
|
||||||
@@ -112,15 +113,18 @@ export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
const next =
|
const next =
|
||||||
data.next_price === null
|
data.next_price === null
|
||||||
? ''
|
? ''
|
||||||
: `\n-# ${translate('bot.commands.auction.body.next', [
|
: `\n-# ${literals(strings.bot.commands.auction.body.next, [
|
||||||
`<:gold:1317173197082333244> ${data.next_price.value.toLocaleString(
|
`<:gold:1317173197082333244> ${data.next_price.value.toLocaleString(
|
||||||
interaction.locale,
|
interaction.locale,
|
||||||
)}`,
|
)}`,
|
||||||
])}`;
|
])}`;
|
||||||
const available = translate('bot.commands.auction.body.available', [
|
const available = literals(
|
||||||
|
strings.bot.commands.auction.body.available,
|
||||||
|
[
|
||||||
data.current_count.toLocaleString(interaction.locale),
|
data.current_count.toLocaleString(interaction.locale),
|
||||||
data.initial_count.toLocaleString(interaction.locale),
|
data.initial_count.toLocaleString(interaction.locale),
|
||||||
]);
|
],
|
||||||
|
);
|
||||||
const isOut = data.current_count === 0;
|
const isOut = data.current_count === 0;
|
||||||
const outString = isOut ? '~~' : '';
|
const outString = isOut ? '~~' : '';
|
||||||
const isLow = data.current_count <= WARNING_COUNT;
|
const isLow = data.current_count <= WARNING_COUNT;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getAccountInfo, getClanInfo } from '@blitzkit/core';
|
import { getAccountInfo, getClanInfo } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { CommandWrapper } from '../components/CommandWrapper';
|
import { CommandWrapper } from '../components/CommandWrapper';
|
||||||
import { GenericStats } from '../components/GenericStats';
|
import { GenericStats } from '../components/GenericStats';
|
||||||
@@ -19,7 +20,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
command: createLocalizedCommand('inactive')
|
command: createLocalizedCommand('inactive')
|
||||||
.addStringOption(addClanChoices)
|
.addStringOption(addClanChoices)
|
||||||
.addNumberOption((option) => {
|
.addNumberOption((option) => {
|
||||||
const { translate } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
|
|
||||||
return option
|
return option
|
||||||
.setName('threshold')
|
.setName('threshold')
|
||||||
@@ -31,7 +32,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
translate('bot.commands.inactive.options.threshold.description'),
|
strings.bot.commands.inactive.options.threshold.description,
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(
|
localizationObject(
|
||||||
@@ -42,7 +43,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
async handler(interaction) {
|
async handler(interaction) {
|
||||||
const { translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const { region, id } = await resolveClanFromCommand(interaction);
|
const { region, id } = await resolveClanFromCommand(interaction);
|
||||||
const threshold =
|
const threshold =
|
||||||
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
||||||
@@ -63,7 +64,7 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
([name, days]) =>
|
([name, days]) =>
|
||||||
[
|
[
|
||||||
name,
|
name,
|
||||||
translate('bot.commands.inactive.body.listing', [
|
literals(strings.bot.commands.inactive.body.listing, [
|
||||||
days.toFixed(0),
|
days.toFixed(0),
|
||||||
]),
|
]),
|
||||||
] as [string, string],
|
] as [string, string],
|
||||||
@@ -75,9 +76,10 @@ export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|||||||
<TitleBar
|
<TitleBar
|
||||||
title={clanInfo.name}
|
title={clanInfo.name}
|
||||||
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`}
|
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`}
|
||||||
description={`${translate('bot.commands.inactive.body.subtitle', [
|
description={`${literals(
|
||||||
`${threshold}`,
|
strings.bot.commands.inactive.body.subtitle,
|
||||||
])} • ${new Date().toLocaleDateString(interaction.locale)}`}
|
[`${threshold}`],
|
||||||
|
)} • ${new Date().toLocaleDateString(interaction.locale)}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!hasInactiveMembers && (
|
{!hasInactiveMembers && (
|
||||||
|
|||||||
@@ -16,39 +16,67 @@ export function addPeriodSubCommands(
|
|||||||
option: SlashCommandSubcommandBuilder,
|
option: SlashCommandSubcommandBuilder,
|
||||||
) => SlashCommandSubcommandBuilder = (option) => option,
|
) => SlashCommandSubcommandBuilder = (option) => option,
|
||||||
) {
|
) {
|
||||||
const { translate } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
const subcommandNameLocalizations = {
|
const subcommandNameLocalizations = {
|
||||||
today: localizationObject('bot.common.subcommands.today', undefined, true),
|
today: localizationObject(
|
||||||
30: localizationObject('bot.common.subcommands.30', undefined, true),
|
(strings) => strings.bot.common.subcommands.today.$,
|
||||||
60: localizationObject('bot.common.subcommands.60', undefined, true),
|
undefined,
|
||||||
90: localizationObject('bot.common.subcommands.90', undefined, true),
|
true,
|
||||||
|
),
|
||||||
|
30: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands[30].$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
60: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands[60].$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
90: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands[90].$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
career: localizationObject(
|
career: localizationObject(
|
||||||
'bot.common.subcommands.career',
|
(strings) => strings.bot.common.subcommands.career.$,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
custom: localizationObject(
|
custom: localizationObject(
|
||||||
'bot.common.subcommands.custom',
|
(strings) => strings.bot.common.subcommands.custom.$,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
const subcommandDescriptionLocalizations = {
|
const subcommandDescriptionLocalizations = {
|
||||||
today: localizationObject('bot.common.subcommands.today.description'),
|
today: localizationObject(
|
||||||
30: localizationObject('bot.common.subcommands.30.description'),
|
(strings) => strings.bot.common.subcommands.today.description,
|
||||||
60: localizationObject('bot.common.subcommands.60.description'),
|
),
|
||||||
90: localizationObject('bot.common.subcommands.90.description'),
|
30: localizationObject(
|
||||||
career: localizationObject('bot.common.subcommands.career.description'),
|
(strings) => strings.bot.common.subcommands[30].description,
|
||||||
custom: localizationObject('bot.common.subcommands.custom.description'),
|
),
|
||||||
|
60: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands[60].description,
|
||||||
|
),
|
||||||
|
90: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands[90].description,
|
||||||
|
),
|
||||||
|
career: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands.career.description,
|
||||||
|
),
|
||||||
|
custom: localizationObject(
|
||||||
|
(strings) => strings.bot.common.subcommands.custom.description,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
option
|
option
|
||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.today'))
|
.setName(strings.bot.common.subcommands.today.$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations.today)
|
.setNameLocalizations(subcommandNameLocalizations.today)
|
||||||
.setDescription(translate('bot.common.subcommands.today.description'))
|
.setDescription(strings.bot.common.subcommands.today.description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
subcommandDescriptionLocalizations.today,
|
subcommandDescriptionLocalizations.today,
|
||||||
),
|
),
|
||||||
@@ -57,38 +85,36 @@ export function addPeriodSubCommands(
|
|||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.30'))
|
.setName(strings.bot.common.subcommands[30].$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations[30])
|
.setNameLocalizations(subcommandNameLocalizations[30])
|
||||||
.setDescription(translate('bot.common.subcommands.30.description'))
|
.setDescription(strings.bot.common.subcommands[30].description)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations[30]),
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations[30]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.60'))
|
.setName(strings.bot.common.subcommands[60].$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations[60])
|
.setNameLocalizations(subcommandNameLocalizations[60])
|
||||||
.setDescription(translate('bot.common.subcommands.60.description'))
|
.setDescription(strings.bot.common.subcommands[60].description)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations[60]),
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations[60]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.90'))
|
.setName(strings.bot.common.subcommands[90].$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations[90])
|
.setNameLocalizations(subcommandNameLocalizations[90])
|
||||||
.setDescription(translate('bot.common.subcommands.90.description'))
|
.setDescription(strings.bot.common.subcommands[90].description)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations[90]),
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations[90]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.career'))
|
.setName(strings.bot.common.subcommands.career.$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations.career)
|
.setNameLocalizations(subcommandNameLocalizations.career)
|
||||||
.setDescription(
|
.setDescription(strings.bot.common.subcommands.career.description)
|
||||||
translate('bot.common.subcommands.career.description'),
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
subcommandDescriptionLocalizations.career,
|
subcommandDescriptionLocalizations.career,
|
||||||
),
|
),
|
||||||
@@ -97,31 +123,25 @@ export function addPeriodSubCommands(
|
|||||||
.addSubcommand((option) =>
|
.addSubcommand((option) =>
|
||||||
extra(
|
extra(
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.custom'))
|
.setName(strings.bot.common.subcommands.custom.$)
|
||||||
.setNameLocalizations(subcommandNameLocalizations.custom)
|
.setNameLocalizations(subcommandNameLocalizations.custom)
|
||||||
.setDescription(
|
.setDescription(strings.bot.common.subcommands.custom.description)
|
||||||
translate('bot.common.subcommands.custom.description'),
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
subcommandDescriptionLocalizations.custom,
|
subcommandDescriptionLocalizations.custom,
|
||||||
)
|
)
|
||||||
.addIntegerOption((option) =>
|
.addIntegerOption((option) =>
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.custom.options.start'))
|
.setName(strings.bot.common.subcommands.custom.options.start.$)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
translate(
|
strings.bot.common.subcommands.custom.options.start.description,
|
||||||
'bot.common.subcommands.custom.options.start.description',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
)
|
)
|
||||||
.addIntegerOption((option) =>
|
.addIntegerOption((option) =>
|
||||||
option
|
option
|
||||||
.setName(translate('bot.common.subcommands.custom.options.end'))
|
.setName(strings.bot.common.subcommands.custom.options.end.$)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
translate(
|
strings.bot.common.subcommands.custom.options.end.description,
|
||||||
'bot.common.subcommands.custom.options.end.description',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.setRequired(true),
|
.setRequired(true),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -8,25 +8,31 @@ import { translator } from '../localization/translator';
|
|||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from './localizationObject';
|
||||||
|
|
||||||
export function addRegionChoices(option: SlashCommandStringOption) {
|
export function addRegionChoices(option: SlashCommandStringOption) {
|
||||||
const { t, translate } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
|
|
||||||
return option
|
return option
|
||||||
.setName(t`bot.common.options.region`)
|
.setName(strings.bot.common.options.region.$)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject('bot.common.options.region', undefined, true),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.region.$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setDescription(t`bot.common.options.region.description`)
|
.setDescription(strings.bot.common.options.region.description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject('bot.common.options.region.description'),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.region.description,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.addChoices(
|
.addChoices(
|
||||||
...REGIONS.map(
|
...REGIONS.map(
|
||||||
(region) =>
|
(region) =>
|
||||||
({
|
({
|
||||||
value: region,
|
value: region,
|
||||||
name: translate(`common.regions.normal.${region}`),
|
name: strings.common.regions.normal[region],
|
||||||
name_localizations: localizationObject(
|
name_localizations: localizationObject(
|
||||||
`common.regions.normal.${region}`,
|
(strings) => strings.common.regions.normal[region],
|
||||||
),
|
),
|
||||||
}) satisfies APIApplicationCommandOptionChoice,
|
}) satisfies APIApplicationCommandOptionChoice,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,16 +3,22 @@ import { translator } from '../localization/translator';
|
|||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from './localizationObject';
|
||||||
|
|
||||||
export function addTankChoices(option: SlashCommandStringOption) {
|
export function addTankChoices(option: SlashCommandStringOption) {
|
||||||
const { translate } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
|
|
||||||
return option
|
return option
|
||||||
.setName(translate('bot.common.options.tank'))
|
.setName(strings.bot.common.options.tank.$)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject('bot.common.options.tank', undefined, true),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.tank.$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setDescription(translate('bot.common.options.tank.description'))
|
.setDescription(strings.bot.common.options.tank.description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject('bot.common.options.tank.description'),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.tank.description,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setAutocomplete(true)
|
.setAutocomplete(true)
|
||||||
.setRequired(true);
|
.setRequired(true);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { numberToRomanNumeral } from '@blitzkit/core';
|
import { numberToRomanNumeral } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import {
|
import {
|
||||||
APIApplicationCommandOptionChoice,
|
APIApplicationCommandOptionChoice,
|
||||||
Locale,
|
Locale,
|
||||||
@@ -9,28 +10,34 @@ import { translator } from '../localization/translator';
|
|||||||
import { localizationObject } from './localizationObject';
|
import { localizationObject } from './localizationObject';
|
||||||
|
|
||||||
export function addTierChoices(option: SlashCommandStringOption) {
|
export function addTierChoices(option: SlashCommandStringOption) {
|
||||||
const { t, translate } = translator(Locale.EnglishUS);
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
|
|
||||||
return option
|
return option
|
||||||
.setName(t`bot.common.options.tier`)
|
.setName(strings.bot.common.options.tier.$)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject('bot.common.options.tier', undefined, true),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.tier.$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setDescription(t`bot.common.options.tier.description`)
|
.setDescription(strings.bot.common.options.tier.description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject('bot.common.options.tier.description'),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.common.options.tier.description,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setChoices(
|
.setChoices(
|
||||||
...range(10, 0).map(
|
...range(10, 0).map(
|
||||||
(tier) =>
|
(tier) =>
|
||||||
({
|
({
|
||||||
name: translate('bot.common.options.tier.choices.tier', [
|
name: literals(strings.bot.common.options.tier.choices.tier, [
|
||||||
`${tier}`,
|
`${tier}`,
|
||||||
numberToRomanNumeral(tier),
|
numberToRomanNumeral(tier),
|
||||||
]),
|
]),
|
||||||
value: `${tier}`,
|
value: `${tier}`,
|
||||||
name_localizations: localizationObject(
|
name_localizations: localizationObject(
|
||||||
'bot.common.options.tier.choices.tier',
|
(strings) => strings.bot.common.options.tier.choices.tier,
|
||||||
[`${tier}`, numberToRomanNumeral(tier)],
|
[`${tier}`, numberToRomanNumeral(tier)],
|
||||||
),
|
),
|
||||||
}) satisfies APIApplicationCommandOptionChoice,
|
}) satisfies APIApplicationCommandOptionChoice,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { DISCORD_CHOICES_MAX_NAME_SIZE, OVERFLOW_SUFFIX } from './constants';
|
|||||||
export async function autocompleteClan(
|
export async function autocompleteClan(
|
||||||
interaction: AutocompleteInteraction<CacheType>,
|
interaction: AutocompleteInteraction<CacheType>,
|
||||||
) {
|
) {
|
||||||
const { translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const focusedOption = interaction.options.getFocused(true);
|
const focusedOption = interaction.options.getFocused(true);
|
||||||
if (focusedOption.name !== 'clan') return;
|
if (focusedOption.name !== 'clan') return;
|
||||||
if (focusedOption.value.length < 2) return interaction.respond([]);
|
if (focusedOption.value.length < 2) return interaction.respond([]);
|
||||||
@@ -19,9 +19,7 @@ export async function autocompleteClan(
|
|||||||
await interaction.respond(
|
await interaction.respond(
|
||||||
clans
|
clans
|
||||||
? clans.map((clan) => {
|
? clans.map((clan) => {
|
||||||
let name = `${clan.name} (${translate(
|
let name = `${clan.name} (${strings.common.regions.short[clan.region]})`;
|
||||||
`common.regions.short.${clan.region}`,
|
|
||||||
)})`;
|
|
||||||
|
|
||||||
if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) {
|
if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) {
|
||||||
const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE;
|
const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE;
|
||||||
@@ -29,9 +27,7 @@ export async function autocompleteClan(
|
|||||||
name = `${clan.name.slice(
|
name = `${clan.name.slice(
|
||||||
0,
|
0,
|
||||||
clan.name.length - overSize - OVERFLOW_SUFFIX.length,
|
clan.name.length - overSize - OVERFLOW_SUFFIX.length,
|
||||||
)}${OVERFLOW_SUFFIX} (${translate(
|
)}${OVERFLOW_SUFFIX} (${strings.common.regions.short[clan.region]})`;
|
||||||
`common.regions.short.${clan.region}`,
|
|
||||||
)})`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
export async function autocompleteUsername(
|
export async function autocompleteUsername(
|
||||||
interaction: AutocompleteInteraction<CacheType>,
|
interaction: AutocompleteInteraction<CacheType>,
|
||||||
) {
|
) {
|
||||||
const { translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const focusedOption = interaction.options.getFocused(true);
|
const focusedOption = interaction.options.getFocused(true);
|
||||||
if (focusedOption.name !== 'username') return;
|
if (focusedOption.name !== 'username') return;
|
||||||
const players = await searchPlayersAcrossRegions(focusedOption.value);
|
const players = await searchPlayersAcrossRegions(focusedOption.value);
|
||||||
@@ -22,9 +22,9 @@ export async function autocompleteUsername(
|
|||||||
await interaction.respond(
|
await interaction.respond(
|
||||||
players
|
players
|
||||||
? players.map((player) => {
|
? players.map((player) => {
|
||||||
let name = `${player.nickname} (${translate(
|
let name = `${player.nickname} (${
|
||||||
`common.regions.short.${player.region}`,
|
strings.common.regions.short[player.region]
|
||||||
)})`;
|
})`;
|
||||||
|
|
||||||
if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) {
|
if (name.length > DISCORD_CHOICES_MAX_NAME_SIZE) {
|
||||||
const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE;
|
const overSize = name.length - DISCORD_CHOICES_MAX_NAME_SIZE;
|
||||||
@@ -32,9 +32,9 @@ export async function autocompleteUsername(
|
|||||||
name = `${player.nickname.slice(
|
name = `${player.nickname.slice(
|
||||||
0,
|
0,
|
||||||
player.nickname.length - overSize - OVERFLOW_SUFFIX.length,
|
player.nickname.length - overSize - OVERFLOW_SUFFIX.length,
|
||||||
)}${OVERFLOW_SUFFIX} (${translate(
|
)}${OVERFLOW_SUFFIX} (${
|
||||||
`common.regions.short.${player.region}`,
|
strings.common.regions.short[player.region]
|
||||||
)})`;
|
})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { BlitzKitStrings } from '@blitzkit/i18n';
|
||||||
import {
|
import {
|
||||||
Locale,
|
Locale,
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
@@ -23,28 +24,47 @@ export function createLocalizedCommand(
|
|||||||
| CreateLocalizedCommandSubcommand[]
|
| CreateLocalizedCommandSubcommand[]
|
||||||
| CreateLocalizedCommandSubcommandGroup[],
|
| CreateLocalizedCommandSubcommandGroup[],
|
||||||
) {
|
) {
|
||||||
const commandPathItem = command.replaceAll('-', '_');
|
const commandPathItem = command.replaceAll(
|
||||||
const { translate } = translator(Locale.EnglishUS);
|
'-',
|
||||||
|
'_',
|
||||||
|
) as keyof BlitzKitStrings['bot']['commands'];
|
||||||
|
const { strings } = translator(Locale.EnglishUS);
|
||||||
const slashCommand = new SlashCommandBuilder()
|
const slashCommand = new SlashCommandBuilder()
|
||||||
.setName(command)
|
.setName(command)
|
||||||
.setNameLocalizations(
|
.setNameLocalizations(
|
||||||
localizationObject(`bot.commands.${commandPathItem}`, undefined, true),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.commands[commandPathItem].$,
|
||||||
|
undefined,
|
||||||
|
true,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.setDescription(translate(`bot.commands.${commandPathItem}.description`))
|
.setDescription(strings.bot.commands[commandPathItem].description)
|
||||||
.setDescriptionLocalizations(
|
.setDescriptionLocalizations(
|
||||||
localizationObject(`bot.commands.${commandPathItem}.description`),
|
localizationObject(
|
||||||
|
(strings) => strings.bot.commands[commandPathItem].description,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (sub) {
|
if (sub) {
|
||||||
sub.map((subItem) => {
|
sub.map((subItem) => {
|
||||||
if ('subcommand' in subItem) {
|
if ('subcommand' in subItem) {
|
||||||
const subcommandNameLocalizations = localizationObject(
|
const subcommandNameLocalizations = localizationObject(
|
||||||
`bot.commands.${commandPathItem}.subcommands.${subItem.subcommand}`,
|
(strings) =>
|
||||||
|
(
|
||||||
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
|
subcommands: Record<string, { $: string }>;
|
||||||
|
}
|
||||||
|
).subcommands[subItem.subcommand].$,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const subcommandDescriptionLocalizations = localizationObject(
|
const subcommandDescriptionLocalizations = localizationObject(
|
||||||
`bot.commands.${commandPathItem}.subcommands.${subItem.subcommand}.description`,
|
(strings) =>
|
||||||
|
(
|
||||||
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
|
subcommands: Record<string, { description: string }>;
|
||||||
|
}
|
||||||
|
).subcommands[subItem.subcommand].description,
|
||||||
);
|
);
|
||||||
|
|
||||||
slashCommand.addSubcommand((option) => {
|
slashCommand.addSubcommand((option) => {
|
||||||
@@ -54,20 +74,32 @@ export function createLocalizedCommand(
|
|||||||
.setName(subItem.subcommand)
|
.setName(subItem.subcommand)
|
||||||
.setNameLocalizations(subcommandNameLocalizations)
|
.setNameLocalizations(subcommandNameLocalizations)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
translate(
|
(
|
||||||
`bot.commands.${commandPathItem}.subcommands.${subItem.subcommand}.description`,
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
),
|
subcommands: Record<string, { description: string }>;
|
||||||
|
}
|
||||||
|
).subcommands[subItem.subcommand].description,
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const subcommandNameLocalizations = localizationObject(
|
const subcommandNameLocalizations = localizationObject(
|
||||||
`bot.commands.${commandPathItem}.groups.${subItem.group}`,
|
(strings) =>
|
||||||
|
(
|
||||||
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
|
groups: Record<string, { $: string }>;
|
||||||
|
}
|
||||||
|
).groups[subItem.group].$,
|
||||||
undefined,
|
undefined,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
const subcommandDescriptionLocalizations = localizationObject(
|
const subcommandDescriptionLocalizations = localizationObject(
|
||||||
`bot.commands.${commandPathItem}.groups.${subItem.group}.description`,
|
(strings) =>
|
||||||
|
(
|
||||||
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
|
groups: Record<string, { description: string }>;
|
||||||
|
}
|
||||||
|
).groups[subItem.group].description,
|
||||||
);
|
);
|
||||||
|
|
||||||
slashCommand.addSubcommandGroup((option) => {
|
slashCommand.addSubcommandGroup((option) => {
|
||||||
@@ -77,9 +109,11 @@ export function createLocalizedCommand(
|
|||||||
.setName(subItem.group)
|
.setName(subItem.group)
|
||||||
.setNameLocalizations(subcommandNameLocalizations)
|
.setNameLocalizations(subcommandNameLocalizations)
|
||||||
.setDescription(
|
.setDescription(
|
||||||
translate(
|
(
|
||||||
`bot.commands.${commandPathItem}.groups.${subItem.group}.description`,
|
strings.bot.commands[commandPathItem] as unknown as {
|
||||||
),
|
groups: Record<string, { description: string }>;
|
||||||
|
}
|
||||||
|
).groups[subItem.group].description,
|
||||||
)
|
)
|
||||||
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
.setDescriptionLocalizations(subcommandDescriptionLocalizations);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from '../localization/translator';
|
||||||
import { PeriodSize } from './addPeriodSubCommands';
|
import { PeriodSize } from './addPeriodSubCommands';
|
||||||
|
|
||||||
export function getPeriodOptionName(period: PeriodSize, locale: Locale) {
|
export function getPeriodOptionName(period: PeriodSize, locale: Locale) {
|
||||||
const { translate } = translator(locale);
|
const { strings } = translator(locale);
|
||||||
if (period === 'career') return translate('bot.common.periods.career');
|
if (period === 'career') return strings.bot.common.periods.career;
|
||||||
if (period === 'today') return translate('bot.common.periods.today');
|
if (period === 'today') return strings.bot.common.periods.today;
|
||||||
return translate('bot.common.periods.days', [period]);
|
return literals(strings.bot.common.periods.days, [period]);
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { BlitzKitStrings, literals as literalsFunc } from '@blitzkit/i18n';
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { SUPPORTED_LOCALES_DISCORD } from '../localization/strings/constants';
|
import { SUPPORTED_LOCALES_DISCORD } from '../localization/strings/constants';
|
||||||
import { translator } from '../localization/translator';
|
import { translator } from '../localization/translator';
|
||||||
@@ -5,14 +6,14 @@ import { translator } from '../localization/translator';
|
|||||||
const validNameRegex = /^[-_\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$/u;
|
const validNameRegex = /^[-_\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$/u;
|
||||||
|
|
||||||
export function localizationObject(
|
export function localizationObject(
|
||||||
path: string,
|
path: (strings: BlitzKitStrings) => string,
|
||||||
literals?: string[],
|
literals: string[] = [],
|
||||||
strict = false,
|
strict = false,
|
||||||
) {
|
) {
|
||||||
return SUPPORTED_LOCALES_DISCORD.reduce<Partial<Record<Locale, string>>>(
|
return SUPPORTED_LOCALES_DISCORD.reduce<Partial<Record<Locale, string>>>(
|
||||||
(localizations, locale) => {
|
(localizations, locale) => {
|
||||||
const { translate } = translator(locale);
|
const { strings } = translator(locale);
|
||||||
const translation = translate(path, literals);
|
const translation = literalsFunc(path(strings), literals);
|
||||||
const isValid = !strict || validNameRegex.test(translation);
|
const isValid = !strict || validNameRegex.test(translation);
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Region } from '@blitzkit/core';
|
import { Region } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { ChatInputCommandInteraction } from 'discord.js';
|
import { ChatInputCommandInteraction } from 'discord.js';
|
||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { searchClansAcrossRegionsBotWrapper } from '../blitz/searchClansAcrossRegionsBotWrapper';
|
import { searchClansAcrossRegionsBotWrapper } from '../blitz/searchClansAcrossRegionsBotWrapper';
|
||||||
@@ -10,7 +11,7 @@ export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
|
|||||||
export async function resolveClanFromCommand(
|
export async function resolveClanFromCommand(
|
||||||
interaction: ChatInputCommandInteraction,
|
interaction: ChatInputCommandInteraction,
|
||||||
) {
|
) {
|
||||||
const { translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const clan = interaction.options.getString('clan', true);
|
const clan = interaction.options.getString('clan', true);
|
||||||
|
|
||||||
if (serverAndIdPattern.test(clan)) {
|
if (serverAndIdPattern.test(clan)) {
|
||||||
@@ -26,7 +27,9 @@ export async function resolveClanFromCommand(
|
|||||||
return { region: accounts[0].region, id: accounts[0].clan_id };
|
return { region: accounts[0].region, id: accounts[0].clan_id };
|
||||||
} else {
|
} else {
|
||||||
throw new UserError(
|
throw new UserError(
|
||||||
translate('bot.common.errors.clan_not_found', [markdownEscape(clan)]),
|
literals(strings.bot.common.errors.clan_not_found, [
|
||||||
|
markdownEscape(clan),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getTimeDaysAgo, Region } from '@blitzkit/core';
|
import { getTimeDaysAgo, Region } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||||
import { getPeriodNow } from '../blitzkit/getPeriodNow';
|
import { getPeriodNow } from '../blitzkit/getPeriodNow';
|
||||||
import { getPeriodStart } from '../blitzkit/getPeriodStart';
|
import { getPeriodStart } from '../blitzkit/getPeriodStart';
|
||||||
@@ -17,7 +18,7 @@ export function resolvePeriodFromCommand(
|
|||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
forcedPeriod?: PeriodType,
|
forcedPeriod?: PeriodType,
|
||||||
) {
|
) {
|
||||||
const { translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
let name: string;
|
let name: string;
|
||||||
let start: number;
|
let start: number;
|
||||||
let end: number;
|
let end: number;
|
||||||
@@ -31,7 +32,7 @@ export function resolvePeriodFromCommand(
|
|||||||
const startDaysAgoMin = Math.min(startOption, endOption);
|
const startDaysAgoMin = Math.min(startOption, endOption);
|
||||||
const endDaysAgoMax = Math.max(startOption, endOption);
|
const endDaysAgoMax = Math.max(startOption, endOption);
|
||||||
|
|
||||||
name = translate('bot.common.periods.custom', [
|
name = literals(strings.bot.common.periods.custom, [
|
||||||
`${startDaysAgoMin}`,
|
`${startDaysAgoMin}`,
|
||||||
`${endDaysAgoMax}`,
|
`${endDaysAgoMax}`,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { idToRegion, Region } from '@blitzkit/core';
|
import { idToRegion, Region } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { searchPlayersAcrossRegionsBotWrapper } from '../../blitz/searchPlayersAcrossRegionsBotWrapper';
|
import { searchPlayersAcrossRegionsBotWrapper } from '../../blitz/searchPlayersAcrossRegionsBotWrapper';
|
||||||
@@ -14,7 +15,7 @@ export interface ResolvedPlayer {
|
|||||||
export async function resolvePlayerFromCommand(
|
export async function resolvePlayerFromCommand(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
) {
|
) {
|
||||||
const { t, translate } = translator(interaction.locale);
|
const { strings } = translator(interaction.locale);
|
||||||
const commandUsername = interaction.options.getString('username');
|
const commandUsername = interaction.options.getString('username');
|
||||||
|
|
||||||
if (commandUsername !== null) {
|
if (commandUsername !== null) {
|
||||||
@@ -36,7 +37,7 @@ export async function resolvePlayerFromCommand(
|
|||||||
} satisfies ResolvedPlayer;
|
} satisfies ResolvedPlayer;
|
||||||
} else {
|
} else {
|
||||||
throw new UserError(
|
throw new UserError(
|
||||||
translate('bot.common.errors.player_not_found', [
|
literals(strings.bot.common.errors.player_not_found, [
|
||||||
markdownEscape(commandUsername),
|
markdownEscape(commandUsername),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
@@ -47,6 +48,6 @@ export async function resolvePlayerFromCommand(
|
|||||||
|
|
||||||
if (account) return account;
|
if (account) return account;
|
||||||
|
|
||||||
throw new UserError(t`bot.common.errors.player_not_linked`);
|
throw new UserError(strings.bot.common.errors.player_not_linked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Locale } from 'discord.js';
|
|
||||||
import {
|
|
||||||
SUPPORTED_LOCALES_DISCORD,
|
|
||||||
SUPPORTED_LOCALES_DISCORD_MAP_INVERSE,
|
|
||||||
} from './constants';
|
|
||||||
|
|
||||||
export type TranslationFragmentTree = {
|
|
||||||
[key: string]: TranslationFragment;
|
|
||||||
} & {
|
|
||||||
$?: string;
|
|
||||||
};
|
|
||||||
export type TranslationFragment = string | TranslationFragmentTree;
|
|
||||||
|
|
||||||
export const translations = SUPPORTED_LOCALES_DISCORD.reduce<
|
|
||||||
Partial<Record<Locale, TranslationFragment>>
|
|
||||||
>(
|
|
||||||
(table, locale) => ({
|
|
||||||
...table,
|
|
||||||
[locale]: require(
|
|
||||||
`@blitzkit/i18n/strings/${SUPPORTED_LOCALES_DISCORD_MAP_INVERSE[locale]}.json`,
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { unwrapper } from '@blitzkit/i18n';
|
import { STRINGS, unwrapper } from '@blitzkit/i18n';
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { translations } from './strings';
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_LOCALE_DISCORD,
|
DEFAULT_LOCALE_DISCORD,
|
||||||
SUPPORTED_LOCALES_DISCORD,
|
SUPPORTED_LOCALES_DISCORD,
|
||||||
@@ -13,70 +12,10 @@ export function translator(localeRaw: Locale) {
|
|||||||
SUPPORTED_LOCALES_DISCORD.includes(localeRaw)
|
SUPPORTED_LOCALES_DISCORD.includes(localeRaw)
|
||||||
? localeRaw
|
? localeRaw
|
||||||
: DEFAULT_LOCALE_DISCORD;
|
: DEFAULT_LOCALE_DISCORD;
|
||||||
const strings = translations[locale]!;
|
STRINGS;
|
||||||
|
const strings = STRINGS[SUPPORTED_LOCALES_DISCORD_MAP_INVERSE[locale]];
|
||||||
function translate(path: string, literals?: string[]): string {
|
|
||||||
const pathArray = path.split('.');
|
|
||||||
let fragment = strings;
|
|
||||||
let resolvedString: string;
|
|
||||||
|
|
||||||
for (const pathItem of pathArray) {
|
|
||||||
if (typeof fragment === 'string') {
|
|
||||||
throw new SyntaxError(
|
|
||||||
`Attempted to access string with key "${pathItem}" in "${path}" from within a string instead of an object in locale "${locale}"`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
fragment = fragment[pathItem];
|
|
||||||
|
|
||||||
if (typeof fragment === 'undefined') {
|
|
||||||
const message = `Undefined translation at "${pathItem}" in "${path}" for locale "${locale}"`;
|
|
||||||
|
|
||||||
if (locale === DEFAULT_LOCALE_DISCORD) {
|
|
||||||
throw new Error(message);
|
|
||||||
} else {
|
|
||||||
console.warn(`${message} falling back to en-US`);
|
|
||||||
return translator(DEFAULT_LOCALE_DISCORD).translate(path, literals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof fragment === 'string') {
|
|
||||||
resolvedString = fragment;
|
|
||||||
} else if (fragment.$) {
|
|
||||||
resolvedString = fragment.$!;
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`Unresolved tree ending for "${path}" in locale "${locale}"`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (literals) {
|
|
||||||
const chunks = resolvedString.split('%s');
|
|
||||||
let embeddedString = '';
|
|
||||||
|
|
||||||
chunks.forEach((chunk, index) => {
|
|
||||||
if (index !== 0) embeddedString += literals[index - 1];
|
|
||||||
embeddedString += chunk;
|
|
||||||
});
|
|
||||||
|
|
||||||
return embeddedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function t(paths: TemplateStringsArray, ...embeds: string[]) {
|
|
||||||
return paths
|
|
||||||
.map((path, index) =>
|
|
||||||
path.length === 0
|
|
||||||
? ''
|
|
||||||
: `${translate(path)}${index === embeds.length ? '' : embeds[index]}`,
|
|
||||||
)
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
const unwrap = unwrapper(SUPPORTED_LOCALES_DISCORD_MAP_INVERSE[locale]);
|
const unwrap = unwrapper(SUPPORTED_LOCALES_DISCORD_MAP_INVERSE[locale]);
|
||||||
|
|
||||||
return { locale, translate, t, unwrap };
|
return { locale, strings, unwrap };
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,6 @@ import {
|
|||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
AttachmentBuilder,
|
AttachmentBuilder,
|
||||||
ButtonBuilder,
|
ButtonBuilder,
|
||||||
ButtonStyle,
|
|
||||||
CacheType,
|
CacheType,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
InteractionReplyOptions,
|
InteractionReplyOptions,
|
||||||
@@ -14,7 +13,6 @@ import { normalizeInteractionReturnable } from '../../../core/discord/normalizeI
|
|||||||
import { psa } from '../../../core/discord/psa';
|
import { psa } from '../../../core/discord/psa';
|
||||||
import { translator } from '../../../core/localization/translator';
|
import { translator } from '../../../core/localization/translator';
|
||||||
import { Writeable } from '../../../types/writable';
|
import { Writeable } from '../../../types/writable';
|
||||||
import { UserError } from '../../../core/blitzkit/userError';
|
|
||||||
|
|
||||||
export async function handleChatInputCommand(
|
export async function handleChatInputCommand(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
@@ -127,27 +125,25 @@ export async function handleChatInputCommand(
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const { t } = translator(interaction.locale);
|
const { t } = translator(interaction.locale);
|
||||||
const components = [
|
// const components = [
|
||||||
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
// new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||||
new ButtonBuilder()
|
// new ButtonBuilder()
|
||||||
.setLabel(t`bot.common.errors.get_help`)
|
// .setLabel(t`bot.common.errors.get_help`)
|
||||||
.setURL('https://discord.gg/nDt7AjGJQH')
|
// .setURL('https://discord.gg/nDt7AjGJQH')
|
||||||
.setStyle(ButtonStyle.Link),
|
// .setStyle(ButtonStyle.Link),
|
||||||
),
|
// ),
|
||||||
];
|
// ];
|
||||||
|
// if (error instanceof UserError) {
|
||||||
if (error instanceof UserError) {
|
// interaction.editReply({
|
||||||
interaction.editReply({
|
// content: error.message,
|
||||||
content: error.message,
|
// components,
|
||||||
components,
|
// });
|
||||||
});
|
// } else {
|
||||||
} else {
|
// console.error(interaction.commandName, error);
|
||||||
console.error(interaction.commandName, error);
|
// interaction.editReply({
|
||||||
|
// content: t`bot.common.errors.uncaught_error`,
|
||||||
interaction.editReply({
|
// components,
|
||||||
content: t`bot.common.errors.uncaught_error`,
|
// });
|
||||||
components,
|
// }
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { assertSecret } from '@blitzkit/core';
|
|
||||||
import {
|
import {
|
||||||
AttachmentBuilder,
|
AttachmentBuilder,
|
||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
@@ -8,35 +7,12 @@ import {
|
|||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
Interaction,
|
Interaction,
|
||||||
REST,
|
|
||||||
Routes,
|
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
SlashCommandOptionsOnlyBuilder,
|
SlashCommandOptionsOnlyBuilder,
|
||||||
SlashCommandSubcommandsOnlyBuilder,
|
SlashCommandSubcommandsOnlyBuilder,
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { aboutCommand } from '../../commands/about';
|
|
||||||
import { auctionCommand } from '../../commands/auction';
|
|
||||||
import { breakdownCommand } from '../../commands/breakdown';
|
|
||||||
import { debugCommand } from '../../commands/debug';
|
|
||||||
import { evolutionCommand } from '../../commands/evolution';
|
|
||||||
import { fullStatsCommand } from '../../commands/fullStats';
|
|
||||||
import { inactiveCommand } from '../../commands/inactive';
|
|
||||||
import { verifyCommand } from '../../commands/link';
|
|
||||||
import { ownedTanksCommand } from '../../commands/ownedTanks';
|
|
||||||
import { permissionsCommand } from '../../commands/permissions';
|
|
||||||
import { pingCommand } from '../../commands/ping';
|
|
||||||
import { playerInfoCommand } from '../../commands/playerInfo';
|
|
||||||
import { ratingCommand } from '../../commands/rating';
|
|
||||||
import { ratingLeaderboardCommand } from '../../commands/ratingLeaderboard';
|
|
||||||
import { replayCommand } from '../../commands/replay';
|
|
||||||
import { researchCommand } from '../../commands/research';
|
|
||||||
import { searchClansCommand } from '../../commands/searchClans';
|
|
||||||
import { searchPlayersCommand } from '../../commands/searchPlayers';
|
|
||||||
import { statsCommand } from '../../commands/stats';
|
|
||||||
import { todayCommand } from '../../commands/today';
|
|
||||||
import { RenderConfiguration } from '../../core/blitzkit/renderConfiguration';
|
import { RenderConfiguration } from '../../core/blitzkit/renderConfiguration';
|
||||||
import { handleAutocomplete } from './handlers/autocomplete';
|
import { handleAutocomplete } from './handlers/autocomplete';
|
||||||
import { handleButton } from './handlers/button';
|
|
||||||
import { handleChatInputCommand } from './handlers/chatInputCommand';
|
import { handleChatInputCommand } from './handlers/chatInputCommand';
|
||||||
|
|
||||||
export type InteractionRawReturnable =
|
export type InteractionRawReturnable =
|
||||||
@@ -64,71 +40,72 @@ interface CommandRegistryBase {
|
|||||||
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
|
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
|
||||||
button?: (interaction: ButtonInteraction<CacheType>) => InteractionReturnable;
|
button?: (interaction: ButtonInteraction<CacheType>) => InteractionReturnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommandRegistryImplicit extends CommandRegistryBase {
|
interface CommandRegistryImplicit extends CommandRegistryBase {
|
||||||
handlesInteraction: true;
|
handlesInteraction: true;
|
||||||
handler: (interaction: ChatInputCommandInteraction<CacheType>) => void;
|
handler: (interaction: ChatInputCommandInteraction<CacheType>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommandRegistryExplicit extends CommandRegistryBase {
|
interface CommandRegistryExplicit extends CommandRegistryBase {
|
||||||
handlesInteraction?: false;
|
handlesInteraction?: false;
|
||||||
handler: (
|
handler: (
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
) => InteractionReturnable;
|
) => InteractionReturnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
|
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
|
||||||
|
|
||||||
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
|
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
|
||||||
auctionCommand,
|
// auctionCommand,
|
||||||
permissionsCommand,
|
// permissionsCommand,
|
||||||
debugCommand,
|
// debugCommand,
|
||||||
aboutCommand,
|
// aboutCommand,
|
||||||
inactiveCommand,
|
// inactiveCommand,
|
||||||
ownedTanksCommand,
|
// ownedTanksCommand,
|
||||||
playerInfoCommand,
|
// playerInfoCommand,
|
||||||
searchClansCommand,
|
// searchClansCommand,
|
||||||
searchPlayersCommand,
|
// searchPlayersCommand,
|
||||||
fullStatsCommand,
|
// fullStatsCommand,
|
||||||
breakdownCommand,
|
// breakdownCommand,
|
||||||
verifyCommand,
|
// verifyCommand,
|
||||||
pingCommand,
|
// pingCommand,
|
||||||
evolutionCommand,
|
// evolutionCommand,
|
||||||
statsCommand,
|
// statsCommand,
|
||||||
ratingLeaderboardCommand,
|
// ratingLeaderboardCommand,
|
||||||
todayCommand,
|
// todayCommand,
|
||||||
researchCommand,
|
// researchCommand,
|
||||||
ratingCommand,
|
// ratingCommand,
|
||||||
replayCommand,
|
// replayCommand,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {
|
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {
|
||||||
return rawCommands.reduce<Record<string, CommandRegistry>>(
|
// return rawCommands.reduce<Record<string, CommandRegistry>>(
|
||||||
(commands, registry, index) => {
|
// (commands, registry, index) => {
|
||||||
if (registry.status === 'rejected') {
|
// if (registry.status === 'rejected') {
|
||||||
console.warn(
|
// console.warn(
|
||||||
`Command ${index} failed to load; skipping...`,
|
// `Command ${index} failed to load; skipping...`,
|
||||||
registry.reason,
|
// registry.reason,
|
||||||
);
|
// );
|
||||||
|
// return commands;
|
||||||
return commands;
|
// }
|
||||||
}
|
// return { ...commands, [registry.value.command.name]: registry.value };
|
||||||
|
// },
|
||||||
return { ...commands, [registry.value.command.name]: registry.value };
|
// {},
|
||||||
},
|
// );
|
||||||
{},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const rest = new REST().setToken(assertSecret(import.meta.env.DISCORD_TOKEN));
|
// const rest = new REST().setToken(assertSecret(import.meta.env.DISCORD_TOKEN));
|
||||||
|
|
||||||
commands.then((awaitedCommands) => {
|
// commands.then((awaitedCommands) => {
|
||||||
const body = Object.values(awaitedCommands).map((registry) =>
|
// const body = Object.values(awaitedCommands).map((registry) =>
|
||||||
registry.command.toJSON(),
|
// registry.command.toJSON(),
|
||||||
);
|
// );
|
||||||
|
|
||||||
rest.put(
|
// rest.put(
|
||||||
Routes.applicationCommands(assertSecret(import.meta.env.DISCORD_CLIENT_ID)),
|
// Routes.applicationCommands(assertSecret(import.meta.env.DISCORD_CLIENT_ID)),
|
||||||
{ body },
|
// { body },
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
|
|
||||||
export async function interactionCreate(interaction: Interaction<CacheType>) {
|
export async function interactionCreate(interaction: Interaction<CacheType>) {
|
||||||
if (interaction.isAutocomplete()) {
|
if (interaction.isAutocomplete()) {
|
||||||
@@ -136,6 +113,6 @@ export async function interactionCreate(interaction: Interaction<CacheType>) {
|
|||||||
} else if (interaction.isChatInputCommand()) {
|
} else if (interaction.isChatInputCommand()) {
|
||||||
handleChatInputCommand(interaction);
|
handleChatInputCommand(interaction);
|
||||||
} else if (interaction.isButton()) {
|
} else if (interaction.isButton()) {
|
||||||
handleButton(interaction);
|
// handleButton(interaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
|
export * from './literals';
|
||||||
export * from './strings';
|
export * from './strings';
|
||||||
export * from './supportedLocales';
|
|
||||||
export * from './unwrapper';
|
export * from './unwrapper';
|
||||||
File renamed without changes.
@@ -1,38 +1,21 @@
|
|||||||
import { merge } from 'lodash-es';
|
import { merge } from 'lodash-es';
|
||||||
import type en from '../strings/en.json';
|
import en from '../strings/en.json';
|
||||||
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from './supportedLocales';
|
import es from '../strings/es.json';
|
||||||
|
import fr from '../strings/fr.json';
|
||||||
|
import ja from '../strings/ja.json';
|
||||||
|
import pl from '../strings/pl.json';
|
||||||
|
import pt from '../strings/pt.json';
|
||||||
|
import ru from '../strings/ru.json';
|
||||||
|
import uk from '../strings/uk.json';
|
||||||
|
import zh from '../strings/zh.json';
|
||||||
|
|
||||||
export type TranslationTree = { [key: string]: TranslationNode };
|
export type BlitzKitStrings = typeof en;
|
||||||
|
|
||||||
export type TranslationNode = string | TranslationTree;
|
const stringsRaw = { en, es, fr, ja, pl, pt, ru, uk, zh };
|
||||||
|
|
||||||
const files = import.meta.glob('../strings/*.json', { eager: true });
|
export const SUPPORTED_LOCALES = Object.keys(stringsRaw) as SupportedLocale[];
|
||||||
export const localizedStrings: Record<string, typeof en> = {};
|
|
||||||
|
|
||||||
function nuke(object: TranslationTree) {
|
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
|
||||||
for (const key in object) {
|
|
||||||
const typedKey = key as keyof typeof object;
|
|
||||||
|
|
||||||
if (typeof object[typedKey] === 'string') {
|
|
||||||
const value = object[typedKey];
|
|
||||||
object[typedKey] = redact(value as string);
|
|
||||||
} else nuke(object[typedKey] as TranslationTree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SUPPORTED_LOCALES.forEach((locale) => {
|
|
||||||
const defaultStrings = files[`../strings/${DEFAULT_LOCALE}.json`];
|
|
||||||
const strings = files[`../strings/${locale}.json`];
|
|
||||||
const mergedStrings = merge({}, defaultStrings, strings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For some reason, this won't load on the server on the first render so I am
|
|
||||||
* not asserting this one lol
|
|
||||||
*/
|
|
||||||
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') nuke(mergedStrings);
|
|
||||||
|
|
||||||
localizedStrings[locale] = mergedStrings as typeof en;
|
|
||||||
});
|
|
||||||
|
|
||||||
function redact(string: string) {
|
function redact(string: string) {
|
||||||
const matches = [...string.matchAll(/%s\d+/g)];
|
const matches = [...string.matchAll(/%s\d+/g)];
|
||||||
@@ -50,3 +33,70 @@ function redact(string: string) {
|
|||||||
|
|
||||||
return characters.join('');
|
return characters.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function nuke(object: TranslationTree) {
|
||||||
|
for (const key in object) {
|
||||||
|
const typedKey = key as keyof typeof object;
|
||||||
|
|
||||||
|
if (typeof object[typedKey] === 'string') {
|
||||||
|
const value = object[typedKey];
|
||||||
|
object[typedKey] = redact(value as string);
|
||||||
|
} else nuke(object[typedKey] as TranslationTree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stringsPartial: Partial<Record<SupportedLocale, TranslationTree>> = {};
|
||||||
|
|
||||||
|
for (const locale in stringsRaw) {
|
||||||
|
if (locale === DEFAULT_LOCALE) {
|
||||||
|
stringsPartial[DEFAULT_LOCALE] = stringsRaw[DEFAULT_LOCALE];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const localeStrings = stringsRaw[locale as SupportedLocale];
|
||||||
|
|
||||||
|
stringsPartial[locale as SupportedLocale] = merge(
|
||||||
|
{},
|
||||||
|
stringsRaw[DEFAULT_LOCALE],
|
||||||
|
localeStrings,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') {
|
||||||
|
nuke(stringsPartial[locale as SupportedLocale]!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const STRINGS = stringsPartial as Record<
|
||||||
|
SupportedLocale,
|
||||||
|
BlitzKitStrings
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type SupportedLocale = keyof typeof stringsRaw;
|
||||||
|
|
||||||
|
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
|
||||||
|
en: 'en',
|
||||||
|
es: 'es',
|
||||||
|
fr: 'fr',
|
||||||
|
ja: 'ja',
|
||||||
|
pt: 'pt',
|
||||||
|
ru: 'ru',
|
||||||
|
uk: 'uk',
|
||||||
|
zh: 'zh-Hans',
|
||||||
|
pl: 'pl',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
||||||
|
en: '🇺🇸',
|
||||||
|
es: '🇪🇸',
|
||||||
|
fr: '🇫🇷',
|
||||||
|
ja: '🇯🇵',
|
||||||
|
pt: '🇵🇹',
|
||||||
|
ru: '🇷🇺',
|
||||||
|
uk: '🇺🇦',
|
||||||
|
zh: '🇨🇳',
|
||||||
|
pl: '🇵🇱',
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TranslationTree = { [key: string]: TranslationNode };
|
||||||
|
|
||||||
|
export type TranslationNode = string | TranslationTree;
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
export const SUPPORTED_LOCALES = [
|
|
||||||
'en',
|
|
||||||
'es',
|
|
||||||
'fr',
|
|
||||||
'ja',
|
|
||||||
'pl',
|
|
||||||
'pt',
|
|
||||||
'ru',
|
|
||||||
'uk',
|
|
||||||
'zh',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
export type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
|
|
||||||
|
|
||||||
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
|
|
||||||
|
|
||||||
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
|
|
||||||
en: 'en',
|
|
||||||
es: 'es',
|
|
||||||
fr: 'fr',
|
|
||||||
ja: 'ja',
|
|
||||||
pt: 'pt',
|
|
||||||
ru: 'ru',
|
|
||||||
uk: 'uk',
|
|
||||||
zh: 'zh-Hans',
|
|
||||||
pl: 'pl',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
|
|
||||||
en: '🇺🇸',
|
|
||||||
es: '🇪🇸',
|
|
||||||
fr: '🇫🇷',
|
|
||||||
ja: '🇯🇵',
|
|
||||||
pt: '🇵🇹',
|
|
||||||
ru: '🇷🇺',
|
|
||||||
uk: '🇺🇦',
|
|
||||||
zh: '🇨🇳',
|
|
||||||
pl: '🇵🇱',
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { I18nString } from '@blitzkit/core';
|
import { I18nString } from '@blitzkit/core';
|
||||||
import { DEFAULT_LOCALE } from './supportedLocales';
|
import { DEFAULT_LOCALE } from './strings';
|
||||||
|
|
||||||
export function unwrapper(locale: string) {
|
export function unwrapper(locale: string) {
|
||||||
return function (i18nString: I18nString) {
|
return function (i18nString: I18nString) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
Flex,
|
Flex,
|
||||||
@@ -8,7 +9,6 @@ import {
|
|||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import type { ComponentProps } from 'react';
|
import type { ComponentProps } from 'react';
|
||||||
import { radToDeg } from 'three/src/math/MathUtils.js';
|
import { radToDeg } from 'three/src/math/MathUtils.js';
|
||||||
import { literals } from '../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../hooks/useLocale';
|
import { useLocale } from '../../../hooks/useLocale';
|
||||||
import type { Shot, ShotLayer } from '../../../stores/tankopediaEphemeral';
|
import type { Shot, ShotLayer } from '../../../stores/tankopediaEphemeral';
|
||||||
import { shotStatusColors } from './ShotDisplay';
|
import { shotStatusColors } from './ShotDisplay';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
type AccountListItem,
|
type AccountListItem,
|
||||||
type AccountListWithServer,
|
type AccountListWithServer,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { CaretLeftIcon, Link2Icon, PersonIcon } from '@radix-ui/react-icons';
|
import { CaretLeftIcon, Link2Icon, PersonIcon } from '@radix-ui/react-icons';
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge,
|
||||||
@@ -18,7 +19,6 @@ import { debounce } from 'lodash-es';
|
|||||||
import { useCallback, useRef, useState } from 'react';
|
import { useCallback, useRef, useState } from 'react';
|
||||||
import { stringify } from 'urlon';
|
import { stringify } from 'urlon';
|
||||||
import type { embedConfigurations } from '../../constants/embeds';
|
import type { embedConfigurations } from '../../constants/embeds';
|
||||||
import { literals } from '../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../hooks/useLocale';
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
import { EmbedState, type EmbedStateStore } from '../../stores/embedState';
|
import { EmbedState, type EmbedStateStore } from '../../stores/embedState';
|
||||||
import { CopyButton } from '../CopyButton';
|
import { CopyButton } from '../CopyButton';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Flex, Text } from '@radix-ui/themes';
|
import { Flex, Text } from '@radix-ui/themes';
|
||||||
import fuzzysort from 'fuzzysort';
|
import fuzzysort from 'fuzzysort';
|
||||||
import { times } from 'lodash-es';
|
import { times } from 'lodash-es';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { literals } from '../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../hooks/useLocale';
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
import { GalleryEphemeral } from '../../stores/galleryEphemeral';
|
import { GalleryEphemeral } from '../../stores/galleryEphemeral';
|
||||||
import { GalleryCard } from './Card';
|
import { GalleryCard } from './Card';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Code, Flex, Heading, Text } from '@radix-ui/themes';
|
import { Code, Flex, Heading, Text } from '@radix-ui/themes';
|
||||||
import { resolveBranchName } from '../core/blitzkit/branches';
|
import { resolveBranchName } from '../core/blitzkit/branches';
|
||||||
import { getStrings } from '../core/i18n/getStrings';
|
import { getStrings } from '../core/i18n/getStrings';
|
||||||
import { literals } from '../core/i18n/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
|
|
||||||
const { locale } = Astro.params;
|
const { locale } = Astro.params;
|
||||||
const branchName = resolveBranchName(locale);
|
const branchName = resolveBranchName(locale);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { assertSecret } from '@blitzkit/core';
|
import { assertSecret } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { EyeOpenIcon } from '@radix-ui/react-icons';
|
import { EyeOpenIcon } from '@radix-ui/react-icons';
|
||||||
import { Box, Flex, Heading, Text } from '@radix-ui/themes';
|
import { Box, Flex, Heading, Text } from '@radix-ui/themes';
|
||||||
import { google } from 'googleapis';
|
import { google } from 'googleapis';
|
||||||
import { awaitableTankDefinitions } from '../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../core/awaitables/tankDefinitions';
|
||||||
import { literals } from '../core/i18n/literals';
|
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
LocaleProvider,
|
||||||
useLocale,
|
useLocale,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { formatCompact } from '@blitzkit/core';
|
import { formatCompact } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { InfoCircledIcon } from '@radix-ui/react-icons';
|
import { InfoCircledIcon } from '@radix-ui/react-icons';
|
||||||
import { Callout, Flex } from '@radix-ui/themes';
|
import { Callout, Flex } from '@radix-ui/themes';
|
||||||
import { awaitableAverageDefinitions } from '../../core/awaitables/averageDefinitions';
|
import { awaitableAverageDefinitions } from '../../core/awaitables/averageDefinitions';
|
||||||
import { awaitableDiscoveredIdsDefinitions } from '../../core/awaitables/discoveredIdsDefinitions';
|
import { awaitableDiscoveredIdsDefinitions } from '../../core/awaitables/discoveredIdsDefinitions';
|
||||||
import { literals } from '../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../hooks/useLocale';
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
import type { MaybeSkeletonComponentProps } from '../../types/maybeSkeletonComponentProps';
|
import type { MaybeSkeletonComponentProps } from '../../types/maybeSkeletonComponentProps';
|
||||||
import { InlineSkeleton } from '../InlineSkeleton';
|
import { InlineSkeleton } from '../InlineSkeleton';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
unionBoundingBox,
|
unionBoundingBox,
|
||||||
type TankDefinition,
|
type TankDefinition,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { Callout, Flex, Link, Text, type FlexProps } from '@radix-ui/themes';
|
import { Callout, Flex, Link, Text, type FlexProps } from '@radix-ui/themes';
|
||||||
import fuzzysort from 'fuzzysort';
|
import fuzzysort from 'fuzzysort';
|
||||||
@@ -16,7 +17,6 @@ import { awaitableTankDefinitions } from '../../core/awaitables/tankDefinitions'
|
|||||||
import { awaitableTankNames } from '../../core/awaitables/tankNames';
|
import { awaitableTankNames } from '../../core/awaitables/tankNames';
|
||||||
import { filterTank } from '../../core/blitzkit/filterTank';
|
import { filterTank } from '../../core/blitzkit/filterTank';
|
||||||
import { resolveReload } from '../../core/blitzkit/resolveReload';
|
import { resolveReload } from '../../core/blitzkit/resolveReload';
|
||||||
import { literals } from '../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../hooks/useLocale';
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
import { $tankFilters } from '../../stores/tankFilters';
|
import { $tankFilters } from '../../stores/tankFilters';
|
||||||
import { TankopediaPersistent } from '../../stores/tankopediaPersistent';
|
import { TankopediaPersistent } from '../../stores/tankopediaPersistent';
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { TIER_ROMAN_NUMERALS } from '@blitzkit/core';
|
import { TIER_ROMAN_NUMERALS } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Flex, Heading, SegmentedControl, Text } from '@radix-ui/themes';
|
import { Flex, Heading, SegmentedControl, Text } from '@radix-ui/themes';
|
||||||
import { literals } from '../../../../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../../../../hooks/useLocale';
|
import { useLocale } from '../../../../../../hooks/useLocale';
|
||||||
import { Duel } from '../../../../../../stores/duel';
|
import { Duel } from '../../../../../../stores/duel';
|
||||||
import {
|
import {
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,7 @@ import {
|
|||||||
isExplosive,
|
isExplosive,
|
||||||
resolvePenetrationCoefficient,
|
resolvePenetrationCoefficient,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { AccessibilityIcon, InfoCircledIcon } from '@radix-ui/react-icons';
|
import { AccessibilityIcon, InfoCircledIcon } from '@radix-ui/react-icons';
|
||||||
import {
|
import {
|
||||||
Flex,
|
Flex,
|
||||||
@@ -25,7 +26,6 @@ import { awaitableEquipmentDefinitions } from '../../../../../core/awaitables/eq
|
|||||||
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
|
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
|
||||||
import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits';
|
import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits';
|
||||||
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
|
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
|
||||||
import { literals } from '../../../../../core/i18n/literals';
|
|
||||||
import { useEquipment } from '../../../../../hooks/useEquipment';
|
import { useEquipment } from '../../../../../hooks/useEquipment';
|
||||||
import { useLocale } from '../../../../../hooks/useLocale';
|
import { useLocale } from '../../../../../hooks/useLocale';
|
||||||
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,5 @@
|
|||||||
import { imgur, ShellType } from '@blitzkit/core';
|
import { imgur, ShellType } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Flex,
|
Flex,
|
||||||
@@ -11,7 +12,6 @@ import {
|
|||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
import { type ChangeEvent } from 'react';
|
import { type ChangeEvent } from 'react';
|
||||||
import { literals } from '../../../../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../../../../hooks/useLocale';
|
import { useLocale } from '../../../../../../hooks/useLocale';
|
||||||
import { Duel } from '../../../../../../stores/duel';
|
import { Duel } from '../../../../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { EyeClosedIcon, EyeOpenIcon, ReloadIcon } from '@radix-ui/react-icons';
|
import { EyeClosedIcon, EyeOpenIcon, ReloadIcon } from '@radix-ui/react-icons';
|
||||||
import { Button, Checkbox, Flex, Text } from '@radix-ui/themes';
|
import { Button, Checkbox, Flex, Text } from '@radix-ui/themes';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
import { literals } from '../../../../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../../../../hooks/useLocale';
|
import { useLocale } from '../../../../../../hooks/useLocale';
|
||||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||||
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent';
|
import { TankopediaPersistent } from '../../../../../../stores/tankopediaPersistent';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
TIER_ROMAN_NUMERALS,
|
TIER_ROMAN_NUMERALS,
|
||||||
uniqueGuns,
|
uniqueGuns,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import {
|
import {
|
||||||
CameraIcon,
|
CameraIcon,
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
@@ -30,7 +31,6 @@ import {
|
|||||||
} from '@radix-ui/themes';
|
} from '@radix-ui/themes';
|
||||||
import { Suspense, useState, type RefObject } from 'react';
|
import { Suspense, useState, type RefObject } from 'react';
|
||||||
import { Pose, poseEvent } from '../../../../../core/blitzkit/pose';
|
import { Pose, poseEvent } from '../../../../../core/blitzkit/pose';
|
||||||
import { literals } from '../../../../../core/i18n/literals';
|
|
||||||
import { useEquipment } from '../../../../../hooks/useEquipment';
|
import { useEquipment } from '../../../../../hooks/useEquipment';
|
||||||
import { useFullScreen } from '../../../../../hooks/useFullScreen';
|
import { useFullScreen } from '../../../../../hooks/useFullScreen';
|
||||||
import { useFullscreenAvailability } from '../../../../../hooks/useFullscreenAvailability';
|
import { useFullscreenAvailability } from '../../../../../hooks/useFullscreenAvailability';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { asset, formatCompact, TIER_ROMAN_NUMERALS } from '@blitzkit/core';
|
import { asset, formatCompact, TIER_ROMAN_NUMERALS } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Box, Flex, Skeleton, Text } from '@radix-ui/themes';
|
import { Box, Flex, Skeleton, Text } from '@radix-ui/themes';
|
||||||
import { awaitableAverageDefinitions } from '../../../../core/awaitables/averageDefinitions';
|
import { awaitableAverageDefinitions } from '../../../../core/awaitables/averageDefinitions';
|
||||||
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
|
||||||
import { literals } from '../../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../../hooks/useLocale';
|
import { useLocale } from '../../../../hooks/useLocale';
|
||||||
import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral';
|
||||||
import type { MaybeSkeletonComponentProps } from '../../../../types/maybeSkeletonComponentProps';
|
import type { MaybeSkeletonComponentProps } from '../../../../types/maybeSkeletonComponentProps';
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { asset, imgur, TankType } from '@blitzkit/core';
|
import { asset, imgur, TankType } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { CaretLeftIcon, CaretRightIcon, PlusIcon } from '@radix-ui/react-icons';
|
import { CaretLeftIcon, CaretRightIcon, PlusIcon } from '@radix-ui/react-icons';
|
||||||
import { Flex, Heading, IconButton, ScrollArea, Text } from '@radix-ui/themes';
|
import { Flex, Heading, IconButton, ScrollArea, Text } from '@radix-ui/themes';
|
||||||
import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
|
import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { awaitableTankDefinitions } from '../../../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../../../core/awaitables/tankDefinitions';
|
||||||
import { literals } from '../../../core/i18n/literals';
|
|
||||||
import { useLocale } from '../../../hooks/useLocale';
|
import { useLocale } from '../../../hooks/useLocale';
|
||||||
import { Duel } from '../../../stores/duel';
|
import { Duel } from '../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { youtubers } from '@blitzkit/core';
|
import { youtubers } from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { Box, Flex, Heading, Link, Skeleton, Text } from '@radix-ui/themes';
|
import { Box, Flex, Heading, Link, Skeleton, Text } from '@radix-ui/themes';
|
||||||
import { awaitableReviews } from '../../core/awaitables/reviews';
|
import { awaitableReviews } from '../../core/awaitables/reviews';
|
||||||
import { literals } from '../../core/i18n/literals';
|
|
||||||
import { Var } from '../../core/radix/var';
|
import { Var } from '../../core/radix/var';
|
||||||
import { useLocale } from '../../hooks/useLocale';
|
import { useLocale } from '../../hooks/useLocale';
|
||||||
import { Duel } from '../../stores/duel';
|
import { Duel } from '../../stores/duel';
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
tierListTool,
|
tierListTool,
|
||||||
} from '../../constants/tools';
|
} from '../../constants/tools';
|
||||||
import { getStrings } from '../../core/i18n/getStrings';
|
import { getStrings } from '../../core/i18n/getStrings';
|
||||||
import { literals } from '../../core/i18n/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
|
|
||||||
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import { CalendarIcon } from '@radix-ui/react-icons';
|
import { CalendarIcon } from '@radix-ui/react-icons';
|
||||||
import { Callout, Flex } from '@radix-ui/themes';
|
import { Callout, Flex } from '@radix-ui/themes';
|
||||||
import { GalleryList, type Avatar } from '../../../../components/Gallery/List';
|
import { GalleryList, type Avatar } from '../../../../components/Gallery/List';
|
||||||
import { GallerySearch } from '../../../../components/Gallery/Search';
|
import { GallerySearch } from '../../../../components/Gallery/Search';
|
||||||
import { PageWrapper } from '../../../../components/PageWrapper';
|
import { PageWrapper } from '../../../../components/PageWrapper';
|
||||||
import { literals } from '../../../../core/i18n/literals';
|
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
LocaleProvider,
|
||||||
useLocale,
|
useLocale,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
type IndividualAccountInfo,
|
type IndividualAccountInfo,
|
||||||
type IndividualTankStats,
|
type IndividualTankStats,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import {
|
import {
|
||||||
ArrowDownIcon,
|
ArrowDownIcon,
|
||||||
MagnifyingGlassIcon,
|
MagnifyingGlassIcon,
|
||||||
@@ -38,7 +39,6 @@ import { StickyTableRoot } from '../../../../components/StickyTableRoot';
|
|||||||
import { TankRowHeaderCell } from '../../../../components/TankRowHeaderCell';
|
import { TankRowHeaderCell } from '../../../../components/TankRowHeaderCell';
|
||||||
import { awaitableAverageDefinitions } from '../../../../core/awaitables/averageDefinitions';
|
import { awaitableAverageDefinitions } from '../../../../core/awaitables/averageDefinitions';
|
||||||
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
|
||||||
import { literals } from '../../../../core/i18n/literals';
|
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
LocaleProvider,
|
||||||
useLocale,
|
useLocale,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n';
|
|||||||
import type { GetStaticPaths } from 'astro';
|
import type { GetStaticPaths } from 'astro';
|
||||||
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
|
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
|
||||||
import { getStrings } from '../../../../../core/i18n/getStrings';
|
import { getStrings } from '../../../../../core/i18n/getStrings';
|
||||||
import { literals } from '../../../../../core/i18n/literals';
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
import BaseLayout from '../../../../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../../../../layouts/BaseLayout.astro';
|
||||||
import { genericDefaultEquipmentMatrix } from '../../../../../stores/duel/constants';
|
import { genericDefaultEquipmentMatrix } from '../../../../../stores/duel/constants';
|
||||||
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
||||||
|
|||||||
Reference in new issue
Block a user