12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- 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.map(c => c.emote).includes(react.emoji.name)
- const reactionP = msg.awaitReactions(reactionFilter, {max: 1})
- .then(reactions => reactions.first())
- .then(reaction => choices.find(c => c.emote === reaction.emoji.name))
- 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: '(Finish)'}]
- : choosable
- }))
- if (choice.emote === EMOTE_DONE) {
- return chosen
- }
- chosen.push(choice)
- }
- return chosen
- }
- module.exports = Object.assign(prompt, {multi})
|