mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 16:43:31 +01:00
refactor(Collector): make filter an option (#5903)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
@@ -16,6 +16,7 @@ const Util = require('../../util/Util');
|
||||
/**
|
||||
* Options to be applied to the collector.
|
||||
* @typedef {Object} CollectorOptions
|
||||
* @property {CollectorFilter} [filter] The filter applied to this collector
|
||||
* @property {number} [time] How long to run the collector for in milliseconds
|
||||
* @property {number} [idle] How long to stop the collector after inactivity in milliseconds
|
||||
* @property {boolean} [dispose=false] Whether to dispose data when it's deleted
|
||||
@@ -26,7 +27,7 @@ const Util = require('../../util/Util');
|
||||
* @abstract
|
||||
*/
|
||||
class Collector extends EventEmitter {
|
||||
constructor(client, filter, options = {}) {
|
||||
constructor(client, options = {}) {
|
||||
super();
|
||||
|
||||
/**
|
||||
@@ -40,8 +41,9 @@ class Collector extends EventEmitter {
|
||||
/**
|
||||
* The filter applied to this collector
|
||||
* @type {CollectorFilter}
|
||||
* @returns {boolean|Promise<boolean>}
|
||||
*/
|
||||
this.filter = filter;
|
||||
this.filter = options.filter ?? (() => true);
|
||||
|
||||
/**
|
||||
* The options of this collector
|
||||
@@ -75,8 +77,8 @@ class Collector extends EventEmitter {
|
||||
*/
|
||||
this._idletimeout = null;
|
||||
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
if (typeof this.filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'options.filter', 'function');
|
||||
}
|
||||
|
||||
this.handleCollect = this.handleCollect.bind(this);
|
||||
@@ -89,6 +91,7 @@ class Collector extends EventEmitter {
|
||||
/**
|
||||
* Call this to handle an event as a collectable element. Accepts any event data as parameters.
|
||||
* @param {...*} args The arguments emitted by the listener
|
||||
* @returns {Promise<void>}
|
||||
* @emits Collector#collect
|
||||
*/
|
||||
async handleCollect(...args) {
|
||||
@@ -115,13 +118,14 @@ class Collector extends EventEmitter {
|
||||
/**
|
||||
* Call this to remove an element from the collection. Accepts any event data as parameters.
|
||||
* @param {...*} args The arguments emitted by the listener
|
||||
* @returns {Promise<void>}
|
||||
* @emits Collector#dispose
|
||||
*/
|
||||
handleDispose(...args) {
|
||||
async handleDispose(...args) {
|
||||
if (!this.options.dispose) return;
|
||||
|
||||
const dispose = this.dispose(...args);
|
||||
if (!dispose || !this.filter(...args) || !this.collected.has(dispose)) return;
|
||||
if (!dispose || !(await this.filter(...args)) || !this.collected.has(dispose)) return;
|
||||
this.collected.delete(dispose);
|
||||
|
||||
/**
|
||||
|
||||
@@ -275,18 +275,17 @@ class TextBasedChannel {
|
||||
|
||||
/**
|
||||
* Creates a Message Collector.
|
||||
* @param {CollectorFilter} filter The filter to create the collector with
|
||||
* @param {MessageCollectorOptions} [options={}] The options to pass to the collector
|
||||
* @returns {MessageCollector}
|
||||
* @example
|
||||
* // Create a message collector
|
||||
* const filter = m => m.content.includes('discord');
|
||||
* const collector = channel.createMessageCollector(filter, { time: 15000 });
|
||||
* const collector = channel.createMessageCollector({ filter, time: 15000 });
|
||||
* collector.on('collect', m => console.log(`Collected ${m.content}`));
|
||||
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
||||
*/
|
||||
createMessageCollector(filter, options = {}) {
|
||||
return new MessageCollector(this, filter, options);
|
||||
createMessageCollector(options = {}) {
|
||||
return new MessageCollector(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,20 +297,19 @@ class TextBasedChannel {
|
||||
/**
|
||||
* Similar to createMessageCollector but in promise form.
|
||||
* Resolves with a collection of messages that pass the specified filter.
|
||||
* @param {CollectorFilter} filter The filter function to use
|
||||
* @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector
|
||||
* @returns {Promise<Collection<Snowflake, Message>>}
|
||||
* @example
|
||||
* // Await !vote messages
|
||||
* const filter = m => m.content.startsWith('!vote');
|
||||
* // Errors: ['time'] treats ending because of the time limit as an error
|
||||
* channel.awaitMessages(filter, { max: 4, time: 60000, errors: ['time'] })
|
||||
* channel.awaitMessages({ filter, max: 4, time: 60000, errors: ['time'] })
|
||||
* .then(collected => console.log(collected.size))
|
||||
* .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`));
|
||||
*/
|
||||
awaitMessages(filter, options = {}) {
|
||||
awaitMessages(options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = this.createMessageCollector(filter, options);
|
||||
const collector = this.createMessageCollector(options);
|
||||
collector.once('end', (collection, reason) => {
|
||||
if (options.errors && options.errors.includes(reason)) {
|
||||
reject(collection);
|
||||
@@ -324,36 +322,34 @@ class TextBasedChannel {
|
||||
|
||||
/**
|
||||
* Creates a button interaction collector.
|
||||
* @param {CollectorFilter} filter The filter to apply
|
||||
* @param {MessageComponentInteractionCollectorOptions} [options={}] Options to send to the collector
|
||||
* @returns {MessageComponentInteractionCollector}
|
||||
* @example
|
||||
* // Create a button interaction collector
|
||||
* const filter = (interaction) => interaction.customID === 'button' && interaction.user.id === 'someID';
|
||||
* const collector = channel.createMessageComponentInteractionCollector(filter, { time: 15000 });
|
||||
* const collector = channel.createMessageComponentInteractionCollector({ filter, time: 15000 });
|
||||
* collector.on('collect', i => console.log(`Collected ${i.customID}`));
|
||||
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
||||
*/
|
||||
createMessageComponentInteractionCollector(filter, options = {}) {
|
||||
return new MessageComponentInteractionCollector(this, filter, options);
|
||||
createMessageComponentInteractionCollector(options = {}) {
|
||||
return new MessageComponentInteractionCollector(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects a single component interaction that passes the filter.
|
||||
* The Promise will reject if the time expires.
|
||||
* @param {CollectorFilter} filter The filter function to use
|
||||
* @param {AwaitMessageComponentInteractionOptions} [options={}] Options to pass to the internal collector
|
||||
* @returns {Promise<MessageComponentInteraction>}
|
||||
* @example
|
||||
* // Collect a message component interaction
|
||||
* const filter = (interaction) => interaction.customID === 'button' && interaction.user.id === 'someID';
|
||||
* channel.awaitMessageComponentInteraction(filter, { time: 15000 })
|
||||
* channel.awaitMessageComponentInteraction({ filter, time: 15000 })
|
||||
* .then(interaction => console.log(`${interaction.customID} was clicked!`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
awaitMessageComponentInteraction(filter, { time } = {}) {
|
||||
awaitMessageComponentInteraction(options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = this.createMessageComponentInteractionCollector(filter, { max: 1, time });
|
||||
const collector = this.createMessageComponentInteractionCollector({ ...options, max: 1 });
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
|
||||
Reference in New Issue
Block a user