import type { AllChannels, Interaction, ModalCommand, ModalSubmitInteraction, ReturnCache } from '..'; import type { GuildMemberStructure, GuildStructure, InteractionGuildMemberStructure, UserStructure, WebhookMessageStructure, } from '../client/transformers'; import type { CommandMetadata, ExtendContext, GlobalMetadata, RegisteredMiddlewares, UsingClient } from '../commands'; import { BaseContext } from '../commands/basecontext'; import type { InteractionCreateBodyRequest, InteractionMessageUpdateBodyRequest, MakeRequired, MessageWebhookCreateBodyRequest, ModalCreateBodyRequest, UnionToTuple, When, } from '../common'; import { MessageFlags } from '../types'; export interface ModalContext extends BaseContext, ExtendContext {} /** * Represents a context for interacting with components in a Discord bot. * @template Type - The type of component interaction. */ export class ModalContext extends BaseContext { /** * Creates a new instance of the ComponentContext class. * @param client - The UsingClient instance. * @param interaction - The component interaction object. */ constructor( readonly client: UsingClient, public interaction: ModalSubmitInteraction, ) { super(client); } command!: ModalCommand; metadata: CommandMetadata> = {} as never; globalMetadata: GlobalMetadata = {}; get customId() { return this.interaction.customId; } get components() { return this.interaction.components; } /** * Gets the language object for the interaction's locale. */ get t() { return this.client.t(this.interaction.locale ?? this.client.langs.defaultLang ?? 'en-US'); } /** * Writes a response to the interaction. * @param body - The body of the response. * @param fetchReply - Whether to fetch the reply or not. */ write( body: InteractionCreateBodyRequest, fetchReply?: FR, ): Promise> { return this.interaction.write(body, fetchReply); } /** * Defers the reply to the interaction. * @param ephemeral - Whether the reply should be ephemeral or not. */ deferReply( ephemeral = false, fetchReply?: FR, ): Promise> { return this.interaction.deferReply(ephemeral ? MessageFlags.Ephemeral : undefined, fetchReply); } /** * Edits the response of the interaction. * @param body - The updated body of the response. */ editResponse(body: InteractionMessageUpdateBodyRequest): Promise { return this.interaction.editResponse(body); } /** * Edits the response or replies to the interaction. * @param body - The body of the response or updated body of the interaction. * @param fetchReply - Whether to fetch the reply or not. */ editOrReply( body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, fetchReply?: FR, ): Promise> { return this.interaction.editOrReply(body as InteractionCreateBodyRequest, fetchReply); } followup(body: MessageWebhookCreateBodyRequest): Promise { return this.interaction.followup(body); } /** * @returns A Promise that resolves to the fetched message */ fetchResponse(): Promise { return this.interaction.fetchResponse(); } /** * Deletes the response of the interaction. * @returns A promise that resolves when the response is deleted. */ deleteResponse() { return this.interaction.deleteResponse(); } modal(body: ModalCreateBodyRequest): ReturnType { //@ts-expect-error return this.interaction.modal(body); } /** * Gets the channel of the interaction. * @param mode - The mode to fetch the channel. * @returns A promise that resolves to the channel. */ channel(mode?: 'rest' | 'flow'): Promise; channel(mode: 'cache'): ReturnCache; channel(mode: 'cache' | 'rest' | 'flow' = 'flow') { if (this.interaction.channel && mode === 'cache') return this.client.cache.adapter.isAsync ? Promise.resolve(this.interaction.channel) : this.interaction.channel; return this.client.channels.fetch(this.channelId, mode === 'rest'); } /** * Gets the bot member in the guild of the interaction. * @param mode - The mode to fetch the member. * @returns A promise that resolves to the bot member. */ me(mode?: 'rest' | 'flow'): Promise; me(mode: 'cache'): ReturnCache; me(mode: 'cache' | 'rest' | 'flow' = 'flow') { if (!this.guildId) return mode === 'cache' ? (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined) : Promise.resolve(); switch (mode) { case 'cache': return this.client.cache.members?.get(this.client.botId, this.guildId); default: return this.client.members.fetch(this.guildId, this.client.botId, mode === 'rest'); } } /** * Gets the guild of the interaction. * @param mode - The mode to fetch the guild. * @returns A promise that resolves to the guild. */ guild(mode?: 'rest' | 'flow'): Promise | undefined>; guild(mode: 'cache'): ReturnCache | undefined>; guild(mode: 'cache' | 'rest' | 'flow' = 'flow') { if (!this.guildId) return ( mode === 'cache' ? (this.client.cache.adapter.isAsync ? Promise.resolve() : undefined) : Promise.resolve() ) as any; switch (mode) { case 'cache': return this.client.cache.guilds?.get(this.guildId); default: return this.client.guilds.fetch(this.guildId, mode === 'rest'); } } /** * Gets the ID of the guild of the interaction. */ get guildId() { return this.interaction.guildId; } /** * Gets the ID of the channel of the interaction. */ get channelId() { return this.interaction.channel.id; } /** * Gets the author of the interaction. */ get author(): UserStructure { return this.interaction.user; } /** * Gets the member of the interaction. */ get member(): InteractionGuildMemberStructure | undefined { return this.interaction.member; } isModal(): this is ModalContext { return true; } inGuild(): this is GuildModalContext { return !!this.guildId; } } export interface GuildModalContext extends Omit, 'guildId' | 'member'>, 'guild'> { guild(mode?: 'rest' | 'flow'): Promise>; guild(mode: 'cache'): ReturnCache | undefined>; }