From 6ca99336a416389dd2b0b8c4c6a7b2ef87bc9fef Mon Sep 17 00:00:00 2001 From: IRONM00N <64110067+IRONM00N@users.noreply.github.com> Date: Sun, 23 Jan 2022 22:19:32 -0500 Subject: allow whoHasRole to search for multiple roles --- src/commands/utilities/whoHasRole.ts | 62 ++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts index 4993528..ac6f3c5 100644 --- a/src/commands/utilities/whoHasRole.ts +++ b/src/commands/utilities/whoHasRole.ts @@ -1,4 +1,5 @@ -import { BushCommand, ButtonPaginator, type ArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import { BushCommand, BushRole, ButtonPaginator, OptionalArgType, type BushMessage, type BushSlashMessage } from '#lib'; +import assert from 'assert'; import { ApplicationCommandOptionType, Util, type CommandInteraction } from 'discord.js'; export default class WhoHasRoleCommand extends BushCommand { @@ -7,19 +8,20 @@ export default class WhoHasRoleCommand extends BushCommand { aliases: ['who-has-role', 'whr', 'dump'], category: 'utilities', description: 'Allows you to view what users have a certain role.', - usage: ['who-has-role '], + usage: ['who-has-role <...roles>'], examples: ['who-has-role admin'], - args: [ - { - id: 'role', - description: 'The role to find the users of.', - type: 'role', - prompt: 'What role would you like to find the users of?', - retry: '{error} Pick a valid role.', - optional: false, - slashType: ApplicationCommandOptionType.Role - } - ], + args: new Array(25).fill(0).map( + (_, i) => + ({ + id: `role${i + 1}`, + description: i === 0 ? 'The role to find the users of.' : 'Another role that the user must have.', + type: 'role', + prompt: i === 0 ? 'What role would you like to find the users of?' : 'What other role should the user also have?', + retry: '{error} Choose a valid role.', + slashType: ApplicationCommandOptionType.Role, + optional: i !== 0 + } as const) + ), slash: true, channel: 'guild', clientPermissions: (m) => util.clientSendAndPermCheck(m), @@ -28,13 +30,31 @@ export default class WhoHasRoleCommand extends BushCommand { }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { role: ArgType<'role'> }) { + public override async exec( + message: BushMessage | BushSlashMessage, + args: { + [K in `role${NumberRange}`]: OptionalArgType<'role'>; + } + ) { + assert(message.inGuild()); if (message.util.isSlash) await (message.interaction as CommandInteraction).deferReply(); - const roleMembers = args.role.members.map((member) => `${member.user} (${Util.escapeMarkdown(member.user.tag)})`); + const rawRoles = Object.values(args).filter((v) => v !== null) as BushRole[]; + const roles = rawRoles.map((v) => v.id); + + const members = message.guild.members.cache.filter((m) => roles.every((r) => m.roles.cache.has(r))); + + const roleMembers = members.map((member) => `${member.user} (${Util.escapeMarkdown(member.user.tag)})`); const chunkedRoleMembers = util.chunk(roleMembers, 30); - const title = `${args.role.name}'s Members [\`${args.role.members.size.toLocaleString()}\`]`; + const title = `Members with ${ + roles.length < 4 + ? util.oxford( + rawRoles.map((r) => r.name), + 'and' + ) + : `${rawRoles.length} Roles` + } [\`${members.size.toLocaleString()}\`]`; const color = util.colors.default; const embedPages = chunkedRoleMembers.map((chunk) => ({ title, @@ -42,6 +62,16 @@ export default class WhoHasRoleCommand extends BushCommand { color })); + if (embedPages.length === 0) { + return await message.util.reply(`${util.emojis.error} No members found matching the given roles.`); + } + return await ButtonPaginator.send(message, embedPages, null, true); } } + +type Mapped = []> = Result['length'] extends N + ? Result + : Mapped; + +type NumberRange = Exclude[number], 0 | 1>; -- cgit