blob: df2cdb4e91469389c9debaeee6584cc225a425ed [file] [log] [blame]
pineafan0bc04162022-07-25 17:22:26 +01001import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
2import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
3import getEmojiByName from "../../utils/getEmojiByName.js";
4import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
5import { WrappedCheck } from "jshaiku";
6import client from "../../utils/client.js";
7import { modalInteractionCollector } from "../../utils/dualCollector.js";
8import confirmationMessage from "../../utils/confirmationMessage.js";
9import keyValueList from "../../utils/generateKeyValueList.js";
10
11const command = (builder: SlashCommandSubcommandBuilder) =>
12 builder
13 .setName("commands")
14 .setDescription("Links and text shown to a user after a moderator action is performed")
15 .addRoleOption(o => o.setName("role").setDescription("The role given when a member is muted"))
16
17const callback = async (interaction: CommandInteraction): Promise<any> => {
18 await interaction.reply({embeds: [new EmojiEmbed()
19 .setTitle("Loading")
20 .setStatus("Danger")
21 .setEmoji("NUCLEUS.LOADING")
22 ], ephemeral: true, fetchReply: true});
23 let m;
24 let clicked = "";
25 if (interaction.options.getRole("role")) {
26 let confirmation = await new confirmationMessage(interaction)
27 .setEmoji("GUILD.ROLES.DELETE")
28 .setTitle("Moderation Commands")
29 .setDescription(keyValueList({
30 role: `<@&${interaction.options.getRole("role").id}>`,
31 }))
32 .setColor("Danger")
33 .send(true)
34 if (confirmation.cancelled) return await interaction.editReply({embeds: [new EmojiEmbed()
35 .setTitle("Moderation Commands")
36 .setDescription("No changes were made")
37 .setStatus("Success")
38 .setEmoji("GUILD.ROLES.CREATE")
39 ]})
40 if (confirmation.success) {
41 await client.database.guilds.write(interaction.guild.id, {["moderation.mute.role"]: interaction.options.getRole("role").id});
42 }
43 }
44 while (true) {
45 let config = await client.database.guilds.read(interaction.guild.id);
46 let moderation = config.getKey("moderation");
47 m = await interaction.editReply({embeds: [new EmojiEmbed()
48 .setTitle("Moderation Commands")
49 .setEmoji("PUNISH.BAN.GREEN")
50 .setStatus("Success")
51 .setDescription(
52 "These links are shown below the message sent in a user's DM when they are warned, banned, etc.\n\n" +
53 `**Mute Role:** ` + (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
54 )
55 ], components: [new MessageActionRow().addComponents([
56 new MessageButton().setLabel("Warn").setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id")).setCustomId("warn").setStyle("SECONDARY"),
57 new MessageButton().setLabel("Mute").setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id")).setCustomId("mute").setStyle("SECONDARY"),
58 new MessageButton().setLabel("Nickname").setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id")).setCustomId("nickname").setStyle("SECONDARY")
59 ]), new MessageActionRow().addComponents([
60 new MessageButton().setLabel("Kick").setEmoji(getEmojiByName("PUNISH.KICK.RED", "id")).setCustomId("kick").setStyle("SECONDARY"),
61 new MessageButton().setLabel("Softban").setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id")).setCustomId("softban").setStyle("SECONDARY"),
62 new MessageButton().setLabel("Ban").setEmoji(getEmojiByName("PUNISH.BAN.RED", "id")).setCustomId("ban").setStyle("SECONDARY")
63 ]), new MessageActionRow().addComponents([
64 new MessageButton().setLabel(
65 clicked === "clearMuteRole" ? "Click again to confirm" : "Clear mute role"
66 ).setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setCustomId("clearMuteRole").setStyle("DANGER").setDisabled(!moderation.mute.role),
67 new MessageButton()
68 .setCustomId("timeout")
69 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
70 .setStyle(moderation.mute.timeout ? "SUCCESS" : "DANGER")
71 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
72 ])]});
73 let i;
74 try {
75 i = await m.awaitMessageComponent({ time: 300000 });
76 } catch (e) { return }
77 let chosen = moderation[i.customId] ?? {text: null, url: null};
78 if (i.component.customId === "clearMuteRole") {
79 if (clicked === "clearMuteRole") {
80 await client.database.guilds.write(interaction.guild.id, { moderation: { mute: { role: null } } });
81 } else { clicked = "clearMuteRole" }
82 } else { clicked = "" }
83 if (i.component.customId === "timeout") {
84 await i.deferUpdate()
85 await client.database.guilds.write(interaction.guild.id, { moderation: { mute: { timeout: !moderation.mute.timeout } } });
86 } else if (i.customId) {
87 await i.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Options for ${i.customId}`).addComponents(
88 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
89 .setCustomId("name")
90 .setLabel("Button text")
91 .setMaxLength(100)
92 .setRequired(false)
93 .setStyle("SHORT")
94 .setValue(chosen.text ?? "")
95 ),
96 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
97 .setCustomId("url")
98 .setLabel("URL - Type {id} to insert the user's ID")
99 .setMaxLength(2000)
100 .setRequired(false)
101 .setStyle("SHORT")
102 .setValue(chosen.link ?? "")
103 )
104 ))
105 await interaction.editReply({
106 embeds: [new EmojiEmbed()
107 .setTitle("Moderation Links")
108 .setDescription("Modal opened. If you can't see it, click back and try again.")
109 .setStatus("Success")
110 .setEmoji("GUILD.TICKET.OPEN")
111 ], components: [new MessageActionRow().addComponents([new MessageButton()
112 .setLabel("Back")
113 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
114 .setStyle("PRIMARY")
115 .setCustomId("back")
116 ])]
117 });
118 let out;
119 try {
120 out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => true)
121 } catch (e) { continue }
122 if (out.fields) {
123 let buttonText = out.fields.getTextInputValue("name");
124 let buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
125 let current = chosen;
126 if (current.text !== buttonText || current.link !== buttonLink) {
127 chosen = { text: buttonText, link: buttonLink };
128 await client.database.guilds.write(interaction.guild.id, { ["moderation" + i.customId]: { text: buttonText, link: buttonLink }});
129 }
130 } else { continue }
131 }
132 }
133}
134
135
136const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
137 let member = (interaction.member as Discord.GuildMember)
138 if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage server permission to use this command"
139 return true;
140}
141
142export { command };
143export { callback };
144export { check };