blob: 336e53a22ab67d7cca5e9bdc8101f7f9a2782996 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../utils/defaults.js";
TheCodedProf01cba762023-02-18 15:55:05 -05002import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, ButtonStyle, ButtonComponent, TextInputBuilder, 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> => {
TheCodedProf01cba762023-02-18 15:55:05 -050015 const m = await interaction.reply({
Skyler Grey75ea9172022-08-06 10:22:23 +010016 embeds: LoadingEmbed,
17 ephemeral: true,
18 fetchReply: true
19 });
Skyler Greyad002172022-08-16 18:48:26 +010020 let timedOut = false;
21 while (!timedOut) {
TheCodedProfd9636e82023-01-17 22:13:06 -050022 const config = await client.database.guilds.read(interaction.guild!.id);
PineaFan9b2ac4d2023-01-18 14:41:07 +000023 const moderation = config.moderation;
TheCodedProff8ef7942023-03-03 15:32:32 -050024 console.log(moderation)
TheCodedProf01cba762023-02-18 15:55:05 -050025 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010026 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 {
TheCodedProf01cba762023-02-18 15:55:05 -0500155 out = await modalInteractionCollector(m, interaction.user) as Discord.ModalSubmitInteraction | null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100156 } catch (e) {
157 continue;
158 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500159 if (!out || out.isButton()) continue
PineaFan9b2ac4d2023-01-18 14:41:07 +0000160 const buttonText = out.fields.getTextInputValue("name");
161 const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
162 const current = chosen;
163 if (current.text !== buttonText || current.link !== buttonLink) {
164 chosen = { text: buttonText, link: buttonLink };
165 await client.database.guilds.write(interaction.guild!.id, {
166 ["moderation." + i.customId]: {
167 text: buttonText,
168 link: buttonLink
169 }
170 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100171 }
pineafan0bc04162022-07-25 17:22:26 +0100172 }
173 }
TheCodedProf01cba762023-02-18 15:55:05 -0500174 await interaction.deleteReply()
pineafan63fc5e22022-08-04 22:04:10 +0100175};
pineafan0bc04162022-07-25 17:22:26 +0100176
TheCodedProff86ba092023-01-27 17:10:07 -0500177const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100178 const member = interaction.member as Discord.GuildMember;
PineaFan0d06edc2023-01-17 22:10:31 +0000179 if (!member.permissions.has("ManageGuild"))
180 return "You must have the *Manage Server* permission to use this command";
pineafan0bc04162022-07-25 17:22:26 +0100181 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100182};
pineafan0bc04162022-07-25 17:22:26 +0100183
184export { command };
185export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100186export { check };