123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- const discord = require('discord.js')
- const EMOTE_DONE = '✅'
- // TODO: timeout
- async function prompt({channel, user, title, description = '', choices}) {
- const userID = user.discordID || user
- if (description !== '') description += '\n\n'
- const embed = new discord.RichEmbed()
- .setTitle(title)
- .setDescription(
- description +
- choices.map(({name, emote}) => `${emote} ${name}`).join('\n')
- )
- const msg = await channel.send(embed)
- const reactionFilter = (react, user) =>
- user.id === userID &&
- choices.find(c => c.emote.toString() === react.emoji.toString())
- const reactionP = msg
- .awaitReactions(reactionFilter, {max: 1})
- .then(reactions => reactions.first())
- .then(reaction =>
- choices.find(c => c.emote.toString() === reaction.emoji.toString())
- )
- for (const choice of choices) {
- await msg.react(choice.emote)
- }
- // TODO: textual selection? - see https://git.io/fAjFH
- const chosen = await reactionP
- await msg.delete()
- return chosen
- }
- async function multi(opts) {
- const {chooseMin, chooseMax} = opts
- const chosen = []
- while (chosen.length < chooseMax) {
- // Disallow choosing the same choice twice
- const choosable = opts.choices.filter(choice => !chosen.includes(choice))
- // Prompt for next
- const choice = await prompt(
- Object.assign({}, opts, {
- choices:
- chosen.length >= chooseMin
- ? [...choosable, {emote: EMOTE_DONE, name: 'Done'}]
- : choosable,
- })
- )
- if (choice.emote === EMOTE_DONE) {
- return chosen
- }
- chosen.push(choice)
- }
- return chosen
- }
- module.exports = Object.assign(prompt, {multi})
|