blob: ffd3063f532c1a2a4f24b44e751b36ba9de75589 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../utils/defaults.js";
TheCodedProf1f675042023-02-16 17:01:29 -05002import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle, ButtonComponent, TextInputBuilder, Message, RoleSelectMenuBuilder } from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
4import getEmojiByName from "../../utils/getEmojiByName.js";
TheCodedProff86ba092023-01-27 17:10:07 -05005import type { SlashCommandSubcommandBuilder } from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +01006import client from "../../utils/client.js";
7import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan0bc04162022-07-25 17:22:26 +01008
9const command = (builder: SlashCommandSubcommandBuilder) =>
10 builder
TheCodedProf1f675042023-02-16 17:01:29 -050011 .setName("moderation")
Skyler Grey11236ba2022-08-08 21:13:33 +010012 .setDescription("Links and text shown to a user after a moderator action is performed")
pineafan0bc04162022-07-25 17:22:26 +010013
TheCodedProf1f675042023-02-16 17:01:29 -050014const callback = async (interaction: CommandInteraction): Promise<void> => {
Skyler Grey75ea9172022-08-06 10:22:23 +010015 await interaction.reply({
16 embeds: LoadingEmbed,
17 ephemeral: true,
18 fetchReply: true
19 });
TheCodedProf267563a2023-01-21 17:00:57 -050020 let m: Message;
Skyler Greyad002172022-08-16 18:48:26 +010021 let timedOut = false;
22 while (!timedOut) {
TheCodedProfd9636e82023-01-17 22:13:06 -050023 const config = await client.database.guilds.read(interaction.guild!.id);
PineaFan9b2ac4d2023-01-18 14:41:07 +000024 const moderation = config.moderation;
Skyler Grey75ea9172022-08-06 10:22:23 +010025 m = await interaction.editReply({
26 embeds: [
27 new EmojiEmbed()
28 .setTitle("Moderation Commands")
29 .setEmoji("PUNISH.BAN.GREEN")
30 .setStatus("Success")
31 .setDescription(
32 "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
TheCodedProf1f675042023-02-16 17:01:29 -050033 "**Mute Role:** " + (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
Skyler Grey75ea9172022-08-06 10:22:23 +010034 )
35 ],
36 components: [
TheCodedProfd9636e82023-01-17 22:13:06 -050037 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040038 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010039 .setLabel("Warn")
40 .setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id"))
41 .setCustomId("warn")
TheCodedProf21c08592022-09-13 14:14:43 -040042 .setStyle(ButtonStyle.Secondary),
43 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010044 .setLabel("Mute")
45 .setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id"))
46 .setCustomId("mute")
TheCodedProf21c08592022-09-13 14:14:43 -040047 .setStyle(ButtonStyle.Secondary),
48 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010049 .setLabel("Nickname")
50 .setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id"))
51 .setCustomId("nickname")
TheCodedProf21c08592022-09-13 14:14:43 -040052 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +010053 ]),
TheCodedProfd9636e82023-01-17 22:13:06 -050054 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040055 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010056 .setLabel("Kick")
57 .setEmoji(getEmojiByName("PUNISH.KICK.RED", "id"))
58 .setCustomId("kick")
TheCodedProf21c08592022-09-13 14:14:43 -040059 .setStyle(ButtonStyle.Secondary),
60 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010061 .setLabel("Softban")
62 .setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id"))
63 .setCustomId("softban")
TheCodedProf21c08592022-09-13 14:14:43 -040064 .setStyle(ButtonStyle.Secondary),
65 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010066 .setLabel("Ban")
67 .setEmoji(getEmojiByName("PUNISH.BAN.RED", "id"))
68 .setCustomId("ban")
TheCodedProf21c08592022-09-13 14:14:43 -040069 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +010070 ]),
TheCodedProfd9636e82023-01-17 22:13:06 -050071 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040072 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010073 .setCustomId("timeout")
Skyler Grey11236ba2022-08-08 21:13:33 +010074 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
TheCodedProf21c08592022-09-13 14:14:43 -040075 .setStyle(moderation.mute.timeout ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey11236ba2022-08-08 21:13:33 +010076 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
TheCodedProf1f675042023-02-16 17:01:29 -050077 ]),
78 new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
79 new RoleSelectMenuBuilder()
80 .setCustomId("muteRole")
81 .setPlaceholder("Select a new mute role")
82 )
Skyler Grey75ea9172022-08-06 10:22:23 +010083 ]
84 });
pineafan0bc04162022-07-25 17:22:26 +010085 let i;
86 try {
PineaFan0d06edc2023-01-17 22:10:31 +000087 i = await m.awaitMessageComponent({
88 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -050089 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id && i.message.id === m.id }
PineaFan0d06edc2023-01-17 22:10:31 +000090 });
Skyler Grey75ea9172022-08-06 10:22:23 +010091 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +010092 timedOut = true;
93 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +010094 }
TheCodedProfd9636e82023-01-17 22:13:06 -050095 type modIDs = "mute" | "kick" | "ban" | "softban" | "warn" | "role";
PineaFan9b2ac4d2023-01-18 14:41:07 +000096 let chosen = moderation[i.customId as modIDs];
TheCodedProf1f675042023-02-16 17:01:29 -050097 if (i.isRoleSelectMenu()) {
TheCodedProf267563a2023-01-21 17:00:57 -050098 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -050099 await client.database.guilds.write(interaction.guild!.id, {
100 "moderation.mute.role": i.values[0]!
101 });
pineafan63fc5e22022-08-04 22:04:10 +0100102 continue;
TheCodedProf1f675042023-02-16 17:01:29 -0500103 } else if ((i.component as ButtonComponent).customId === "timeout") {
pineafan63fc5e22022-08-04 22:04:10 +0100104 await i.deferUpdate();
TheCodedProfd9636e82023-01-17 22:13:06 -0500105 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 "moderation.mute.timeout": !moderation.mute.timeout
107 });
pineafan63fc5e22022-08-04 22:04:10 +0100108 continue;
pineafan0bc04162022-07-25 17:22:26 +0100109 } else if (i.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100110 await i.showModal(
TheCodedProfd9636e82023-01-17 22:13:06 -0500111 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100112 .setCustomId("modal")
113 .setTitle(`Options for ${i.customId}`)
114 .addComponents(
TheCodedProfd9636e82023-01-17 22:13:06 -0500115 new ActionRowBuilder<TextInputBuilder>().addComponents(
116 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100117 .setCustomId("name")
118 .setLabel("Button text")
119 .setMaxLength(100)
120 .setRequired(false)
TheCodedProfd9636e82023-01-17 22:13:06 -0500121 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100122 .setValue(chosen.text ?? "")
TheCodedProfd9636e82023-01-17 22:13:06 -0500123 ).toJSON(),
124 new ActionRowBuilder<TextInputBuilder>().addComponents(
125 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100126 .setCustomId("url")
Skyler Grey11236ba2022-08-08 21:13:33 +0100127 .setLabel("URL - Type {id} to insert the user's ID")
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 .setMaxLength(2000)
129 .setRequired(false)
TheCodedProfd9636e82023-01-17 22:13:06 -0500130 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 .setValue(chosen.link ?? "")
TheCodedProfd9636e82023-01-17 22:13:06 -0500132 ).toJSON()
Skyler Grey75ea9172022-08-06 10:22:23 +0100133 )
134 );
pineafan0bc04162022-07-25 17:22:26 +0100135 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100136 embeds: [
137 new EmojiEmbed()
138 .setTitle("Moderation Links")
Skyler Grey11236ba2022-08-08 21:13:33 +0100139 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100140 .setStatus("Success")
141 .setEmoji("GUILD.TICKET.OPEN")
142 ],
143 components: [
TheCodedProfd9636e82023-01-17 22:13:06 -0500144 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400145 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 .setLabel("Back")
147 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400148 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100149 .setCustomId("back")
150 ])
151 ]
pineafan0bc04162022-07-25 17:22:26 +0100152 });
PineaFan9b2ac4d2023-01-18 14:41:07 +0000153 let out: Discord.ModalSubmitInteraction | null;
pineafan0bc04162022-07-25 17:22:26 +0100154 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100155 out = await modalInteractionCollector(
156 m,
TheCodedProfd9636e82023-01-17 22:13:06 -0500157 (m) => m.channel!.id === interaction.channel!.id,
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 (_) => true
PineaFan9b2ac4d2023-01-18 14:41:07 +0000159 ) as Discord.ModalSubmitInteraction | null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 } catch (e) {
161 continue;
162 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500163 if (!out || out.isButton()) continue
PineaFan9b2ac4d2023-01-18 14:41:07 +0000164 const buttonText = out.fields.getTextInputValue("name");
165 const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
166 const current = chosen;
167 if (current.text !== buttonText || current.link !== buttonLink) {
168 chosen = { text: buttonText, link: buttonLink };
169 await client.database.guilds.write(interaction.guild!.id, {
170 ["moderation." + i.customId]: {
171 text: buttonText,
172 link: buttonLink
173 }
174 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 }
pineafan0bc04162022-07-25 17:22:26 +0100176 }
177 }
pineafan63fc5e22022-08-04 22:04:10 +0100178};
pineafan0bc04162022-07-25 17:22:26 +0100179
TheCodedProff86ba092023-01-27 17:10:07 -0500180const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100181 const member = interaction.member as Discord.GuildMember;
PineaFan0d06edc2023-01-17 22:10:31 +0000182 if (!member.permissions.has("ManageGuild"))
183 return "You must have the *Manage Server* permission to use this command";
pineafan0bc04162022-07-25 17:22:26 +0100184 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100185};
pineafan0bc04162022-07-25 17:22:26 +0100186
187export { command };
188export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100189export { check };