mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat(modal): add awaitModalSubmit (#7751)
* feat(modal): add awaitModalSubmit * fix: allow command interactions to await modal submissions * Update packages/discord.js/src/structures/CommandInteraction.js Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com> * chore: less is more * Update packages/discord.js/src/structures/interfaces/InteractionResponses.js Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: MateoDeveloper <79017590+Mateo-tem@users.noreply.github.com> Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
@@ -204,6 +204,7 @@ class CommandInteraction extends Interaction {
|
||||
deleteReply() {}
|
||||
followUp() {}
|
||||
showModal() {}
|
||||
awaitModalSubmit() {}
|
||||
}
|
||||
|
||||
InteractionResponses.applyToClass(CommandInteraction, ['deferUpdate', 'update']);
|
||||
|
||||
@@ -91,6 +91,7 @@ class MessageComponentInteraction extends Interaction {
|
||||
deferUpdate() {}
|
||||
update() {}
|
||||
showModal() {}
|
||||
awaitModalSubmit() {}
|
||||
}
|
||||
|
||||
InteractionResponses.applyToClass(MessageComponentInteraction);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { InteractionResponseType, MessageFlags, Routes } = require('discord-api-types/v10');
|
||||
const { InteractionResponseType, MessageFlags, Routes, InteractionType } = require('discord-api-types/v10');
|
||||
const { Error } = require('../../errors');
|
||||
const InteractionCollector = require('../InteractionCollector');
|
||||
const MessagePayload = require('../MessagePayload');
|
||||
|
||||
/**
|
||||
@@ -248,6 +249,38 @@ class InteractionResponses {
|
||||
this.replied = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object containing the same properties as {@link CollectorOptions}, but a few less:
|
||||
* @typedef {Object} AwaitModalSubmitOptions
|
||||
* @property {CollectorFilter} [filter] The filter applied to this collector
|
||||
* @property {number} time Time to wait for an interaction before rejecting
|
||||
*/
|
||||
|
||||
/**
|
||||
* Collects a single modal submit interaction that passes the filter.
|
||||
* The Promise will reject if the time expires.
|
||||
* @param {AwaitModalSubmitOptions} options Options to pass to the internal collector
|
||||
* @returns {Promise<ModalSubmitInteraction>}
|
||||
* @example
|
||||
* // Collect a modal submit interaction
|
||||
* const filter = (interaction) => interaction.customId === 'modal';
|
||||
* interaction.awaitModalSubmit({ filter, time: 15_000 })
|
||||
* .then(interaction => console.log(`${interaction.customId} was submitted!`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
awaitModalSubmit(options) {
|
||||
if (typeof options.time !== 'number') throw new Error('INVALID_TYPE', 'time', 'number');
|
||||
const _options = { ...options, max: 1, interactionType: InteractionType.ModalSubmit };
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = new InteractionCollector(this.client, _options);
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static applyToClass(structure, ignore = []) {
|
||||
const props = [
|
||||
'deferReply',
|
||||
@@ -259,6 +292,7 @@ class InteractionResponses {
|
||||
'deferUpdate',
|
||||
'update',
|
||||
'showModal',
|
||||
'awaitModalSubmit',
|
||||
];
|
||||
|
||||
for (const prop of props) {
|
||||
|
||||
14
packages/discord.js/typings/index.d.ts
vendored
14
packages/discord.js/typings/index.d.ts
vendored
@@ -379,6 +379,7 @@ export interface InteractionResponseFields<Cached extends CacheType = CacheType>
|
||||
showModal(
|
||||
modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalData | APIModalInteractionResponseCallbackData,
|
||||
): Promise<void>;
|
||||
awaitModalSubmit(options: AwaitModalSubmitOptions<ModalSubmitInteraction>): Promise<ModalSubmitInteraction<Cached>>;
|
||||
}
|
||||
|
||||
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
|
||||
@@ -1744,6 +1745,7 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
||||
public showModal(
|
||||
modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalData | APIModalInteractionResponseCallbackData,
|
||||
): Promise<void>;
|
||||
public awaitModalSubmit(options: AwaitModalSubmitOptions<ModalSubmitInteraction>): Promise<ModalSubmitInteraction>;
|
||||
}
|
||||
|
||||
export class MessageContextMenuCommandInteraction<
|
||||
@@ -3563,6 +3565,18 @@ export type AwaitMessageComponentOptions<T extends MessageComponentInteraction>
|
||||
'max' | 'maxComponents' | 'maxUsers'
|
||||
>;
|
||||
|
||||
export type ModalSubmitInteractionCollectorOptions<T extends ModalSubmitInteraction> = Omit<
|
||||
InteractionCollectorOptions<T>,
|
||||
'channel' | 'message' | 'guild' | 'interactionType'
|
||||
>;
|
||||
|
||||
export type AwaitModalSubmitOptions<T extends ModalSubmitInteraction> = Omit<
|
||||
ModalSubmitInteractionCollectorOptions<T>,
|
||||
'max' | 'maxComponents' | 'maxUsers'
|
||||
> & {
|
||||
time: number;
|
||||
};
|
||||
|
||||
export interface AwaitMessagesOptions extends MessageCollectorOptions {
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user