blob: 6ee6e1e837aca339dacde0396dcc559a8da013f1 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../utils/defaults.js";
Skyler Greyda16adf2023-03-05 10:22:12 +00002import Discord, {
3 CommandInteraction,
4 ActionRowBuilder,
5 ButtonBuilder,
6 ButtonStyle,
7 ButtonComponent,
8 TextInputBuilder,
9 RoleSelectMenuBuilder
10} from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +010011import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
12import getEmojiByName from "../../utils/getEmojiByName.js";
TheCodedProff86ba092023-01-27 17:10:07 -050013import type { SlashCommandSubcommandBuilder } from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +010014import client from "../../utils/client.js";
15import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan0bc04162022-07-25 17:22:26 +010016
17const command = (builder: SlashCommandSubcommandBuilder) =>
18 builder
TheCodedProf1f675042023-02-16 17:01:29 -050019 .setName("moderation")
Skyler Greyda16adf2023-03-05 10:22:12 +000020 .setDescription("Links and text shown to a user after a moderator action is performed");
pineafan0bc04162022-07-25 17:22:26 +010021
TheCodedProf1f675042023-02-16 17:01:29 -050022const callback = async (interaction: CommandInteraction): Promise<void> => {
TheCodedProf01cba762023-02-18 15:55:05 -050023 const m = await interaction.reply({
Skyler Grey75ea9172022-08-06 10:22:23 +010024 embeds: LoadingEmbed,
25 ephemeral: true,
26 fetchReply: true
27 });
Skyler Greyad002172022-08-16 18:48:26 +010028 let timedOut = false;
29 while (!timedOut) {
TheCodedProfd9636e82023-01-17 22:13:06 -050030 const config = await client.database.guilds.read(interaction.guild!.id);
PineaFan9b2ac4d2023-01-18 14:41:07 +000031 const moderation = config.moderation;
Skyler Greyda16adf2023-03-05 10:22:12 +000032 console.log(moderation);
TheCodedProf01cba762023-02-18 15:55:05 -050033 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010034 embeds: [
35 new EmojiEmbed()
36 .setTitle("Moderation Commands")
37 .setEmoji("PUNISH.BAN.GREEN")
38 .setStatus("Success")
39 .setDescription(
40 "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
Skyler Greyda16adf2023-03-05 10:22:12 +000041 "**Mute Role:** " +
42 (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
Skyler Grey75ea9172022-08-06 10:22:23 +010043 )
44 ],
45 components: [
TheCodedProfd9636e82023-01-17 22:13:06 -050046 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040047 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010048 .setLabel("Warn")
49 .setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id"))
50 .setCustomId("warn")
TheCodedProf21c08592022-09-13 14:14:43 -040051 .setStyle(ButtonStyle.Secondary),
52 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010053 .setLabel("Mute")
54 .setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id"))
55 .setCustomId("mute")
TheCodedProf21c08592022-09-13 14:14:43 -040056 .setStyle(ButtonStyle.Secondary),
57 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010058 .setLabel("Nickname")
59 .setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id"))
60 .setCustomId("nickname")
TheCodedProf21c08592022-09-13 14:14:43 -040061 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +010062 ]),
TheCodedProfd9636e82023-01-17 22:13:06 -050063 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040064 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010065 .setLabel("Kick")
66 .setEmoji(getEmojiByName("PUNISH.KICK.RED", "id"))
67 .setCustomId("kick")
TheCodedProf21c08592022-09-13 14:14:43 -040068 .setStyle(ButtonStyle.Secondary),
69 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010070 .setLabel("Softban")
71 .setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id"))
72 .setCustomId("softban")
TheCodedProf21c08592022-09-13 14:14:43 -040073 .setStyle(ButtonStyle.Secondary),
74 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010075 .setLabel("Ban")
76 .setEmoji(getEmojiByName("PUNISH.BAN.RED", "id"))
77 .setCustomId("ban")
TheCodedProf21c08592022-09-13 14:14:43 -040078 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +010079 ]),
TheCodedProfd9636e82023-01-17 22:13:06 -050080 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040081 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010082 .setCustomId("timeout")
Skyler Grey11236ba2022-08-08 21:13:33 +010083 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
TheCodedProf21c08592022-09-13 14:14:43 -040084 .setStyle(moderation.mute.timeout ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey11236ba2022-08-08 21:13:33 +010085 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
TheCodedProf1f675042023-02-16 17:01:29 -050086 ]),
87 new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
Skyler Greyda16adf2023-03-05 10:22:12 +000088 new RoleSelectMenuBuilder().setCustomId("muteRole").setPlaceholder("Select a new mute role")
TheCodedProf1f675042023-02-16 17:01:29 -050089 )
Skyler Grey75ea9172022-08-06 10:22:23 +010090 ]
91 });
pineafan0bc04162022-07-25 17:22:26 +010092 let i;
93 try {
PineaFan0d06edc2023-01-17 22:10:31 +000094 i = await m.awaitMessageComponent({
95 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +000096 filter: (i) => {
97 return (
98 i.user.id === interaction.user.id &&
99 i.channel!.id === interaction.channel!.id &&
100 i.message.id === m.id
101 );
102 }
PineaFan0d06edc2023-01-17 22:10:31 +0000103 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100104 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100105 timedOut = true;
106 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 }
TheCodedProfd9636e82023-01-17 22:13:06 -0500108 type modIDs = "mute" | "kick" | "ban" | "softban" | "warn" | "role";
PineaFan9b2ac4d2023-01-18 14:41:07 +0000109 let chosen = moderation[i.customId as modIDs];
TheCodedProf1f675042023-02-16 17:01:29 -0500110 if (i.isRoleSelectMenu()) {
TheCodedProf267563a2023-01-21 17:00:57 -0500111 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500112 await client.database.guilds.write(interaction.guild!.id, {
113 "moderation.mute.role": i.values[0]!
114 });
pineafan63fc5e22022-08-04 22:04:10 +0100115 continue;
TheCodedProf1f675042023-02-16 17:01:29 -0500116 } else if ((i.component as ButtonComponent).customId === "timeout") {
pineafan63fc5e22022-08-04 22:04:10 +0100117 await i.deferUpdate();
TheCodedProfd9636e82023-01-17 22:13:06 -0500118 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 "moderation.mute.timeout": !moderation.mute.timeout
120 });
pineafan63fc5e22022-08-04 22:04:10 +0100121 continue;
pineafan0bc04162022-07-25 17:22:26 +0100122 } else if (i.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100123 await i.showModal(
TheCodedProfd9636e82023-01-17 22:13:06 -0500124 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 .setCustomId("modal")
126 .setTitle(`Options for ${i.customId}`)
127 .addComponents(
Skyler Greyda16adf2023-03-05 10:22:12 +0000128 new ActionRowBuilder<TextInputBuilder>()
129 .addComponents(
130 new TextInputBuilder()
131 .setCustomId("name")
132 .setLabel("Button text")
133 .setMaxLength(100)
134 .setRequired(false)
135 .setStyle(Discord.TextInputStyle.Short)
136 .setValue(chosen.text ?? "")
137 )
138 .toJSON(),
139 new ActionRowBuilder<TextInputBuilder>()
140 .addComponents(
141 new TextInputBuilder()
142 .setCustomId("url")
143 .setLabel("URL - Type {id} to insert the user's ID")
144 .setMaxLength(2000)
145 .setRequired(false)
146 .setStyle(Discord.TextInputStyle.Short)
147 .setValue(chosen.link ?? "")
148 )
149 .toJSON()
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 )
151 );
pineafan0bc04162022-07-25 17:22:26 +0100152 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100153 embeds: [
154 new EmojiEmbed()
155 .setTitle("Moderation Links")
Skyler Grey11236ba2022-08-08 21:13:33 +0100156 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100157 .setStatus("Success")
158 .setEmoji("GUILD.TICKET.OPEN")
159 ],
160 components: [
TheCodedProfd9636e82023-01-17 22:13:06 -0500161 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400162 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 .setLabel("Back")
164 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400165 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100166 .setCustomId("back")
167 ])
168 ]
pineafan0bc04162022-07-25 17:22:26 +0100169 });
PineaFan9b2ac4d2023-01-18 14:41:07 +0000170 let out: Discord.ModalSubmitInteraction | null;
pineafan0bc04162022-07-25 17:22:26 +0100171 try {
Skyler Greyda16adf2023-03-05 10:22:12 +0000172 out = (await modalInteractionCollector(m, interaction.user)) as Discord.ModalSubmitInteraction | null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 } catch (e) {
174 continue;
175 }
Skyler Greyda16adf2023-03-05 10:22:12 +0000176 if (!out || out.isButton()) continue;
PineaFan9b2ac4d2023-01-18 14:41:07 +0000177 const buttonText = out.fields.getTextInputValue("name");
178 const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
179 const current = chosen;
180 if (current.text !== buttonText || current.link !== buttonLink) {
181 chosen = { text: buttonText, link: buttonLink };
182 await client.database.guilds.write(interaction.guild!.id, {
183 ["moderation." + i.customId]: {
184 text: buttonText,
185 link: buttonLink
186 }
187 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100188 }
pineafan0bc04162022-07-25 17:22:26 +0100189 }
190 }
Skyler Greyda16adf2023-03-05 10:22:12 +0000191 await interaction.deleteReply();
pineafan63fc5e22022-08-04 22:04:10 +0100192};
pineafan0bc04162022-07-25 17:22:26 +0100193
TheCodedProff86ba092023-01-27 17:10:07 -0500194const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100195 const member = interaction.member as Discord.GuildMember;
PineaFan0d06edc2023-01-17 22:10:31 +0000196 if (!member.permissions.has("ManageGuild"))
197 return "You must have the *Manage Server* permission to use this command";
pineafan0bc04162022-07-25 17:22:26 +0100198 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100199};
pineafan0bc04162022-07-25 17:22:26 +0100200
201export { command };
202export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100203export { check };