diff --git a/.pnp.js b/.pnp.js index 2559646..7ed93bb 100755 --- a/.pnp.js +++ b/.pnp.js @@ -68,6 +68,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["make-dir", "npm:3.1.0"], ["node-emoji", "npm:1.10.0"], ["nodemon", "npm:2.0.6"], + ["p-event", "npm:4.2.0"], ["p-limit", "npm:3.0.2"], ["reflect-metadata", "npm:0.1.13"], ["sequelize", "npm:5.22.3"], @@ -3220,6 +3221,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["make-dir", "npm:3.1.0"], ["node-emoji", "npm:1.10.0"], ["nodemon", "npm:2.0.6"], + ["p-event", "npm:4.2.0"], ["p-limit", "npm:3.0.2"], ["reflect-metadata", "npm:0.1.13"], ["sequelize", "npm:5.22.3"], @@ -3584,6 +3586,25 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["p-event", [ + ["npm:4.2.0", { + "packageLocation": "./.yarn/cache/p-event-npm-4.2.0-1d17e9941e-2f57be6597.zip/node_modules/p-event/", + "packageDependencies": [ + ["p-event", "npm:4.2.0"], + ["p-timeout", "npm:3.2.0"] + ], + "linkType": "HARD", + }] + ]], + ["p-finally", [ + ["npm:1.0.0", { + "packageLocation": "./.yarn/cache/p-finally-npm-1.0.0-35fbaa57c6-01f49b2d9c.zip/node_modules/p-finally/", + "packageDependencies": [ + ["p-finally", "npm:1.0.0"] + ], + "linkType": "HARD", + }] + ]], ["p-limit", [ ["npm:2.2.2", { "packageLocation": "./.yarn/cache/p-limit-npm-2.2.2-b674d9f268-10cd927c1e.zip/node_modules/p-limit/", @@ -3612,6 +3633,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["p-timeout", [ + ["npm:3.2.0", { + "packageLocation": "./.yarn/cache/p-timeout-npm-3.2.0-7fdb33f733-d7e71c1547.zip/node_modules/p-timeout/", + "packageDependencies": [ + ["p-timeout", "npm:3.2.0"], + ["p-finally", "npm:1.0.0"] + ], + "linkType": "HARD", + }] + ]], ["p-try", [ ["npm:2.2.0", { "packageLocation": "./.yarn/cache/p-try-npm-2.2.0-e0390dbaf8-20983f3765.zip/node_modules/p-try/", diff --git a/package.json b/package.json index eae5a17..dc77479 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "iso8601-duration": "^1.2.0", "make-dir": "^3.1.0", "node-emoji": "^1.10.0", + "p-event": "^4.2.0", "p-limit": "^3.0.2", "sequelize": "^5.21.11", "sequelize-typescript": "^1.1.0", diff --git a/src/events/guild-create.ts b/src/events/guild-create.ts index e842b13..4bf6af2 100644 --- a/src/events/guild-create.ts +++ b/src/events/guild-create.ts @@ -1,6 +1,8 @@ -import {Guild, MessageReaction, TextChannel, User, Message} from 'discord.js'; +import {Guild, TextChannel, Message} from 'discord.js'; import emoji from 'node-emoji'; +import pEvent from 'p-event'; import {Settings} from '../models'; +import {chunk} from '../utils/arrays'; const DEFAULT_PREFIX = '!'; @@ -13,6 +15,9 @@ export default async (guild: Guild): Promise => { firstStep += 'I just need to ask a few questions before you start listening to music.\n\n'; firstStep += 'First, what channel should I listen to for music commands?\n\n'; + const firstStepMsg = await owner.send(firstStep); + + // Show emoji selector interface EmojiChannel { name: string; id: string; @@ -31,23 +36,30 @@ export default async (guild: Guild): Promise => { } } - for (const channel of emojiChannels) { - firstStep += `${channel.emoji}: #${channel.name}\n`; - } + const sentMessageIds: string[] = []; - firstStep += '\n'; + chunk(emojiChannels, 10).map(async chunk => { + let str = ''; + for (const channel of chunk) { + str += `${channel.emoji}: #${channel.name}\n`; + } - // Send message - const msg = await owner.send(firstStep); + const msg = await owner.send(str); - // Add reactions - for await (const channel of emojiChannels) { - await msg.react(channel.emoji); - } + sentMessageIds.push(msg.id); - const reactions = await msg.awaitReactions((reaction: MessageReaction, user: User) => user.id !== msg.author.id && emojiChannels.map(e => e.emoji).includes(reaction.emoji.name), {max: 1}); + await Promise.all(chunk.map(async channel => msg.react(channel.emoji))); + }); - const choice = reactions.first() as MessageReaction; + // Wait for response from user + + const [choice] = await pEvent(guild.client, 'messageReactionAdd', { + multiArgs: true, + filter: options => { + const [reaction, user] = options; + return sentMessageIds.includes(reaction.message.id) && user.id === owner.id; + } + }); const chosenChannel = emojiChannels.find(e => e.emoji === choice.emoji.name) as EmojiChannel; @@ -57,7 +69,7 @@ export default async (guild: Guild): Promise => { await owner.send(secondStep); - const prefixResponses = await msg.channel.awaitMessages((r: Message) => r.content.length === 1, {max: 1}); + const prefixResponses = await firstStepMsg.channel.awaitMessages((r: Message) => r.content.length === 1, {max: 1}); const prefixCharacter = prefixResponses.first()!.content; @@ -69,5 +81,5 @@ export default async (guild: Guild): Promise => { await boundChannel.send(`hey <@${owner.id}> try \`${prefixCharacter}play https://www.youtube.com/watch?v=dQw4w9WgXcQ\``); - await msg.channel.send(`Sounds good. Check out **#${chosenChannel.name}** to get started.`); + await firstStepMsg.channel.send(`Sounds good. Check out **#${chosenChannel.name}** to get started.`); }; diff --git a/src/utils/arrays.ts b/src/utils/arrays.ts new file mode 100644 index 0000000..3961244 --- /dev/null +++ b/src/utils/arrays.ts @@ -0,0 +1,10 @@ +export const chunk = (arr: T[], len: number) => { + const chunks = []; + + let i = 0; + while (i < arr.length) { + chunks.push(arr.slice(i, i += len)); + } + + return chunks; +}; diff --git a/yarn.lock b/yarn.lock index e44c0c3..f10ab57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2734,6 +2734,7 @@ fsevents@~2.1.2: make-dir: ^3.1.0 node-emoji: ^1.10.0 nodemon: ^2.0.6 + p-event: ^4.2.0 p-limit: ^3.0.2 reflect-metadata: ^0.1.13 sequelize: ^5.21.11 @@ -3090,6 +3091,22 @@ fsevents@~2.1.2: languageName: node linkType: hard +"p-event@npm:^4.2.0": + version: 4.2.0 + resolution: "p-event@npm:4.2.0" + dependencies: + p-timeout: ^3.1.0 + checksum: 2f57be65972285794231072b188a1f0ff542285e5629066b6902db4420ce09bec9b4c75829ce0f996132d2ca0e38b16f675e2be15a20a03fc9e7ab515571b0b8 + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 01f49b2d9c67573b3a1cb253cd9e1ecf5c912b6ba5de8824118bbc8d647bfa6296820b5a536e91ec68a54395d4e1c58de9a381ded3b688074fb446a8fe351931 + languageName: node + linkType: hard + "p-limit@npm:^2.2.0": version: 2.2.2 resolution: "p-limit@npm:2.2.2" @@ -3117,6 +3134,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"p-timeout@npm:^3.1.0": + version: 3.2.0 + resolution: "p-timeout@npm:3.2.0" + dependencies: + p-finally: ^1.0.0 + checksum: d7e71c1547736ecd392be3c4ea956af1abd2b6f56179f37443672cfaccb41383533cdf2e927890bb5282e1eb41c979be133eef26a6a84a8224ff4f5c9455b517 + languageName: node + linkType: hard + "p-try@npm:^2.0.0": version: 2.2.0 resolution: "p-try@npm:2.2.0"