From 704bbe374c98342631e74dbba302c1455f41523b Mon Sep 17 00:00:00 2001 From: TrisTOON <36267812+TrisTOON@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:57:16 +0200 Subject: [PATCH 1/2] Splits the chat subcommands into their own modules --- src/commands/chat.ts | 367 +++--------------------------------- src/commands/chat/attach.ts | 163 ++++++++++++++++ src/commands/chat/detach.ts | 159 ++++++++++++++++ src/commands/chat/patch.ts | 109 +++++++++++ src/commands/chat/post.ts | 153 +++++++++++++++ src/compilations/chat.ts | 32 +++- src/definitions.ts | 8 +- src/definitions/chat.json | 32 +++- src/dependencies/chat.d.ts | 35 +++- 9 files changed, 692 insertions(+), 366 deletions(-) create mode 100644 src/commands/chat/attach.ts create mode 100644 src/commands/chat/detach.ts create mode 100644 src/commands/chat/patch.ts create mode 100644 src/commands/chat/post.ts diff --git a/src/commands/chat.ts b/src/commands/chat.ts index fb07ceb..a8cc5fb 100644 --- a/src/commands/chat.ts +++ b/src/commands/chat.ts @@ -3,7 +3,6 @@ import type { ChatInputCommandInteraction, GuildBasedChannel, Message, - ModalSubmitInteraction, ThreadChannel, } from "discord.js"; import type Command from "../commands.js"; @@ -13,14 +12,12 @@ import type {Chat as ChatDefinition} from "../definitions.js"; import type {Chat as ChatDependency} from "../dependencies.js"; import type {Locale, Localized} from "../utils/string.js"; import { - ApplicationCommandOptionType, - ApplicationCommandType, ChannelType, - ComponentType, - TextInputStyle, - escapeMarkdown, } from "discord.js"; -import {patch as patchCommand} from "../commands.js"; +import attachSubCommand from "./chat/attach.js"; +import detachSubCommand from "./chat/detach.js"; +import patchSubCommand from "./chat/patch.js"; +import postSubCommand from "./chat/post.js"; import {chat as chatCompilation} from "../compilations.js"; import {chat as chatDefinition} from "../definitions.js"; import {composeAll, localize, resolve} from "../utils/string.js"; @@ -29,35 +26,20 @@ const { commandName, commandDescription, postSubCommandName, - postSubCommandDescription, patchSubCommandName, - patchSubCommandDescription, attachSubCommandName, - attachSubCommandDescription, detachSubCommandName, - detachSubCommandDescription, channelOptionName, - channelOptionDescription, messageOptionName, - messageOptionDescription, - contentOptionName, - contentOptionDescription, + // contentOptionName, positionOptionName, - positionOptionDescription, attachmentOptionName, - attachmentOptionDescription, }: ChatDefinition = chatDefinition; const { help: helpLocalizations, - reply: replyLocalizations, - bareReply: bareReplyLocalizations, noChannelReply: noChannelReplyLocalizations, noMessageReply: noMessageReplyLocalizations, - noPositionReply: noPositionReplyLocalizations, noInteractionReply: noInteractionReplyLocalizations, - noContentOrAttachmentReply: noContentOrAttachmentReplyLocalizations, - noPatchPermissionReply: noPatchPermissionReplyLocalizations, - noPostPermissionReply: noPostPermissionReplyLocalizations, }: ChatCompilation = chatCompilation; const messagePattern: RegExp = /^(?:0|[1-9]\d*)$/; const chatCommand: Command = { @@ -67,154 +49,10 @@ const chatCommand: Command = { description: commandDescription["en-US"], descriptionLocalizations: commandDescription, options: [ - { - type: ApplicationCommandOptionType.Subcommand, - name: postSubCommandName, - description: postSubCommandDescription["en-US"], - descriptionLocalizations: postSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - ], - }, - { - type: ApplicationCommandOptionType.Subcommand, - name: patchSubCommandName, - description: patchSubCommandDescription["en-US"], - descriptionLocalizations: patchSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - { - type: ApplicationCommandOptionType.String, - name: messageOptionName, - description: messageOptionDescription["en-US"], - descriptionLocalizations: messageOptionDescription, - required: true, - }, - ], - }, - { - type: ApplicationCommandOptionType.Subcommand, - name: attachSubCommandName, - description: attachSubCommandDescription["en-US"], - descriptionLocalizations: attachSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - { - type: ApplicationCommandOptionType.String, - name: messageOptionName, - description: messageOptionDescription["en-US"], - descriptionLocalizations: messageOptionDescription, - required: true, - }, - { - type: ApplicationCommandOptionType.Integer, - name: positionOptionName, - description: positionOptionDescription["en-US"], - descriptionLocalizations: positionOptionDescription, - required: true, - minValue: 0, - }, - { - type: ApplicationCommandOptionType.Attachment, - name: attachmentOptionName, - description: attachmentOptionDescription["en-US"], - descriptionLocalizations: attachmentOptionDescription, - required: true, - }, - ], - }, - { - type: ApplicationCommandOptionType.Subcommand, - name: detachSubCommandName, - description: detachSubCommandDescription["en-US"], - descriptionLocalizations: detachSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - { - type: ApplicationCommandOptionType.String, - name: messageOptionName, - description: messageOptionDescription["en-US"], - descriptionLocalizations: messageOptionDescription, - required: true, - }, - { - type: ApplicationCommandOptionType.Integer, - name: positionOptionName, - description: positionOptionDescription["en-US"], - descriptionLocalizations: positionOptionDescription, - required: true, - minValue: 0, - }, - ], - }, + postSubCommand.register(), + patchSubCommand.register(), + attachSubCommand.register(), + detachSubCommand.register(), ], defaultMemberPermissions: [], dmPermission: false, @@ -246,64 +84,7 @@ const chatCommand: Command = { return; } if (subCommandName === postSubCommandName) { - await interaction.showModal({ - customId: interaction.id, - title: contentOptionDescription[resolvedLocale], - components: [ - { - type: ComponentType.ActionRow, - components: [ - { - type: ComponentType.TextInput, - style: TextInputStyle.Paragraph, - customId: contentOptionName, - label: contentOptionName, - required: true, - value: "", - minLength: 0, - maxLength: 2000, - }, - ], - }, - ], - }); - const modalSubmitInteraction: ModalSubmitInteraction<"cached"> = await interaction.awaitModalSubmit({ - filter: (modalSubmitInteraction: ModalSubmitInteraction): boolean => { - return modalSubmitInteraction.customId === interaction.id; - }, - time: 900000, - }); - const content: string = modalSubmitInteraction.fields.getTextInputValue(contentOptionName); - try { - if (channel.isThreadOnly()) { - const name: string = "New post"; - await channel.threads.create({ - name, - message: {content}, - }); - } else { - await channel.send({content}); - } - } catch { - await modalSubmitInteraction.reply({ - content: noPostPermissionReplyLocalizations[resolvedLocale]({}), - ephemeral: true, - }); - return; - } - function formatMessage(locale: Locale): string { - return bareReplyLocalizations[locale]({}); - } - await modalSubmitInteraction.reply({ - content: formatMessage("en-US"), - }); - if (resolvedLocale === "en-US") { - return; - } - await modalSubmitInteraction.followUp({ - content: formatMessage(resolvedLocale), - ephemeral: true, - }); + await postSubCommand.interact(interaction, channel); return; } const identifier: string = options.getString(messageOptionName, true); @@ -349,136 +130,34 @@ const chatCommand: Command = { return; } if (subCommandName === patchSubCommandName) { - await patchCommand.interact(Object.assign(Object.create(interaction), { - commandType: ApplicationCommandType.Message, - get targetMessage(): Message { - return message; - }, - })); + await patchSubCommand.interact(interaction, message); return; } + const position: number = options.getInteger(positionOptionName, true); if (subCommandName === attachSubCommandName) { - const content: string = message.content; - const attachments: Attachment[] = [...message.attachments.values()]; - const position: number = options.getInteger(positionOptionName, true); - if (position < 0 || position >= attachments.length + 1) { - const max: number = attachments.length; - await interaction.reply({ - content: noPositionReplyLocalizations[resolvedLocale]({ - max: (): string => { - return escapeMarkdown(`${max}`); - }, - }), - ephemeral: true, - }); - return; - } - const attachment: Attachment = options.getAttachment(attachmentOptionName, true); - const files: Attachment[] = [...attachments.slice(0, position), attachment, ...attachments.slice(position)]; - try { - await message.edit({content, files}); - } catch { - await interaction.reply({ - content: noPatchPermissionReplyLocalizations[resolvedLocale]({}), - ephemeral: true, - }); - return; - } - function formatMessage(locale: Locale): string { - return replyLocalizations[locale]({}); - } - await interaction.reply({ - content: formatMessage("en-US"), - ephemeral: true, - }); - if (resolvedLocale === "en-US") { - return; - } - await interaction.followUp({ - content: formatMessage(resolvedLocale), - ephemeral: true, - }); + await attachSubCommand.interact(interaction, message, position); return; } + const attachment: Attachment = options.getAttachment(attachmentOptionName, true); if (subCommandName === detachSubCommandName) { - const content: string = message.content; - const attachments: Attachment[] = [...message.attachments.values()]; - const position: number = options.getInteger(positionOptionName, true); - if (position < 0 || position >= attachments.length) { - const max: number = attachments.length - 1; - await interaction.reply({ - content: noPositionReplyLocalizations[resolvedLocale]({ - max: (): string => { - return escapeMarkdown(`${max}`); - }, - }), - ephemeral: true, - }); - return; - } - if (content === "" && attachments.length === 1) { - await interaction.reply({ - content: noContentOrAttachmentReplyLocalizations[resolvedLocale]({}), - ephemeral: true, - }); - return; - } - const files: Attachment[] = [...attachments.slice(0, position), ...attachments.slice(position + 1)]; - try { - await message.edit({content, files}); - } catch { - await interaction.reply({ - content: noPatchPermissionReplyLocalizations[resolvedLocale]({}), - ephemeral: true, - }); - return; - } - function formatMessage(locale: Locale): string { - return replyLocalizations[locale]({}); - } - await interaction.reply({ - content: formatMessage("en-US"), - ephemeral: true, - }); - if (resolvedLocale === "en-US") { - return; - } - await interaction.followUp({ - content: formatMessage(resolvedLocale), - ephemeral: true, - }); + await detachSubCommand.interact(interaction, message, position, attachment); return; } }, describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { return composeAll(helpLocalizations, localize((locale: Locale): HelpGroups => { return { - postSubCommandMention: (): string => { - return ``; - }, - patchSubCommandMention: (): string => { - return ``; - }, - attachSubCommandMention: (): string => { - return ``; - }, - detachSubCommandMention: (): string => { - return ``; - }, - channelOptionDescription: (): string => { - return channelOptionDescription[locale]; - }, - messageOptionDescription: (): string => { - return messageOptionDescription[locale]; + postSubCommandHelp: (): string => { + return postSubCommand.describe(applicationCommand)[locale]({}); }, - contentOptionDescription: (): string => { - return contentOptionDescription[locale]; + patchSubCommandHelp: (): string => { + return patchSubCommand.describe(applicationCommand)[locale]({}); }, - positionOptionDescription: (): string => { - return positionOptionDescription[locale]; + attachSubCommandHelp: (): string => { + return attachSubCommand.describe(applicationCommand)[locale]({}); }, - attachmentOptionDescription: (): string => { - return attachmentOptionDescription[locale]; + detachSubCommandHelp: (): string => { + return detachSubCommand.describe(applicationCommand)[locale]({}); }, }; })); diff --git a/src/commands/chat/attach.ts b/src/commands/chat/attach.ts new file mode 100644 index 0000000..a970b18 --- /dev/null +++ b/src/commands/chat/attach.ts @@ -0,0 +1,163 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + Attachment, + ChatInputCommandInteraction, + Message, +} from "discord.js"; +import type {Chat as ChatCompilation} from "../../compilations.js"; +import type {Chat as ChatDefinition} from "../../definitions.js"; +import type {Chat as ChatDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ChannelType, + escapeMarkdown, +} from "discord.js"; +import {chat as chatCompilation} from "../../compilations.js"; +import {chat as chatDefinition} from "../../definitions.js"; +import {composeAll, localize, resolve} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type AttachHelpGroups = ChatDependency["attachHelp"]; +const { + commandName, + attachSubCommandName, + attachSubCommandDescription, + channelOptionName, + channelOptionDescription, + messageOptionName, + messageOptionDescription, + positionOptionName, + positionOptionDescription, + attachmentOptionName, + attachmentOptionDescription, +}: ChatDefinition = chatDefinition; +const { + attachHelp: attachHelpLocalizations, + patchReply: patchReplyLocalizations, + noPositionReply: noPositionReplyLocalizations, + noPatchPermissionReply: noPatchPermissionReplyLocalizations, +}: ChatCompilation = chatCompilation; +const attachSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: attachSubCommandName, + description: attachSubCommandDescription["en-US"], + descriptionLocalizations: attachSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + { + type: ApplicationCommandOptionType.String, + name: messageOptionName, + description: messageOptionDescription["en-US"], + descriptionLocalizations: messageOptionDescription, + required: true, + }, + { + type: ApplicationCommandOptionType.Integer, + name: positionOptionName, + description: positionOptionDescription["en-US"], + descriptionLocalizations: positionOptionDescription, + required: true, + minValue: 0, + }, + { + type: ApplicationCommandOptionType.Attachment, + name: attachmentOptionName, + description: attachmentOptionDescription["en-US"], + descriptionLocalizations: attachmentOptionDescription, + required: true, + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, message: Message, position: number, attachment: Attachment): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + const {locale}: ChatInputCommandInteraction<"cached"> = interaction; + const resolvedLocale: Locale = resolve(locale); + const content: string = message.content; + const attachments: Attachment[] = [...message.attachments.values()]; + if (position < 0 || position >= attachments.length + 1) { + const max: number = attachments.length; + await interaction.reply({ + content: noPositionReplyLocalizations[resolvedLocale]({ + max: (): string => { + return escapeMarkdown(`${max}`); + }, + }), + ephemeral: true, + }); + return; + } + const files: Attachment[] = [...attachments.slice(0, position), attachment, ...attachments.slice(position)]; + try { + await message.edit({content, files}); + } catch { + await interaction.reply({ + content: noPatchPermissionReplyLocalizations[resolvedLocale]({}), + ephemeral: true, + }); + return; + } + function formatMessage(locale: Locale): string { + return patchReplyLocalizations[locale]({}); + } + await interaction.reply({ + content: formatMessage("en-US"), + ephemeral: true, + }); + if (resolvedLocale === "en-US") { + return; + } + await interaction.followUp({ + content: formatMessage(resolvedLocale), + ephemeral: true, + }); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(attachHelpLocalizations, localize((locale: Locale): AttachHelpGroups => { + return { + attachSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + messageOptionDescription: (): string => { + return messageOptionDescription[locale]; + }, + positionOptionDescription: (): string => { + return positionOptionDescription[locale]; + }, + attachmentOptionDescription: (): string => { + return attachmentOptionDescription[locale]; + }, + }; + })); + }, +}; +export default attachSubCommand; diff --git a/src/commands/chat/detach.ts b/src/commands/chat/detach.ts new file mode 100644 index 0000000..059b301 --- /dev/null +++ b/src/commands/chat/detach.ts @@ -0,0 +1,159 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + Attachment, + ChatInputCommandInteraction, + Message, +} from "discord.js"; +import type {Chat as ChatCompilation} from "../../compilations.js"; +import type {Chat as ChatDefinition} from "../../definitions.js"; +import type {Chat as ChatDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ChannelType, + escapeMarkdown, +} from "discord.js"; +import {chat as chatCompilation} from "../../compilations.js"; +import {chat as chatDefinition} from "../../definitions.js"; +import {composeAll, localize, resolve} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type DetachHelpGroups = ChatDependency["detachHelp"]; +const { + commandName, + detachSubCommandName, + detachSubCommandDescription, + channelOptionName, + channelOptionDescription, + messageOptionName, + messageOptionDescription, + positionOptionName, + positionOptionDescription, +}: ChatDefinition = chatDefinition; +const { + detachHelp: detachHelpLocalizations, + patchReply: patchReplyLocalizations, + noPositionReply: noPositionReplyLocalizations, + noContentOrAttachmentReply: noContentOrAttachmentReplyLocalizations, + noPatchPermissionReply: noPatchPermissionReplyLocalizations, +}: ChatCompilation = chatCompilation; +const detachSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: detachSubCommandName, + description: detachSubCommandDescription["en-US"], + descriptionLocalizations: detachSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + { + type: ApplicationCommandOptionType.String, + name: messageOptionName, + description: messageOptionDescription["en-US"], + descriptionLocalizations: messageOptionDescription, + required: true, + }, + { + type: ApplicationCommandOptionType.Integer, + name: positionOptionName, + description: positionOptionDescription["en-US"], + descriptionLocalizations: positionOptionDescription, + required: true, + minValue: 0, + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, message: Message, position: number): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + const {locale}: ChatInputCommandInteraction<"cached"> = interaction; + const resolvedLocale: Locale = resolve(locale); + const content: string = message.content; + const attachments: Attachment[] = [...message.attachments.values()]; + if (position < 0 || position >= attachments.length) { + const max: number = attachments.length - 1; + await interaction.reply({ + content: noPositionReplyLocalizations[resolvedLocale]({ + max: (): string => { + return escapeMarkdown(`${max}`); + }, + }), + ephemeral: true, + }); + return; + } + if (content === "" && attachments.length === 1) { + await interaction.reply({ + content: noContentOrAttachmentReplyLocalizations[resolvedLocale]({}), + ephemeral: true, + }); + return; + } + const files: Attachment[] = [...attachments.slice(0, position), ...attachments.slice(position + 1)]; + try { + await message.edit({content, files}); + } catch { + await interaction.reply({ + content: noPatchPermissionReplyLocalizations[resolvedLocale]({}), + ephemeral: true, + }); + return; + } + function formatMessage(locale: Locale): string { + return patchReplyLocalizations[locale]({}); + } + await interaction.reply({ + content: formatMessage("en-US"), + ephemeral: true, + }); + if (resolvedLocale === "en-US") { + return; + } + await interaction.followUp({ + content: formatMessage(resolvedLocale), + ephemeral: true, + }); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(detachHelpLocalizations, localize((locale: Locale): DetachHelpGroups => { + return { + detachSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + messageOptionDescription: (): string => { + return messageOptionDescription[locale]; + }, + positionOptionDescription: (): string => { + return positionOptionDescription[locale]; + }, + }; + })); + }, +}; +export default detachSubCommand; diff --git a/src/commands/chat/patch.ts b/src/commands/chat/patch.ts new file mode 100644 index 0000000..49b391c --- /dev/null +++ b/src/commands/chat/patch.ts @@ -0,0 +1,109 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + ChatInputCommandInteraction, + Message, +} from "discord.js"; +import type {Chat as ChatCompilation} from "../../compilations.js"; +import type {Chat as ChatDefinition} from "../../definitions.js"; +import type {Chat as ChatDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ApplicationCommandType, + ChannelType, +} from "discord.js"; +import {patch as patchCommand} from "../../commands.js"; +import {chat as chatCompilation} from "../../compilations.js"; +import {chat as chatDefinition} from "../../definitions.js"; +import {composeAll, localize} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type PatchHelpGroups = ChatDependency["patchHelp"]; +const { + commandName, + patchSubCommandName, + patchSubCommandDescription, + channelOptionName, + channelOptionDescription, + messageOptionName, + messageOptionDescription, + // contentOptionName, + contentOptionDescription, +}: ChatDefinition = chatDefinition; +const { + patchHelp: patchHelpLocalizations, + // patchReply: patchReplyLocalizations, + // noContentOrAttachmentReply: noContentOrAttachmentReplyLocalizations, + // noPatchPermissionReply: noPatchPermissionReplyLocalizations, +}: ChatCompilation = chatCompilation; +const patchSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: patchSubCommandName, + description: patchSubCommandDescription["en-US"], + descriptionLocalizations: patchSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + { + type: ApplicationCommandOptionType.String, + name: messageOptionName, + description: messageOptionDescription["en-US"], + descriptionLocalizations: messageOptionDescription, + required: true, + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, message: Message): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + await patchCommand.interact(Object.assign(Object.create(interaction), { + commandType: ApplicationCommandType.Message, + get targetMessage(): Message { + return message; + }, + })); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(patchHelpLocalizations, localize((locale: Locale): PatchHelpGroups => { + return { + patchSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + messageOptionDescription: (): string => { + return messageOptionDescription[locale]; + }, + contentOptionDescription: (): string => { + return contentOptionDescription[locale]; + }, + }; + })); + }, +}; +export default patchSubCommand; diff --git a/src/commands/chat/post.ts b/src/commands/chat/post.ts new file mode 100644 index 0000000..4538212 --- /dev/null +++ b/src/commands/chat/post.ts @@ -0,0 +1,153 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + CategoryChannel, + ChatInputCommandInteraction, + GuildBasedChannel, + ModalSubmitInteraction, +} from "discord.js"; +import type {Chat as ChatCompilation} from "../../compilations.js"; +import type {Chat as ChatDefinition} from "../../definitions.js"; +import type {Chat as ChatDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ChannelType, + ComponentType, + TextInputStyle, +} from "discord.js"; +import {chat as chatCompilation} from "../../compilations.js"; +import {chat as chatDefinition} from "../../definitions.js"; +import {composeAll, localize, resolve} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type PostHelpGroups = ChatDependency["postHelp"]; +const { + commandName, + postSubCommandName, + postSubCommandDescription, + channelOptionName, + channelOptionDescription, + contentOptionName, + contentOptionDescription, +}: ChatDefinition = chatDefinition; +const { + postHelp: postHelpLocalizations, + postReply: postReplyLocalizations, + noPostPermissionReply: noPostPermissionReplyLocalizations, +}: ChatCompilation = chatCompilation; +const postSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: postSubCommandName, + description: postSubCommandDescription["en-US"], + descriptionLocalizations: postSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, channel: Exclude): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + const {locale}: ChatInputCommandInteraction<"cached"> = interaction; + const resolvedLocale: Locale = resolve(locale); + await interaction.showModal({ + customId: interaction.id, + title: contentOptionDescription[resolvedLocale], + components: [ + { + type: ComponentType.ActionRow, + components: [ + { + type: ComponentType.TextInput, + style: TextInputStyle.Paragraph, + customId: contentOptionName, + label: contentOptionName, + required: true, + value: "", + minLength: 0, + maxLength: 2000, + }, + ], + }, + ], + }); + const modalSubmitInteraction: ModalSubmitInteraction<"cached"> = await interaction.awaitModalSubmit({ + filter: (modalSubmitInteraction: ModalSubmitInteraction): boolean => { + return modalSubmitInteraction.customId === interaction.id; + }, + time: 900000, + }); + const content: string = modalSubmitInteraction.fields.getTextInputValue(contentOptionName); + try { + if (channel.isThreadOnly()) { + const name: string = "New post"; + await channel.threads.create({ + name, + message: {content}, + }); + } else { + await channel.send({content}); + } + } catch { + await modalSubmitInteraction.reply({ + content: noPostPermissionReplyLocalizations[resolvedLocale]({}), + ephemeral: true, + }); + return; + } + function formatMessage(locale: Locale): string { + return postReplyLocalizations[locale]({}); + } + await modalSubmitInteraction.reply({ + content: formatMessage("en-US"), + ephemeral: true, + }); + if (resolvedLocale === "en-US") { + return; + } + await modalSubmitInteraction.followUp({ + content: formatMessage(resolvedLocale), + ephemeral: true, + }); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(postHelpLocalizations, localize((locale: Locale): PostHelpGroups => { + return { + postSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + contentOptionDescription: (): string => { + return contentOptionDescription[locale]; + }, + }; + })); + }, +}; +export default postSubCommand; diff --git a/src/compilations/chat.ts b/src/compilations/chat.ts index 752951f..3315db0 100644 --- a/src/compilations/chat.ts +++ b/src/compilations/chat.ts @@ -3,8 +3,12 @@ import type {Localized} from "../utils/string.js"; import {chat} from "../definitions.js"; import {compileAll} from "../utils/string.js"; type HelpLocalizations = Localized<(groups: Chat["help"]) => string>; -type ReplyLocalizations = Localized<(groups: Chat["reply"]) => string>; -type BareReplyLocalizations = Localized<(groups: Chat["bareReply"]) => string>; +type PostHelpLocalizations = Localized<(groups: Chat["postHelp"]) => string>; +type PatchHelpLocalizations = Localized<(groups: Chat["patchHelp"]) => string>; +type AttachHelpLocalizations = Localized<(groups: Chat["attachHelp"]) => string>; +type DetachHelpLocalizations = Localized<(groups: Chat["detachHelp"]) => string>; +type PostReplyLocalizations = Localized<(groups: Chat["postReply"]) => string>; +type PatchReplyLocalizations = Localized<(groups: Chat["patchReply"]) => string>; type NoChannelReplyLocalizations = Localized<(groups: Chat["noChannelReply"]) => string>; type NoMessageReplyLocalizations = Localized<(groups: Chat["noMessageReply"]) => string>; type NoPositionReplyLocalizations = Localized<(groups: Chat["noPositionReply"]) => string>; @@ -14,8 +18,12 @@ type NoPatchPermissionReplyLocalizations = Localized<(groups: Chat["noPatchPermi type NoPostPermissionReplyLocalizations = Localized<(groups: Chat["noPostPermissionReply"]) => string>; type ChatCompilation = { help: HelpLocalizations, - reply: ReplyLocalizations, - bareReply: BareReplyLocalizations, + postHelp: PostHelpLocalizations, + patchHelp: PatchHelpLocalizations, + attachHelp: AttachHelpLocalizations, + detachHelp: DetachHelpLocalizations, + postReply: PostReplyLocalizations, + patchReply: PatchReplyLocalizations, noChannelReply: NoChannelReplyLocalizations, noMessageReply: NoMessageReplyLocalizations, noPositionReply: NoPositionReplyLocalizations, @@ -25,8 +33,12 @@ type ChatCompilation = { noPostPermissionReply: NoPostPermissionReplyLocalizations, }; const helpLocalizations: HelpLocalizations = compileAll(chat["help"]); -const replyLocalizations: ReplyLocalizations = compileAll(chat["reply"]); -const bareReplyLocalizations: BareReplyLocalizations = compileAll(chat["bareReply"]); +const postHelpLocalizations: PostHelpLocalizations = compileAll(chat["postHelp"]); +const patchHelpLocalizations: PatchHelpLocalizations = compileAll(chat["patchHelp"]); +const attachHelpLocalizations: AttachHelpLocalizations = compileAll(chat["attachHelp"]); +const detachHelpLocalizations: DetachHelpLocalizations = compileAll(chat["detachHelp"]); +const postReplyLocalizations: PostReplyLocalizations = compileAll(chat["postReply"]); +const patchReplyLocalizations: PatchReplyLocalizations = compileAll(chat["patchReply"]); const noChannelReplyLocalizations: NoChannelReplyLocalizations = compileAll(chat["noChannelReply"]); const noMessageReplyLocalizations: NoMessageReplyLocalizations = compileAll(chat["noMessageReply"]); const noPositionReplyLocalizations: NoPositionReplyLocalizations = compileAll(chat["noPositionReply"]); @@ -36,8 +48,12 @@ const noPatchPermissionReplyLocalizations: NoPatchPermissionReplyLocalizations = const noPostPermissionReplyLocalizations: NoPostPermissionReplyLocalizations = compileAll(chat["noPostPermissionReply"]); const chatCompilation: ChatCompilation = { help: helpLocalizations, - reply: replyLocalizations, - bareReply: bareReplyLocalizations, + postHelp: postHelpLocalizations, + patchHelp: patchHelpLocalizations, + attachHelp: attachHelpLocalizations, + detachHelp: detachHelpLocalizations, + postReply: postReplyLocalizations, + patchReply: patchReplyLocalizations, noChannelReply: noChannelReplyLocalizations, noMessageReply: noMessageReplyLocalizations, noPositionReply: noPositionReplyLocalizations, diff --git a/src/definitions.ts b/src/definitions.ts index 7f562f9..fc408fe 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -106,8 +106,12 @@ type Chat = { attachmentOptionName: string, attachmentOptionDescription: Localized, help: Localized, - reply: Localized, - bareReply: Localized, + postHelp: Localized, + patchHelp: Localized, + attachHelp: Localized, + detachHelp: Localized, + postReply: Localized, + patchReply: Localized, noChannelReply: Localized, noMessageReply: Localized, noPositionReply: Localized, diff --git a/src/definitions/chat.json b/src/definitions/chat.json index c57c7a7..2e1ce47 100644 --- a/src/definitions/chat.json +++ b/src/definitions/chat.json @@ -60,16 +60,36 @@ "pt-BR": "Algum anexo" }, "help": { - "en-US": "Type $ `$ $` to send `$` in `$`\nType $ `$ $ $` to edit `$` with `$` in `$`\nType $ `$ $ $ $` to add at `$` `$` to `$` in `$`\nType $ `$ $ $` to remove at `$` the attachment of `$` in `$`", - "fr": "Tape $ `$ $` pour envoyer `$` dans `$`\nTape $ `$ $` $ pour modifier `$` avec `$` dans `$`\nTape $ `$ $ $ $` pour ajouter à `$` `$` à `$` dans `$`\nTape $ `$ $ $` pour retirer à `$` la pièce jointe d'`$` dans `$`", - "pt-BR": "Digite $ `$ $` pra enviar `$` em `$`\nDigite $ `$ $ $` pra editar `$` com `$` em `$`\nDigite $ `$ $ $ $` pra adicionar em `$` `$` pra `$` em `$`\nDigite $ `$ $ $` pra remover em `$` o anexo de `$` em `$`" - }, - "reply": { + "en-US": "$\n$\n$\n$", + "fr": "$\n$\n$\n$", + "pt-BR": "$\n$\n$\n$" + }, + "postHelp": { + "en-US": "Type $ `$ $` to send `$` in `$`", + "fr": "Tape $ `$ $` pour envoyer `$` dans `$`", + "pt-BR": "Digite $ `$ $` pra enviar `$` em `$`" + }, + "patchHelp": { + "en-US": "Type $ `$ $ $` to edit `$` with `$` in `$`", + "fr": "Tape $ `$ $` $ pour modifier `$` avec `$` dans `$`", + "pt-BR": "Digite $ `$ $ $` pra editar `$` com `$` em `$`" + }, + "attachHelp": { + "en-US": "Type $ `$ $ $ $` to add at `$` `$` to `$` in `$`", + "fr": "Tape $ `$ $ $ $` pour ajouter à `$` `$` à `$` dans `$`", + "pt-BR": "Digite $ `$ $ $ $` pra adicionar em `$` `$` pra `$` em `$`" + }, + "detachHelp": { + "en-US": "Type $ `$ $ $` to remove at `$` the attachment of `$` in `$`", + "fr": "Tape $ `$ $ $` pour retirer à `$` la pièce jointe d'`$` dans `$`", + "pt-BR": "Digite $ `$ $ $` pra remover em `$` o anexo de `$` em `$`" + }, + "patchReply": { "en-US": "I have edited the message.", "fr": "J'ai modifié le message.", "pt-BR": "Editei a mensagem." }, - "bareReply": { + "postReply": { "en-US": "I have sent the message.", "fr": "J'ai envoyé le message.", "pt-BR": "Enviei a mensagem." diff --git a/src/dependencies/chat.d.ts b/src/dependencies/chat.d.ts index 047ad61..c87cfaa 100644 --- a/src/dependencies/chat.d.ts +++ b/src/dependencies/chat.d.ts @@ -1,16 +1,35 @@ type HelpGroups = { + postSubCommandHelp: () => string, + patchSubCommandHelp: () => string, + attachSubCommandHelp: () => string, + detachSubCommandHelp: () => string, +}; +type PostHelpGroups = { postSubCommandMention: () => string, + channelOptionDescription: () => string, + contentOptionDescription: () => string, +}; +type PatchHelpGroups = { patchSubCommandMention: () => string, - attachSubCommandMention: () => string, - detachSubCommandMention: () => string, channelOptionDescription: () => string, messageOptionDescription: () => string, contentOptionDescription: () => string, +}; +type AttachHelpGroups = { + attachSubCommandMention: () => string, + channelOptionDescription: () => string, + messageOptionDescription: () => string, positionOptionDescription: () => string, attachmentOptionDescription: () => string, }; -type ReplyGroups = {}; -type BareReplyGroups = {}; +type DetachHelpGroups = { + detachSubCommandMention: () => string, + channelOptionDescription: () => string, + messageOptionDescription: () => string, + positionOptionDescription: () => string, +}; +type PostReplyGroups = {}; +type PatchReplyGroups = {}; type NoChannelReplyGroups = {}; type NoMessageReplyGroups = {}; type NoPositionReplyGroups = { @@ -22,8 +41,12 @@ type NoPatchPermissionReplyGroups = {}; type NoPostPermissionReplyGroups = {}; type ChatDependency = { help: HelpGroups, - reply: ReplyGroups, - bareReply: BareReplyGroups, + postHelp: PostHelpGroups, + patchHelp: PatchHelpGroups, + attachHelp: AttachHelpGroups, + detachHelp: DetachHelpGroups, + postReply: PostReplyGroups, + patchReply: PatchReplyGroups, noChannelReply: NoChannelReplyGroups, noMessageReply: NoMessageReplyGroups, noPositionReply: NoPositionReplyGroups, From de19dea62ba261a21e3782a3110990d088931372 Mon Sep 17 00:00:00 2001 From: TrisTOON <36267812+TrisTOON@users.noreply.github.com> Date: Thu, 21 Dec 2023 23:27:21 +0100 Subject: [PATCH 2/2] Splits the gate subcommands into their own modules --- src/commands/gate.ts | 105 ++++------------------------------- src/commands/gate/approve.ts | 104 ++++++++++++++++++++++++++++++++++ src/commands/gate/refuse.ts | 104 ++++++++++++++++++++++++++++++++++ src/compilations/gate.ts | 24 ++++++++ src/definitions.ts | 6 ++ src/definitions/gate.json | 36 +++++++++++- src/dependencies/gate.d.ts | 18 ++++++ 7 files changed, 299 insertions(+), 98 deletions(-) create mode 100644 src/commands/gate/approve.ts create mode 100644 src/commands/gate/refuse.ts diff --git a/src/commands/gate.ts b/src/commands/gate.ts index 3332ec3..c9181dd 100644 --- a/src/commands/gate.ts +++ b/src/commands/gate.ts @@ -11,11 +11,10 @@ import type {Gate as GateDefinition} from "../definitions.js"; import type {Gate as GateDependency} from "../dependencies.js"; import type {Locale, Localized} from "../utils/string.js"; import { - ApplicationCommandOptionType, - ApplicationCommandType, ChannelType, } from "discord.js"; -import {approve as approveCommand, refuse as refuseCommand} from "../commands.js"; +import approveSubCommand from "./gate/approve.js"; +import refuseSubCommand from "./gate/refuse.js"; import {gate as gateCompilation} from "../compilations.js"; import {gate as gateDefinition} from "../definitions.js"; import {composeAll, localize, resolve} from "../utils/string.js"; @@ -24,13 +23,9 @@ const { commandName, commandDescription, approveSubCommandName, - approveSubCommandDescription, refuseSubCommandName, - refuseSubCommandDescription, channelOptionName, - channelOptionDescription, messageOptionName, - messageOptionDescription, }: GateDefinition = gateDefinition; const { help: helpLocalizations, @@ -45,72 +40,8 @@ const gateCommand: Command = { description: commandDescription["en-US"], descriptionLocalizations: commandDescription, options: [ - { - type: ApplicationCommandOptionType.Subcommand, - name: approveSubCommandName, - description: approveSubCommandDescription["en-US"], - descriptionLocalizations: approveSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - { - type: ApplicationCommandOptionType.String, - name: messageOptionName, - description: messageOptionDescription["en-US"], - descriptionLocalizations: messageOptionDescription, - required: true, - }, - ], - }, - { - type: ApplicationCommandOptionType.Subcommand, - name: refuseSubCommandName, - description: refuseSubCommandDescription["en-US"], - descriptionLocalizations: refuseSubCommandDescription, - options: [ - { - type: ApplicationCommandOptionType.Channel, - name: channelOptionName, - description: channelOptionDescription["en-US"], - descriptionLocalizations: channelOptionDescription, - required: true, - channelTypes: [ - ChannelType.GuildText, - ChannelType.GuildVoice, - ChannelType.GuildAnnouncement, - ChannelType.AnnouncementThread, - ChannelType.PublicThread, - ChannelType.PrivateThread, - ChannelType.GuildStageVoice, - ChannelType.GuildForum, - ChannelType.GuildMedia, - ], - }, - { - type: ApplicationCommandOptionType.String, - name: messageOptionName, - description: messageOptionDescription["en-US"], - descriptionLocalizations: messageOptionDescription, - required: true, - }, - ], - }, + approveSubCommand.register(), + refuseSubCommand.register(), ], defaultMemberPermissions: [], dmPermission: false, @@ -177,38 +108,22 @@ const gateCommand: Command = { return; } if (subCommandName === approveSubCommandName) { - await approveCommand.interact(Object.assign(Object.create(interaction), { - commandType: ApplicationCommandType.Message, - get targetMessage(): Message { - return message; - }, - })); + await approveSubCommand.interact(interaction, message); return; } if (subCommandName === refuseSubCommandName) { - await refuseCommand.interact(Object.assign(Object.create(interaction), { - commandType: ApplicationCommandType.Message, - get targetMessage(): Message { - return message; - }, - })); + await refuseSubCommand.interact(interaction, message); return; } }, describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { return composeAll(helpLocalizations, localize((locale: Locale): HelpGroups => { return { - approveSubCommandMention: (): string => { - return ``; - }, - refuseSubCommandMention: (): string => { - return ``; - }, - channelOptionDescription: (): string => { - return channelOptionDescription[locale]; + approveSubCommandHelp: (): string => { + return approveSubCommand.describe(applicationCommand)[locale]({}); }, - messageOptionDescription: (): string => { - return messageOptionDescription[locale]; + refuseSubCommandHelp: (): string => { + return refuseSubCommand.describe(applicationCommand)[locale]({}); }, }; })); diff --git a/src/commands/gate/approve.ts b/src/commands/gate/approve.ts new file mode 100644 index 0000000..56db050 --- /dev/null +++ b/src/commands/gate/approve.ts @@ -0,0 +1,104 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + ChatInputCommandInteraction, + Message, +} from "discord.js"; +import type {Gate as GateCompilation} from "../../compilations.js"; +import type {Gate as GateDefinition} from "../../definitions.js"; +import type {Gate as GateDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ApplicationCommandType, + ChannelType, +} from "discord.js"; +import {approve as approveCommand} from "../../commands.js"; +import {gate as gateCompilation} from "../../compilations.js"; +import {gate as gateDefinition} from "../../definitions.js"; +import {composeAll, localize} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type ApproveHelpGroups = GateDependency["approveHelp"]; +const { + commandName, + approveSubCommandName, + approveSubCommandDescription, + channelOptionName, + channelOptionDescription, + messageOptionName, + messageOptionDescription, +}: GateDefinition = gateDefinition; +const { + approveHelp: approveHelpLocalizations, + // approveReply: approveReplyLocalizations, + // noMemberReply: noMemberReplyLocalizations, + // noApprovePermissionReply: noApprovePermissionReplyLocalizations, +}: GateCompilation = gateCompilation; +const approveSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: approveSubCommandName, + description: approveSubCommandDescription["en-US"], + descriptionLocalizations: approveSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + { + type: ApplicationCommandOptionType.String, + name: messageOptionName, + description: messageOptionDescription["en-US"], + descriptionLocalizations: messageOptionDescription, + required: true, + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, message: Message): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + await approveCommand.interact(Object.assign(Object.create(interaction), { + commandType: ApplicationCommandType.Message, + get targetMessage(): Message { + return message; + }, + })); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(approveHelpLocalizations, localize((locale: Locale): ApproveHelpGroups => { + return { + approveSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + messageOptionDescription: (): string => { + return messageOptionDescription[locale]; + }, + }; + })); + }, +}; +export default approveSubCommand; diff --git a/src/commands/gate/refuse.ts b/src/commands/gate/refuse.ts new file mode 100644 index 0000000..96daa67 --- /dev/null +++ b/src/commands/gate/refuse.ts @@ -0,0 +1,104 @@ +import type { + ApplicationCommand, + ApplicationCommandSubCommandData, + ChatInputCommandInteraction, + Message, +} from "discord.js"; +import type {Gate as GateCompilation} from "../../compilations.js"; +import type {Gate as GateDefinition} from "../../definitions.js"; +import type {Gate as GateDependency} from "../../dependencies.js"; +import type {Locale, Localized} from "../../utils/string.js"; +import { + ApplicationCommandOptionType, + ApplicationCommandType, + ChannelType, +} from "discord.js"; +import {refuse as refuseCommand} from "../../commands.js"; +import {gate as gateCompilation} from "../../compilations.js"; +import {gate as gateDefinition} from "../../definitions.js"; +import {composeAll, localize} from "../../utils/string.js"; +type SubCommand = { + register(): ApplicationCommandSubCommandData; + interact(interaction: ChatInputCommandInteraction<"cached">, ...rest: unknown[]): Promise; + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string>; +}; +type RefuseHelpGroups = GateDependency["refuseHelp"]; +const { + commandName, + refuseSubCommandName, + refuseSubCommandDescription, + channelOptionName, + channelOptionDescription, + messageOptionName, + messageOptionDescription, +}: GateDefinition = gateDefinition; +const { + refuseHelp: refuseHelpLocalizations, + // refuseReply: refuseReplyLocalizations, + // noMemberReply: noMemberReplyLocalizations, + // noRefusePermissionReply: noRefusePermissionReplyLocalizations, +}: GateCompilation = gateCompilation; +const refuseSubCommand: SubCommand = { + register(): ApplicationCommandSubCommandData { + return { + type: ApplicationCommandOptionType.Subcommand, + name: refuseSubCommandName, + description: refuseSubCommandDescription["en-US"], + descriptionLocalizations: refuseSubCommandDescription, + options: [ + { + type: ApplicationCommandOptionType.Channel, + name: channelOptionName, + description: channelOptionDescription["en-US"], + descriptionLocalizations: channelOptionDescription, + required: true, + channelTypes: [ + ChannelType.GuildText, + ChannelType.GuildVoice, + ChannelType.GuildAnnouncement, + ChannelType.AnnouncementThread, + ChannelType.PublicThread, + ChannelType.PrivateThread, + ChannelType.GuildStageVoice, + ChannelType.GuildForum, + ChannelType.GuildMedia, + ], + }, + { + type: ApplicationCommandOptionType.String, + name: messageOptionName, + description: messageOptionDescription["en-US"], + descriptionLocalizations: messageOptionDescription, + required: true, + }, + ], + }; + }, + async interact(interaction: ChatInputCommandInteraction<"cached">, message: Message): Promise { + if (!interaction.isChatInputCommand()) { + return; + } + await refuseCommand.interact(Object.assign(Object.create(interaction), { + commandType: ApplicationCommandType.Message, + get targetMessage(): Message { + return message; + }, + })); + }, + describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> { + return composeAll(refuseHelpLocalizations, localize((locale: Locale): RefuseHelpGroups => { + return { + refuseSubCommandMention: (): string => { + return ``; + }, + channelOptionDescription: (): string => { + return channelOptionDescription[locale]; + }, + messageOptionDescription: (): string => { + return messageOptionDescription[locale]; + }, + }; + })); + }, +}; +export default refuseSubCommand; diff --git a/src/compilations/gate.ts b/src/compilations/gate.ts index d05ef78..027e9be 100644 --- a/src/compilations/gate.ts +++ b/src/compilations/gate.ts @@ -3,19 +3,43 @@ import type {Localized} from "../utils/string.js"; import {gate} from "../definitions.js"; import {compileAll} from "../utils/string.js"; type HelpLocalizations = Localized<(groups: Gate["help"]) => string>; +type ApproveHelpLocalizations = Localized<(groups: Gate["approveHelp"]) => string>; +type RefuseHelpLocalizations = Localized<(groups: Gate["refuseHelp"]) => string>; +// type ApproveReplyLocalizations = Localized<(groups: Gate["approveReply"]) => string>; +// type RefuseReplyLocalizations = Localized<(groups: Gate["refuseReply"]) => string>; type NoChannelReplyLocalizations = Localized<(groups: Gate["noChannelReply"]) => string>; type NoMessageReplyLocalizations = Localized<(groups: Gate["noMessageReply"]) => string>; +// type NoApprovePermissionReplyLocalizations = Localized<(groups: Gate["noApprovePermissionReply"]) => string>; +// type NoRefusePermissionReplyLocalizations = Localized<(groups: Gate["noRefusePermissionReply"]) => string>; type GateCompilation = { help: HelpLocalizations, + approveHelp: ApproveHelpLocalizations, + refuseHelp: RefuseHelpLocalizations, + // approveReply: ApproveReplyLocalizations, + // refuseReply: RefuseReplyLocalizations, noChannelReply: NoChannelReplyLocalizations, noMessageReply: NoMessageReplyLocalizations, + // noApprovePermissionReply: NoApprovePermissionReplyLocalizations, + // noRefusePermissionReply: NoRefusePermissionReplyLocalizations, }; const helpLocalizations: HelpLocalizations = compileAll(gate["help"]); +const approveHelpLocalizations: ApproveHelpLocalizations = compileAll(gate["approveHelp"]); +const refuseHelpLocalizations: RefuseHelpLocalizations = compileAll(gate["refuseHelp"]); +// const approveReplyLocalizations: ApproveReplyLocalizations = compileAll(gate["approveReply"]); +// const refuseReplyLocalizations: RefuseReplyLocalizations = compileAll(gate["refuseReply"]); const noChannelReplyLocalizations: NoChannelReplyLocalizations = compileAll(gate["noChannelReply"]); const noMessageReplyLocalizations: NoMessageReplyLocalizations = compileAll(gate["noMessageReply"]); +// const noApprovePermissionReplyLocalizations: NoApprovePermissionReplyLocalizations = compileAll(gate["noApprovePermissionReply"]); +// const noRefusePermissionReplyLocalizations: NoRefusePermissionReplyLocalizations = compileAll(gate["noRefusePermissionReply"]); const gateCompilation: GateCompilation = { help: helpLocalizations, + approveHelp: approveHelpLocalizations, + refuseHelp: refuseHelpLocalizations, + // approveReply: approveReplyLocalizations, + // refuseReply: refuseReplyLocalizations, noChannelReply: noChannelReplyLocalizations, noMessageReply: noMessageReplyLocalizations, + // noApprovePermissionReply: noApprovePermissionReplyLocalizations, + // noRefusePermissionReply: noRefusePermissionReplyLocalizations, }; export default gateCompilation; diff --git a/src/definitions.ts b/src/definitions.ts index fc408fe..6afc4a8 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -154,8 +154,14 @@ type Gate = { messageOptionName: string, messageOptionDescription: Localized, help: Localized, + approveHelp: Localized, + refuseHelp: Localized, + // approveReply: Localized, + // refuseReply: Localized, noChannelReply: Localized, noMessageReply: Localized, + // noApprovePermissionReply: Localized, + // noRefusePermissionReply: Localized, }; type Help = { commandName: string, diff --git a/src/definitions/gate.json b/src/definitions/gate.json index c76b684..637b789 100644 --- a/src/definitions/gate.json +++ b/src/definitions/gate.json @@ -30,9 +30,29 @@ "pt-BR": "Alguma mensagem" }, "help": { - "en-US": "Type $ `$ $` to approve the author of `$` in `$`\nType $ `$ $` to refuse the author of `$` in `$`", - "fr": "Tape $ `$ $` pour approuver l'auteur d'`$` dans `$`\nTape $ `$ $` pour refuser l'auteur d'`$` dans `$`", - "pt-BR": "Digite $ `$ $` pra aprovar o autor de `$` em `$`\nDigite $ `$ $` pra recusar o autor de `$` em `$`" + "en-US": "$\n$", + "fr": "$\n$", + "pt-BR": "$\n$" + }, + "approveHelp": { + "en-US": "Type $ `$ $` to approve the author of `$` in `$`", + "fr": "Tape $ `$ $` pour approuver l'auteur d'`$` dans `$`", + "pt-BR": "Digite $ `$ $` pra aprovar o autor de `$` em `$`" + }, + "refuseHelp": { + "en-US": "Type $ `$ $` to refuse the author of `$` in `$`", + "fr": "Tape $ `$ $` pour refuser l'auteur d'`$` dans `$`", + "pt-BR": "Digite $ `$ $` pra recusar o autor de `$` em `$`" + }, + "approveReply": { + "en-US": "I have approved the member.", + "fr": "J'ai approuvé le membre.", + "pt-BR": "Aprovei o membro." + }, + "refuseReply": { + "en-US": "I have refused the member.", + "fr": "J'ai refusé le membre.", + "pt-BR": "Recusei o membro." }, "noChannelReply": { "en-US": "I do not know any channel with this tag.", @@ -43,5 +63,15 @@ "en-US": "I do not know any message with this identifier in this channel.", "fr": "Je ne connais aucun message avec cet identifiant dans ce salon.", "pt-BR": "Não sei nenhuma mensagem com essa identificação nesse canal." + }, + "noApprovePermissionReply": { + "en-US": "I do not have the rights to verify this member.", + "fr": "Je n'ai pas les droits pour vérifier ce membre.", + "pt-BR": "Eu não tenho as permissões pra verificar esse membro." + }, + "noRefusePermissionReply": { + "en-US": "I do not have the rights to unverify this member.", + "fr": "Je n'ai pas les droits pour dévérifier ce membre.", + "pt-BR": "Eu não tenho as permissões pra desverificar esse membro." } } diff --git a/src/dependencies/gate.d.ts b/src/dependencies/gate.d.ts index 84e8973..b9552b8 100644 --- a/src/dependencies/gate.d.ts +++ b/src/dependencies/gate.d.ts @@ -1,14 +1,32 @@ type HelpGroups = { + approveSubCommandHelp: () => string, + refuseSubCommandHelp: () => string, +}; +type ApproveHelpGroups = { approveSubCommandMention: () => string, + channelOptionDescription: () => string, + messageOptionDescription: () => string, +}; +type RefuseHelpGroups = { refuseSubCommandMention: () => string, channelOptionDescription: () => string, messageOptionDescription: () => string, }; +// type ApproveReplyGroups = {}; +// type RefuseReplyGroups = {}; type NoChannelReplyGroups = {}; type NoMessageReplyGroups = {}; +// type NoApprovePermissionReplyGroups = {}; +// type NoRefusePermissionReplyGroups = {}; type GateDependency = { help: HelpGroups, + approveHelp: ApproveHelpGroups, + refuseHelp: RefuseHelpGroups, + // approveReply: ApproveReplyGroups, + // refuseReply: RefuseReplyGroups, noChannelReply: NoChannelReplyGroups, noMessageReply: NoMessageReplyGroups, + // noApprovePermissionReply: NoApprovePermissionReplyGroups, + // noRefusePermissionReply: NoRefusePermissionReplyGroups, }; export type {GateDependency as default};