aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands/utilities/whoHasRole.ts62
1 files 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 <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<N extends number, Result extends Array<unknown> = []> = Result['length'] extends N
+ ? Result
+ : Mapped<N, [...Result, Result['length']]>;
+
+type NumberRange = Exclude<Mapped<25>[number], 0 | 1>;