blob: fe6a181ebab772eb9405821a93907b39de730c67 [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 }
53 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +010054 const config = await client.database.guilds.read(interaction.guild.id);
55 const moderation = config.getKey("moderation");
Skyler Grey75ea9172022-08-06 10:22:23 +010056 m = await interaction.editReply({
57 embeds: [
58 new EmojiEmbed()
59 .setTitle("Moderation Commands")
60 .setEmoji("PUNISH.BAN.GREEN")
61 .setStatus("Success")
62 .setDescription(
63 "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
64 "**Mute Role:** " +
Skyler Grey11236ba2022-08-08 21:13:33 +010065 (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
Skyler Grey75ea9172022-08-06 10:22:23 +010066 )
67 ],
68 components: [
69 new MessageActionRow().addComponents([
70 new MessageButton()
71 .setLabel("Warn")
72 .setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id"))
73 .setCustomId("warn")
74 .setStyle("SECONDARY"),
75 new MessageButton()
76 .setLabel("Mute")
77 .setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id"))
78 .setCustomId("mute")
79 .setStyle("SECONDARY"),
80 new MessageButton()
81 .setLabel("Nickname")
82 .setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id"))
83 .setCustomId("nickname")
84 .setStyle("SECONDARY")
85 ]),
86 new MessageActionRow().addComponents([
87 new MessageButton()
88 .setLabel("Kick")
89 .setEmoji(getEmojiByName("PUNISH.KICK.RED", "id"))
90 .setCustomId("kick")
91 .setStyle("SECONDARY"),
92 new MessageButton()
93 .setLabel("Softban")
94 .setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id"))
95 .setCustomId("softban")
96 .setStyle("SECONDARY"),
97 new MessageButton()
98 .setLabel("Ban")
99 .setEmoji(getEmojiByName("PUNISH.BAN.RED", "id"))
100 .setCustomId("ban")
101 .setStyle("SECONDARY")
102 ]),
103 new MessageActionRow().addComponents([
104 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100105 .setLabel(clicked === "clearMuteRole" ? "Click again to confirm" : "Clear mute role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
107 .setCustomId("clearMuteRole")
108 .setStyle("DANGER")
109 .setDisabled(!moderation.mute.role),
110 new MessageButton()
111 .setCustomId("timeout")
Skyler Grey11236ba2022-08-08 21:13:33 +0100112 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
113 .setStyle(moderation.mute.timeout ? "SUCCESS" : "DANGER")
114 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 ])
116 ]
117 });
pineafan0bc04162022-07-25 17:22:26 +0100118 let i;
119 try {
120 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100121 } catch (e) {
122 return;
123 }
124 let chosen = moderation[i.customId] ?? { text: null, url: null };
pineafan0bc04162022-07-25 17:22:26 +0100125 if (i.component.customId === "clearMuteRole") {
pineafan63fc5e22022-08-04 22:04:10 +0100126 i.deferUpdate();
pineafan0bc04162022-07-25 17:22:26 +0100127 if (clicked === "clearMuteRole") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 await client.database.guilds.write(interaction.guild.id, {
129 "moderation.mute.role": null
130 });
131 } else {
132 clicked = "clearMuteRole";
133 }
pineafan63fc5e22022-08-04 22:04:10 +0100134 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100135 } else {
136 clicked = "";
137 }
pineafan0bc04162022-07-25 17:22:26 +0100138 if (i.component.customId === "timeout") {
pineafan63fc5e22022-08-04 22:04:10 +0100139 await i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100140 await client.database.guilds.write(interaction.guild.id, {
141 "moderation.mute.timeout": !moderation.mute.timeout
142 });
pineafan63fc5e22022-08-04 22:04:10 +0100143 continue;
pineafan0bc04162022-07-25 17:22:26 +0100144 } else if (i.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100145 await i.showModal(
146 new Discord.Modal()
147 .setCustomId("modal")
148 .setTitle(`Options for ${i.customId}`)
149 .addComponents(
150 new MessageActionRow<TextInputComponent>().addComponents(
151 new TextInputComponent()
152 .setCustomId("name")
153 .setLabel("Button text")
154 .setMaxLength(100)
155 .setRequired(false)
156 .setStyle("SHORT")
157 .setValue(chosen.text ?? "")
158 ),
159 new MessageActionRow<TextInputComponent>().addComponents(
160 new TextInputComponent()
161 .setCustomId("url")
Skyler Grey11236ba2022-08-08 21:13:33 +0100162 .setLabel("URL - Type {id} to insert the user's ID")
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 .setMaxLength(2000)
164 .setRequired(false)
165 .setStyle("SHORT")
166 .setValue(chosen.link ?? "")
167 )
168 )
169 );
pineafan0bc04162022-07-25 17:22:26 +0100170 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100171 embeds: [
172 new EmojiEmbed()
173 .setTitle("Moderation Links")
Skyler Grey11236ba2022-08-08 21:13:33 +0100174 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 .setStatus("Success")
176 .setEmoji("GUILD.TICKET.OPEN")
177 ],
178 components: [
179 new MessageActionRow().addComponents([
180 new MessageButton()
181 .setLabel("Back")
182 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
183 .setStyle("PRIMARY")
184 .setCustomId("back")
185 ])
186 ]
pineafan0bc04162022-07-25 17:22:26 +0100187 });
188 let out;
189 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100190 out = await modalInteractionCollector(
191 m,
192 (m) => m.channel.id === interaction.channel.id,
193 (_) => true
194 );
195 } catch (e) {
196 continue;
197 }
pineafan0bc04162022-07-25 17:22:26 +0100198 if (out.fields) {
pineafan63fc5e22022-08-04 22:04:10 +0100199 const buttonText = out.fields.getTextInputValue("name");
Skyler Grey11236ba2022-08-08 21:13:33 +0100200 const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
pineafan63fc5e22022-08-04 22:04:10 +0100201 const current = chosen;
Skyler Grey11236ba2022-08-08 21:13:33 +0100202 if (current.text !== buttonText || current.link !== buttonLink) {
pineafan0bc04162022-07-25 17:22:26 +0100203 chosen = { text: buttonText, link: buttonLink };
Skyler Grey75ea9172022-08-06 10:22:23 +0100204 await client.database.guilds.write(interaction.guild.id, {
205 ["moderation." + i.customId]: {
206 text: buttonText,
207 link: buttonLink
208 }
209 });
pineafan0bc04162022-07-25 17:22:26 +0100210 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100211 } else {
212 continue;
213 }
pineafan0bc04162022-07-25 17:22:26 +0100214 }
215 }
pineafan63fc5e22022-08-04 22:04:10 +0100216};
pineafan0bc04162022-07-25 17:22:26 +0100217
Skyler Grey11236ba2022-08-08 21:13:33 +0100218const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100219 const member = interaction.member as Discord.GuildMember;
220 if (!member.permissions.has("MANAGE_GUILD"))
pineafan3a02ea32022-08-11 21:35:04 +0100221 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan0bc04162022-07-25 17:22:26 +0100222 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100223};
pineafan0bc04162022-07-25 17:22:26 +0100224
225export { command };
226export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100227export { check };