1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import {
BotCommand,
clientSendAndPermCheck,
colors,
emojis,
guildFeaturesArr,
guildFeaturesObj,
type CommandMessage,
type GuildFeatures,
type SlashMessage
} from '#lib';
import assert from 'assert/strict';
import {
ActionRowBuilder,
ComponentType,
EmbedBuilder,
PermissionFlagsBits,
SelectMenuBuilder,
type Message,
type SelectMenuInteraction
} from 'discord.js';
export default class FeaturesCommand extends BotCommand {
public constructor() {
super('features', {
aliases: ['features'],
category: 'config',
description: 'Toggle the features of the server.',
usage: ['features'],
examples: ['features'],
slash: true,
channel: 'guild',
clientPermissions: (m) => clientSendAndPermCheck(m, [PermissionFlagsBits.EmbedLinks], true),
userPermissions: [PermissionFlagsBits.ManageGuild]
});
}
public override async exec(message: CommandMessage | SlashMessage) {
assert(message.inGuild());
const featureEmbed = new EmbedBuilder().setTitle(`${message.guild.name}'s Features`).setColor(colors.default);
const hideHidden = !message.author.isOwner();
const enabledFeatures = await message.guild.getSetting('enabledFeatures');
this.generateDescription(guildFeaturesArr, enabledFeatures, featureEmbed, hideHidden);
const components = this.generateComponents(guildFeaturesArr, false, hideHidden);
const msg = (await message.util.reply({ embeds: [featureEmbed], components: [components] })) as Message;
const collector = msg.createMessageComponentCollector({
componentType: ComponentType.SelectMenu,
time: 300_000,
filter: (i) => i.guildId === msg.guildId && i.message?.id === msg.id
});
collector.on('collect', async (interaction: SelectMenuInteraction) => {
if (interaction.user.id === message.author.id || this.client.config.owners.includes(interaction.user.id)) {
assert(message.inGuild());
const [selected]: GuildFeatures[] = interaction.values as GuildFeatures[];
if (!guildFeaturesArr.includes(selected)) throw new Error('Invalid guild feature selected');
const newEnabledFeatures = await message.guild.toggleFeature(selected, message.member!);
this.generateDescription(guildFeaturesArr, newEnabledFeatures, featureEmbed, hideHidden);
await interaction.update({ embeds: [featureEmbed] }).catch(() => undefined);
return;
} else {
await interaction?.deferUpdate().catch(() => undefined);
return;
}
});
collector.on('end', async () => {
await msg
.edit({ components: [this.generateComponents(guildFeaturesArr, false, !message.author.isOwner())] })
.catch(() => undefined);
});
}
public generateDescription(
allFeatures: GuildFeatures[],
currentFeatures: GuildFeatures[],
embed: EmbedBuilder,
hide: boolean
): void {
embed.setDescription(
allFeatures
.filter((f) => !guildFeaturesObj[f].hidden || !hide)
.map(
(feature) => `${currentFeatures.includes(feature) ? emojis.check : emojis.cross} **${guildFeaturesObj[feature].name}**`
)
.join('\n')
);
}
public generateComponents(guildFeatures: GuildFeatures[], disable: boolean, hide: boolean) {
return new ActionRowBuilder<SelectMenuBuilder>().addComponents(
new SelectMenuBuilder({
customId: 'command_selectFeature',
disabled: disable,
maxValues: 1,
minValues: 1,
options: guildFeatures
.filter((f) => !guildFeaturesObj[f].hidden || !hide)
.map((f) => ({
label: guildFeaturesObj[f].name,
value: f,
description: guildFeaturesObj[f].description
}))
})
);
}
}
|