blob: 294c0fd89375e447510fc43db0266273707d1d5e [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
Skyler Grey11236ba2022-08-08 21:13:33 +01002import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
4import getEmojiByName from "../../utils/getEmojiByName.js";
5import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
6import { WrappedCheck } from "jshaiku";
7import client from "../../utils/client.js";
8import { modalInteractionCollector } from "../../utils/dualCollector.js";
9import confirmationMessage from "../../utils/confirmationMessage.js";
10import keyValueList from "../../utils/generateKeyValueList.js";
11
12const command = (builder: SlashCommandSubcommandBuilder) =>
13 builder
pineafan63fc5e22022-08-04 22:04:10 +010014 .setName("commands")
Skyler Grey11236ba2022-08-08 21:13:33 +010015 .setDescription("Links and text shown to a user after a moderator action is performed")
16 .addRoleOption((o) => o.setName("role").setDescription("The role given when a member is muted"));
pineafan0bc04162022-07-25 17:22:26 +010017
pineafan3a02ea32022-08-11 21:35:04 +010018const callback = async (interaction: CommandInteraction): Promise<unknown> => {
Skyler Grey75ea9172022-08-06 10:22:23 +010019 await interaction.reply({
20 embeds: LoadingEmbed,
21 ephemeral: true,
22 fetchReply: true
23 });
pineafan0bc04162022-07-25 17:22:26 +010024 let m;
25 let clicked = "";
26 if (interaction.options.getRole("role")) {
pineafan63fc5e22022-08-04 22:04:10 +010027 const confirmation = await new confirmationMessage(interaction)
pineafan0bc04162022-07-25 17:22:26 +010028 .setEmoji("GUILD.ROLES.DELETE")
29 .setTitle("Moderation Commands")
Skyler Grey75ea9172022-08-06 10:22:23 +010030 .setDescription(
31 keyValueList({
32 role: `<@&${interaction.options.getRole("role").id}>`
33 })
34 )
pineafan0bc04162022-07-25 17:22:26 +010035 .setColor("Danger")
pineafan63fc5e22022-08-04 22:04:10 +010036 .send(true);
Skyler Grey75ea9172022-08-06 10:22:23 +010037 if (confirmation.cancelled)
38 return await interaction.editReply({
39 embeds: [
40 new EmojiEmbed()
41 .setTitle("Moderation Commands")
42 .setDescription("No changes were made")
43 .setStatus("Success")
44 .setEmoji("GUILD.ROLES.CREATE")
45 ]
46 });
pineafan0bc04162022-07-25 17:22:26 +010047 if (confirmation.success) {
Skyler Grey75ea9172022-08-06 10:22:23 +010048 await client.database.guilds.write(interaction.guild.id, {
49 ["moderation.mute.role"]: interaction.options.getRole("role").id
50 });
pineafan0bc04162022-07-25 17:22:26 +010051 }
52 }
Skyler Greyad002172022-08-16 18:48:26 +010053 let timedOut = false;
54 while (!timedOut) {
pineafan63fc5e22022-08-04 22:04:10 +010055 const config = await client.database.guilds.read(interaction.guild.id);
56 const moderation = config.getKey("moderation");
Skyler Grey75ea9172022-08-06 10:22:23 +010057 m = await interaction.editReply({
58 embeds: [
59 new EmojiEmbed()
60 .setTitle("Moderation Commands")
61 .setEmoji("PUNISH.BAN.GREEN")
62 .setStatus("Success")
63 .setDescription(
64 "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
65 "**Mute Role:** " +
Skyler Grey11236ba2022-08-08 21:13:33 +010066 (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
Skyler Grey75ea9172022-08-06 10:22:23 +010067 )
68 ],
69 components: [
70 new MessageActionRow().addComponents([
71 new MessageButton()
72 .setLabel("Warn")
73 .setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id"))
74 .setCustomId("warn")
75 .setStyle("SECONDARY"),
76 new MessageButton()
77 .setLabel("Mute")
78 .setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id"))
79 .setCustomId("mute")
80 .setStyle("SECONDARY"),
81 new MessageButton()
82 .setLabel("Nickname")
83 .setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id"))
84 .setCustomId("nickname")
85 .setStyle("SECONDARY")
86 ]),
87 new MessageActionRow().addComponents([
88 new MessageButton()
89 .setLabel("Kick")
90 .setEmoji(getEmojiByName("PUNISH.KICK.RED", "id"))
91 .setCustomId("kick")
92 .setStyle("SECONDARY"),
93 new MessageButton()
94 .setLabel("Softban")
95 .setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id"))
96 .setCustomId("softban")
97 .setStyle("SECONDARY"),
98 new MessageButton()
99 .setLabel("Ban")
100 .setEmoji(getEmojiByName("PUNISH.BAN.RED", "id"))
101 .setCustomId("ban")
102 .setStyle("SECONDARY")
103 ]),
104 new MessageActionRow().addComponents([
105 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100106 .setLabel(clicked === "clearMuteRole" ? "Click again to confirm" : "Clear mute role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
108 .setCustomId("clearMuteRole")
109 .setStyle("DANGER")
110 .setDisabled(!moderation.mute.role),
111 new MessageButton()
112 .setCustomId("timeout")
Skyler Grey11236ba2022-08-08 21:13:33 +0100113 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
114 .setStyle(moderation.mute.timeout ? "SUCCESS" : "DANGER")
115 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100116 ])
117 ]
118 });
pineafan0bc04162022-07-25 17:22:26 +0100119 let i;
120 try {
121 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100122 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100123 timedOut = true;
124 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 }
126 let chosen = moderation[i.customId] ?? { text: null, url: null };
pineafan0bc04162022-07-25 17:22:26 +0100127 if (i.component.customId === "clearMuteRole") {
pineafan63fc5e22022-08-04 22:04:10 +0100128 i.deferUpdate();
pineafan0bc04162022-07-25 17:22:26 +0100129 if (clicked === "clearMuteRole") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 await client.database.guilds.write(interaction.guild.id, {
131 "moderation.mute.role": null
132 });
133 } else {
134 clicked = "clearMuteRole";
135 }
pineafan63fc5e22022-08-04 22:04:10 +0100136 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 } else {
138 clicked = "";
139 }
pineafan0bc04162022-07-25 17:22:26 +0100140 if (i.component.customId === "timeout") {
pineafan63fc5e22022-08-04 22:04:10 +0100141 await i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100142 await client.database.guilds.write(interaction.guild.id, {
143 "moderation.mute.timeout": !moderation.mute.timeout
144 });
pineafan63fc5e22022-08-04 22:04:10 +0100145 continue;
pineafan0bc04162022-07-25 17:22:26 +0100146 } else if (i.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100147 await i.showModal(
148 new Discord.Modal()
149 .setCustomId("modal")
150 .setTitle(`Options for ${i.customId}`)
151 .addComponents(
152 new MessageActionRow<TextInputComponent>().addComponents(
153 new TextInputComponent()
154 .setCustomId("name")
155 .setLabel("Button text")
156 .setMaxLength(100)
157 .setRequired(false)
158 .setStyle("SHORT")
159 .setValue(chosen.text ?? "")
160 ),
161 new MessageActionRow<TextInputComponent>().addComponents(
162 new TextInputComponent()
163 .setCustomId("url")
Skyler Grey11236ba2022-08-08 21:13:33 +0100164 .setLabel("URL - Type {id} to insert the user's ID")
Skyler Grey75ea9172022-08-06 10:22:23 +0100165 .setMaxLength(2000)
166 .setRequired(false)
167 .setStyle("SHORT")
168 .setValue(chosen.link ?? "")
169 )
170 )
171 );
pineafan0bc04162022-07-25 17:22:26 +0100172 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 embeds: [
174 new EmojiEmbed()
175 .setTitle("Moderation Links")
Skyler Grey11236ba2022-08-08 21:13:33 +0100176 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100177 .setStatus("Success")
178 .setEmoji("GUILD.TICKET.OPEN")
179 ],
180 components: [
181 new MessageActionRow().addComponents([
182 new MessageButton()
183 .setLabel("Back")
184 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
185 .setStyle("PRIMARY")
186 .setCustomId("back")
187 ])
188 ]
pineafan0bc04162022-07-25 17:22:26 +0100189 });
190 let out;
191 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100192 out = await modalInteractionCollector(
193 m,
194 (m) => m.channel.id === interaction.channel.id,
195 (_) => true
196 );
197 } catch (e) {
198 continue;
199 }
pineafan0bc04162022-07-25 17:22:26 +0100200 if (out.fields) {
pineafan63fc5e22022-08-04 22:04:10 +0100201 const buttonText = out.fields.getTextInputValue("name");
Skyler Grey11236ba2022-08-08 21:13:33 +0100202 const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
pineafan63fc5e22022-08-04 22:04:10 +0100203 const current = chosen;
Skyler Grey11236ba2022-08-08 21:13:33 +0100204 if (current.text !== buttonText || current.link !== buttonLink) {
pineafan0bc04162022-07-25 17:22:26 +0100205 chosen = { text: buttonText, link: buttonLink };
Skyler Grey75ea9172022-08-06 10:22:23 +0100206 await client.database.guilds.write(interaction.guild.id, {
207 ["moderation." + i.customId]: {
208 text: buttonText,
209 link: buttonLink
210 }
211 });
pineafan0bc04162022-07-25 17:22:26 +0100212 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100213 } else {
214 continue;
215 }
pineafan0bc04162022-07-25 17:22:26 +0100216 }
217 }
pineafan63fc5e22022-08-04 22:04:10 +0100218};
pineafan0bc04162022-07-25 17:22:26 +0100219
Skyler Grey11236ba2022-08-08 21:13:33 +0100220const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 const member = interaction.member as Discord.GuildMember;
222 if (!member.permissions.has("MANAGE_GUILD"))
pineafan3a02ea32022-08-11 21:35:04 +0100223 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan0bc04162022-07-25 17:22:26 +0100224 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100225};
pineafan0bc04162022-07-25 17:22:26 +0100226
227export { command };
228export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100229export { check };