feat: partially translated /about

This commit is contained in:
TrèsAbhi committed 2024-03-05 09:59:46 -06:00
1 parent 8e35e0d6d9
commit db7c865c76
5 files changed
+104 -43

No files matched your search

+32 -37
View File
@@ -1,52 +1,33 @@
import { import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
SlashCommandBuilder,
SlashCommandSubcommandsOnlyBuilder,
} from 'discord.js';
import { translator } from '../core/localization/translator'; import { translator } from '../core/localization/translator';
import { COMMANDS_RAW, CommandRegistry } from '../events/interactionCreate'; import { COMMANDS_RAW, CommandRegistry } from '../events/interactionCreate';
const RAW_PATH = `https://raw.githubusercontent.com/tresabhi/blitzkrieg/main/docs/`; const subcommands = [
const DOCS = { 'embeds',
'introduction',
'invite',
'timezones',
'creators',
] as const;
type Subcommand = (typeof subcommands)[number];
const DOCS: Record<Subcommand, string> = {
embeds: 'guide/embeds', embeds: 'guide/embeds',
introduction: 'guide/introduction', introduction: 'guide/introduction',
invite: 'guide/invite', invite: 'guide/invite',
timezones: 'guide/timezones', timezones: 'guide/timezones',
creators: 'guide/creators', creators: 'guide/creators',
}; };
const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = {
embeds: 'How embeds work',
introduction: 'About the bot',
invite: 'How to invite the bot',
timezones: 'How Blitzkrieg infers and uses your timezone',
creators: 'Who created the bot',
};
function addDocsSubcommands(option: SlashCommandSubcommandsOnlyBuilder) {
Object.entries(DOC_DESCRIPTIONS).forEach(([key, value]) => {
option.addSubcommand((sub) => sub.setName(key).setDescription(value));
});
return option;
}
export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => { export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
resolve({ resolve({
inProduction: true, inProduction: true,
inPublic: true, inPublic: true,
command: addDocsSubcommands( command: await createLocalizedCommand('about', [
new SlashCommandBuilder() { subcommand: 'commands' },
.setName('about') ...subcommands.map((subcommand) => ({ subcommand })),
.setNameLocalizations({ ]),
// "es-ES":
})
.setDescription('All the info you need about the bot')
.addSubcommand((option) =>
option
.setName('commands')
.setDescription('List of all commands and their descriptions'),
),
),
async handler(interaction) { async handler(interaction) {
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
@@ -57,15 +38,29 @@ export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
await Promise.all(COMMANDS_RAW) await Promise.all(COMMANDS_RAW)
) )
.filter((registry) => registry.inPublic && registry.inProduction) .filter((registry) => registry.inPublic && registry.inProduction)
.sort((a, b) => (a.command.name < b.command.name ? -1 : 1)) .sort((a, b) =>
(a.command.name_localizations?.[interaction.locale] ??
a.command.name) <
(b.command.name_localizations?.[interaction.locale] ??
b.command.name)
? -1
: 1,
)
.map( .map(
(registry) => (registry) =>
`- \`/${registry.command.name}\`: ${registry.command.description}`, `- \`/${
registry.command.name_localizations?.[interaction.locale] ??
registry.command.name
}\`: ${
registry.command.description_localizations?.[
interaction.locale
] ?? registry.command.description
}`,
) )
.join('\n')}`; .join('\n')}`;
} }
const url = `${RAW_PATH}${DOCS[subcommand as keyof typeof DOCS]}.md`; const url = `https://raw.githubusercontent.com/tresabhi/blitzkrieg/main/docs/${DOCS[subcommand as Subcommand]}.md`;
const content = fetch(url).then((response) => response.text()); const content = fetch(url).then((response) => response.text());
return content; return content;
@@ -0,0 +1,48 @@
import { Locale, SlashCommandBuilder } from 'discord.js';
import { translator } from '../localization/translator';
import { localizationObject } from './localizationObject';
interface CreateLocalizedCommandSubcommand {
subcommand: string;
}
export async function createLocalizedCommand(
command: string,
subcommands?: CreateLocalizedCommandSubcommand[],
) {
const { translate } = await translator(Locale.EnglishUS);
const slashCommand = new SlashCommandBuilder()
.setName(command)
.setNameLocalizations(await localizationObject(`bot.commands.${command}`))
.setDescription(translate(`bot.commands.${command}.description`))
.setDescriptionLocalizations(
await localizationObject(`bot.commands.${command}.description`),
);
if (subcommands) {
await Promise.all(
subcommands.map(async ({ subcommand }) => {
const subcommandNameLocalizations = await localizationObject(
`bot.commands.${command}.subcommands.${subcommand}`,
);
const subcommandDescriptionLocalizations = await localizationObject(
`bot.commands.${command}.subcommands.${subcommand}.description`,
);
slashCommand.addSubcommand((option) =>
option
.setName(subcommand)
.setNameLocalizations(subcommandNameLocalizations)
.setDescription(
translate(
`bot.commands.${command}.subcommands.${subcommand}.description`,
),
)
.setDescriptionLocalizations(subcommandDescriptionLocalizations),
);
}),
);
}
return slashCommand;
}
+17
View File
@@ -0,0 +1,17 @@
import { Locale } from 'discord.js';
import { locales } from '../localization/strings';
import { translator } from '../localization/translator';
export async function localizationObject(path: string) {
return (
await Promise.all(locales.map(async (locale) => await translator(locale)))
).reduce<Partial<Record<Locale, string>>>(
(localizations, { locale, translate }) => {
return {
...localizations,
[locale]: translate(path),
};
},
{},
);
}
+3 -3
View File
@@ -1,6 +1,6 @@
import { Locale } from 'discord.js'; import { Locale } from 'discord.js';
const LOCALES: Locale[number][] = ['en-US', 'es-ES']; export const locales: Locale[] = [Locale.EnglishUS, Locale.SpanishES];
export type TranslationFragmentTree = { export type TranslationFragmentTree = {
[key: string]: TranslationFragment; [key: string]: TranslationFragment;
@@ -10,7 +10,7 @@ export type TranslationFragmentTree = {
export type TranslationFragment = string | TranslationFragmentTree; export type TranslationFragment = string | TranslationFragmentTree;
export const translations = Promise.all( export const translations = Promise.all(
LOCALES.map(async (locale) => ({ locales.map(async (locale) => ({
locale, locale,
translations: await import(`../../lang/${locale}.json`), translations: await import(`../../lang/${locale}.json`),
})), })),
@@ -22,5 +22,5 @@ export const translations = Promise.all(
[locale]: translations, [locale]: translations,
}), }),
{}, {},
) as Record<Locale[number], TranslationFragment>, ) as Record<Locale, TranslationFragment>,
); );
+4 -3
View File
@@ -1,7 +1,8 @@
import { Locale } from 'discord.js'; import { Locale } from 'discord.js';
import { translations } from './strings'; import { locales, translations } from './strings';
export async function translator(locale: Locale) { export async function translator(localeRaw: Locale) {
const locale = locales.includes(localeRaw) ? localeRaw : Locale.EnglishUS;
const strings = (await translations)[locale]; const strings = (await translations)[locale];
function translate(path: string) { function translate(path: string) {
@@ -45,5 +46,5 @@ export async function translator(locale: Locale) {
.join(''); .join('');
} }
return { translate, t }; return { locale, translate, t };
} }