mirror of
https://github.com/LBRYFoundation/curate.git
synced 2025-08-23 17:37:25 +00:00
154 lines
No EOL
5.5 KiB
JavaScript
154 lines
No EOL
5.5 KiB
JavaScript
const Halt = require('./structures/Halt');
|
|
const ReactionCollector = require('./structures/ReactionCollector');
|
|
|
|
/**
|
|
* Handles async message functions
|
|
*/
|
|
class MessageAwaiter {
|
|
constructor(client) {
|
|
this.client = client;
|
|
this.halts = new Map();
|
|
this.reactionCollectors = new Map();
|
|
}
|
|
|
|
/**
|
|
* Creates a halt. This pauses any events in the event handler for a specific channel and user.
|
|
* This allows any async functions to handle any follow-up messages.
|
|
* @param {string} channelID The channel's ID
|
|
* @param {string} userID The user's ID
|
|
* @param {number} [timeout=30000] The time until the halt is auto-cleared
|
|
*/
|
|
createHalt(channelID, userID, timeout = 30000) {
|
|
const id = `${channelID}:${userID}`;
|
|
if (this.halts.has(id)) this.halts.get(id).end();
|
|
const halt = new Halt(this, timeout);
|
|
halt.once('end', () => this.halts.delete(id));
|
|
this.halts.set(id, halt);
|
|
return halt;
|
|
}
|
|
|
|
/**
|
|
* Creates a reaction collector. Any reactions from the user will be emitted from the collector.
|
|
* @param {string} message The message to collect from
|
|
* @param {string} userID The user's ID
|
|
* @param {number} [timeout=30000] The time until the halt is auto-cleared
|
|
*/
|
|
createReactionCollector(message, userID, timeout = 30000) {
|
|
const id = `${message.id}:${userID}`;
|
|
if (this.reactionCollectors.has(id)) this.reactionCollectors.get(id).end();
|
|
const collector = new ReactionCollector(this, timeout);
|
|
collector.once('end', () => this.reactionCollectors.delete(id));
|
|
this.reactionCollectors.set(id, collector);
|
|
return collector;
|
|
}
|
|
|
|
/**
|
|
* Gets an ongoing halt based on a message
|
|
* @param {Message} message
|
|
*/
|
|
getHalt(message) {
|
|
const id = `${message.channel.id}:${message.author.id}`;
|
|
return this.halts.get(id);
|
|
}
|
|
|
|
/**
|
|
* Processes a halt based on a message
|
|
* @param {Message} message
|
|
*/
|
|
processHalt(message) {
|
|
const id = `${message.channel.id}:${message.author.id}`;
|
|
if (this.halts.has(id)) {
|
|
const halt = this.halts.get(id);
|
|
halt._onMessage(message);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Awaits the next message from a user
|
|
* @param {Message} message The message to wait for
|
|
* @param {Object} [options] The options for the await
|
|
* @param {number} [options.filter] The message filter
|
|
* @param {number} [options.timeout=30000] The timeout for the halt
|
|
* @returns {?Message}
|
|
*/
|
|
awaitMessage(message, { filter = () => true, timeout = 30000 } = {}) {
|
|
return new Promise(resolve => {
|
|
const halt = this.createHalt(message.channel.id, message.author.id, timeout);
|
|
let foundMessage = null;
|
|
halt.on('message', nextMessage => {
|
|
if (filter(nextMessage)) {
|
|
foundMessage = nextMessage;
|
|
halt.end();
|
|
}
|
|
});
|
|
halt.on('end', () => resolve(foundMessage));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Same as {@see #awaitMessage}, but is used for getting user input via next message
|
|
* @param {Message} message The message to wait for
|
|
* @param {Object} [options] The options for the await
|
|
* @param {number} [options.filter] The message filter
|
|
* @param {number} [options.timeout=30000] The timeout for the halt
|
|
* @param {string} [options.header] The content to put in the bot message
|
|
* @returns {?Message}
|
|
*/
|
|
async getInput(message, { filter = () => true, timeout = 30000, header = null } = {}) {
|
|
await message.channel.createMessage(`<@${message.author.id}>, ` +
|
|
(header || 'Type the message you want to input.') + '\n\n' +
|
|
`Typing "<@!${this.client.user.id}> cancel" will cancel the input.`);
|
|
return new Promise(resolve => {
|
|
const halt = this.createHalt(message.channel.id, message.author.id, timeout);
|
|
let handled = false, input = null;
|
|
halt.on('message', nextMessage => {
|
|
if (filter(nextMessage)) {
|
|
const cancelRegex = new RegExp(`^(?:<@!?${this.client.user.id}>\\s?)(cancel|stop|end)$`);
|
|
|
|
if (!nextMessage.content || cancelRegex.test(nextMessage.content.toLowerCase())) {
|
|
handled = true;
|
|
message.channel.createMessage(`<@${message.author.id}>, Your last input was canceled.`);
|
|
} else input = nextMessage.content;
|
|
halt.end();
|
|
}
|
|
});
|
|
halt.on('end', async () => {
|
|
if (!input && !handled)
|
|
await message.channel.createMessage(`<@${message.author.id}>, Your last input was canceled.`);
|
|
resolve(input);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Same as {@see #awaitMessage}, but is used for confirmation
|
|
* @param {Message} message The message to wait for
|
|
* @param {Object} [options] The options for the await
|
|
* @param {number} [options.timeout=30000] The timeout for the halt
|
|
* @param {string} [options.header] The content to put in the bot message
|
|
* @returns {?Message}
|
|
*/
|
|
async confirm(message, { timeout = 30000, header = null } = {}) {
|
|
await message.channel.createMessage(`<@${message.author.id}>, ` +
|
|
(header || 'Are you sure you want to do this?') + '\n\n' +
|
|
'Type `yes` to confirm. Any other message will cancel the confirmation.');
|
|
return new Promise(resolve => {
|
|
const halt = this.createHalt(message.channel.id, message.author.id, timeout);
|
|
let input = false;
|
|
halt.on('message', nextMessage => {
|
|
input = nextMessage.content === 'yes';
|
|
halt.end();
|
|
});
|
|
halt.on('end', async () => {
|
|
if (!input)
|
|
await message.channel.createMessage(`<@${message.author.id}>, Confirmation canceled.`);
|
|
resolve(input);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
MessageAwaiter.Halt = Halt;
|
|
module.exports = MessageAwaiter; |