multi lang + subcommand support in help
All checks were successful
PR Check / lint-and-format (pull_request) Successful in 27s

This commit is contained in:
Mylloon 2024-11-02 01:32:09 +01:00
parent 8703be8cd9
commit 1a0a2ddb8a
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
2 changed files with 100 additions and 24 deletions

View file

@ -9,7 +9,12 @@ import {
import "../../modules/string";
import { getLocale, getLocalizations } from "../../utils/locales";
import { getFilename } from "../../utils/misc";
import { goodDescription, goodName } from "../../utils/commands/help";
import {
goodDescription,
goodName,
NameNotLocalized,
SubnameNotLocalized,
} from "../../utils/commands/help";
export default {
scope: () => [],
@ -99,28 +104,49 @@ export default {
});
}
// If a command is specified
// TODO: Check if the command exist in the context (guild)
// https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues/187
const command = client.commands.list.get(desired_command);
const error = `${loc.get("c_help3")} \`${desired_command}\``;
const [possible_command, possible_subcommand] = desired_command.split(" ");
const command = NameNotLocalized(client, possible_command);
if (!command) {
// Command don't exist
return interaction.reply({
content: `${loc.get("c_help3")} \`${desired_command}\``,
ephemeral: true,
});
return interaction.reply({ content: error, ephemeral: true });
}
const scope = client.commands.list.get(command.name)?.scope();
if (scope!.length > 0 && scope?.find((id) => id === interaction.guildId) === undefined) {
// Command not available for the current guild
return interaction.reply({ content: error, ephemeral: true });
}
let subcommand = undefined;
if (possible_subcommand) {
subcommand = SubnameNotLocalized(command, possible_subcommand);
} else {
subcommand = null;
}
if (!command || subcommand === undefined) {
// Sub/Command don't exist
return interaction.reply({ content: error, ephemeral: true });
}
// Loads the data according to the user's locals
const requestedName =
goodName(command, interaction.locale) +
(subcommand !== null ? " " + goodName(subcommand, interaction.locale) : "");
const requestedDesc = goodDescription(
subcommand !== null ? subcommand : command,
interaction.locale,
);
// Send information about the command
return interaction.reply({
embeds: [
new EmbedBuilder()
.setColor(Colors.Blurple)
.setTitle("`/" + goodName(command.data, interaction.locale) + "`")
.setDescription(
// Loads the description according to the user's locals
goodDescription(command.data, interaction.locale),
),
.setTitle("`/" + requestedName + "`")
.setDescription(requestedDesc),
],
});
},

View file

@ -1,4 +1,12 @@
import { APIApplicationCommandSubcommandOption, Locale, SlashCommandBuilder } from "discord.js";
import {
APIApplicationCommandSubcommandOption,
ApplicationCommandOptionType,
Client,
Locale,
SlashCommandBuilder,
} from "discord.js";
type Data = SlashCommandBuilder | APIApplicationCommandSubcommandOption;
/**
* Find the name of the command, trying to get the correct locale
@ -6,10 +14,8 @@ import { APIApplicationCommandSubcommandOption, Locale, SlashCommandBuilder } fr
* @param locale Locale wanted
* @returns Command's name
*/
export const goodName = (
data: SlashCommandBuilder | APIApplicationCommandSubcommandOption,
locale: Locale,
) => data.name_localizations?.[locale] ?? data.name;
export const goodName = (data: Data, locale: Locale) =>
data.name_localizations?.[locale] ?? data.name;
/**
* Find the description of the command, trying to get the correct locale
@ -17,7 +23,51 @@ export const goodName = (
* @param locale Locale wanted
* @returns Command's description
*/
export const goodDescription = (
data: SlashCommandBuilder | APIApplicationCommandSubcommandOption,
locale: Locale,
) => data.description_localizations?.[locale] ?? data.description;
export const goodDescription = (data: Data, locale: Locale) =>
data.description_localizations?.[locale] ?? data.description;
/**
* Aux function for Sub/NameNotLocalized
* @param cmd data
* @param command command researched
* @returns if we found or not the researched command
*/
const filterLocalizations = (cmd: Data, command: string) => {
let res = false;
for (const key in cmd?.name_localizations) {
res = res || cmd.name_localizations?.[key as Locale] === command;
}
return res;
};
/**
* Find a command based on any string, localized or not
* @param command string
* @returns the not localized corresponding string's command name
*/
export const NameNotLocalized = (client: Client, command: string): SlashCommandBuilder | null => {
const list = client.commands.list.map((cmd) => cmd.data);
return (
list.find((cmd) => cmd.name === command) ||
list.filter((cmd) => filterLocalizations(cmd, command))[0]
);
};
/**
* Find a subcommand of a command based on any string, localized or not
* @param parent command of the subcommand
* @param command string
* @returns the not localized corresponding string's subcommand name
*/
export const SubnameNotLocalized = (parent: SlashCommandBuilder, command: string) => {
const list = parent
?.toJSON()
.options?.filter((option) => option.type === ApplicationCommandOptionType.Subcommand);
return (
list?.find((cmd) => cmd?.name === command) ||
list?.filter((cmd) => filterLocalizations(cmd, command))[0]
);
};