blob: 23d5c668dc5176ab145478baa2600d15da0daf20 [file] [log] [blame]
pineafane23c4ec2022-07-27 21:56:27 +01001import { LoadingEmbed } from './../../utils/defaultEmbeds.js';
pineafan0bc04162022-07-25 17:22:26 +01002import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
3import 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
14 .setName("commands")
15 .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"))
17
18const callback = async (interaction: CommandInteraction): Promise<any> => {
pineafane23c4ec2022-07-27 21:56:27 +010019 await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
pineafan0bc04162022-07-25 17:22:26 +010020 let m;
21 let clicked = "";
22 if (interaction.options.getRole("role")) {
23 let confirmation = await new confirmationMessage(interaction)
24 .setEmoji("GUILD.ROLES.DELETE")
25 .setTitle("Moderation Commands")
26 .setDescription(keyValueList({
27 role: `<@&${interaction.options.getRole("role").id}>`,
28 }))
29 .setColor("Danger")
30 .send(true)
31 if (confirmation.cancelled) return await interaction.editReply({embeds: [new EmojiEmbed()
32 .setTitle("Moderation Commands")
33 .setDescription("No changes were made")
34 .setStatus("Success")
35 .setEmoji("GUILD.ROLES.CREATE")
36 ]})
37 if (confirmation.success) {
38 await client.database.guilds.write(interaction.guild.id, {["moderation.mute.role"]: interaction.options.getRole("role").id});
39 }
40 }
41 while (true) {
42 let config = await client.database.guilds.read(interaction.guild.id);
43 let moderation = config.getKey("moderation");
44 m = await interaction.editReply({embeds: [new EmojiEmbed()
45 .setTitle("Moderation Commands")
46 .setEmoji("PUNISH.BAN.GREEN")
47 .setStatus("Success")
48 .setDescription(
pineafane23c4ec2022-07-27 21:56:27 +010049 "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
pineafan0bc04162022-07-25 17:22:26 +010050 `**Mute Role:** ` + (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
51 )
52 ], components: [new MessageActionRow().addComponents([
53 new MessageButton().setLabel("Warn").setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id")).setCustomId("warn").setStyle("SECONDARY"),
54 new MessageButton().setLabel("Mute").setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id")).setCustomId("mute").setStyle("SECONDARY"),
55 new MessageButton().setLabel("Nickname").setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id")).setCustomId("nickname").setStyle("SECONDARY")
56 ]), new MessageActionRow().addComponents([
57 new MessageButton().setLabel("Kick").setEmoji(getEmojiByName("PUNISH.KICK.RED", "id")).setCustomId("kick").setStyle("SECONDARY"),
58 new MessageButton().setLabel("Softban").setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id")).setCustomId("softban").setStyle("SECONDARY"),
59 new MessageButton().setLabel("Ban").setEmoji(getEmojiByName("PUNISH.BAN.RED", "id")).setCustomId("ban").setStyle("SECONDARY")
60 ]), new MessageActionRow().addComponents([
61 new MessageButton().setLabel(
62 clicked === "clearMuteRole" ? "Click again to confirm" : "Clear mute role"
63 ).setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setCustomId("clearMuteRole").setStyle("DANGER").setDisabled(!moderation.mute.role),
64 new MessageButton()
65 .setCustomId("timeout")
66 .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
67 .setStyle(moderation.mute.timeout ? "SUCCESS" : "DANGER")
68 .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
69 ])]});
70 let i;
71 try {
72 i = await m.awaitMessageComponent({ time: 300000 });
73 } catch (e) { return }
74 let chosen = moderation[i.customId] ?? {text: null, url: null};
75 if (i.component.customId === "clearMuteRole") {
pineafane23c4ec2022-07-27 21:56:27 +010076 i.deferUpdate()
pineafan0bc04162022-07-25 17:22:26 +010077 if (clicked === "clearMuteRole") {
pineafane23c4ec2022-07-27 21:56:27 +010078 await client.database.guilds.write(interaction.guild.id, {"moderation.mute.role": null });
pineafan0bc04162022-07-25 17:22:26 +010079 } else { clicked = "clearMuteRole" }
pineafane23c4ec2022-07-27 21:56:27 +010080 continue
pineafan0bc04162022-07-25 17:22:26 +010081 } else { clicked = "" }
82 if (i.component.customId === "timeout") {
83 await i.deferUpdate()
pineafane23c4ec2022-07-27 21:56:27 +010084 await client.database.guilds.write(interaction.guild.id, {"moderation.mute.timeout": !moderation.mute.timeout } );
85 continue
pineafan0bc04162022-07-25 17:22:26 +010086 } 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 {
pineafane23c4ec2022-07-27 21:56:27 +0100120 out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => true)
pineafan0bc04162022-07-25 17:22:26 +0100121 } 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 };
pineafane23c4ec2022-07-27 21:56:27 +0100128 await client.database.guilds.write(interaction.guild.id, { ["moderation." + i.customId]: { text: buttonText, link: buttonLink }});
pineafan0bc04162022-07-25 17:22:26 +0100129 }
130 } else { continue }
131 }
132 }
133}
134
135
136const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
137 let member = (interaction.member as Discord.GuildMember)
pineafane23c4ec2022-07-27 21:56:27 +0100138 if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command"
pineafan0bc04162022-07-25 17:22:26 +0100139 return true;
140}
141
142export { command };
143export { callback };
144export { check };