blob: f19998a8ba3f0495f59efa4f7ea1656a6dba4241 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
TheCodedProf21c08592022-09-13 14:14:43 -04002import Discord, { CommandInteraction, Message, ActionRowBuilder, SelectMenuBuilder } from "discord.js";
pineafan0bc04162022-07-25 17:22:26 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
4import confirmationMessage from "../../utils/confirmationMessage.js";
pineafanc1c18792022-08-03 21:41:36 +01005import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan0bc04162022-07-25 17:22:26 +01006import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +01007import convertCurlyBracketString from "../../utils/convertCurlyBracketString.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01008import { callback as statsChannelAddCallback } from "../../reflex/statsChannelUpdate.js";
pineafan63fc5e22022-08-04 22:04:10 +01009import singleNotify from "../../utils/singleNotify.js";
pineafan708692b2022-07-24 22:16:22 +010010
11const command = (builder: SlashCommandSubcommandBuilder) =>
12 builder
pineafan63fc5e22022-08-04 22:04:10 +010013 .setName("stats")
Skyler Grey11236ba2022-08-08 21:13:33 +010014 .setDescription("Controls channels which update when someone joins or leaves the server")
15 .addChannelOption((option) => option.setName("channel").setDescription("The channel to modify"))
Skyler Grey75ea9172022-08-06 10:22:23 +010016 .addStringOption((option) =>
17 option
18 .setName("name")
Skyler Grey11236ba2022-08-08 21:13:33 +010019 .setDescription("The new channel name | Enter any text or use the extra variables like {memberCount}")
Skyler Grey75ea9172022-08-06 10:22:23 +010020 .setAutocomplete(true)
21 );
pineafan708692b2022-07-24 22:16:22 +010022
pineafan3a02ea32022-08-11 21:35:04 +010023const callback = async (interaction: CommandInteraction): Promise<unknown> => {
pineafan63fc5e22022-08-04 22:04:10 +010024 singleNotify("statsChannelDeleted", interaction.guild.id, true);
Skyler Grey75ea9172022-08-06 10:22:23 +010025 const m = (await interaction.reply({
26 embeds: LoadingEmbed,
27 ephemeral: true,
28 fetchReply: true
29 })) as Message;
pineafane23c4ec2022-07-27 21:56:27 +010030 let config = await client.database.guilds.read(interaction.guild.id);
pineafan0bc04162022-07-25 17:22:26 +010031 if (interaction.options.getString("name")) {
pineafane23c4ec2022-07-27 21:56:27 +010032 let channel;
33 if (Object.keys(config.getKey("stats")).length >= 25) {
Skyler Grey75ea9172022-08-06 10:22:23 +010034 return await interaction.editReply({
35 embeds: [
36 new EmojiEmbed()
37 .setEmoji("CHANNEL.TEXT.DELETE")
38 .setTitle("Stats Channel")
Skyler Grey11236ba2022-08-08 21:13:33 +010039 .setDescription("You can only have 25 stats channels in a server")
Skyler Grey75ea9172022-08-06 10:22:23 +010040 .setStatus("Danger")
41 ]
42 });
pineafane23c4ec2022-07-27 21:56:27 +010043 }
pineafan708692b2022-07-24 22:16:22 +010044 try {
pineafan63fc5e22022-08-04 22:04:10 +010045 channel = interaction.options.getChannel("channel");
pineafan708692b2022-07-24 22:16:22 +010046 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010047 return await interaction.editReply({
48 embeds: [
49 new EmojiEmbed()
50 .setEmoji("CHANNEL.TEXT.DELETE")
51 .setTitle("Stats Channel")
Skyler Grey11236ba2022-08-08 21:13:33 +010052 .setDescription("The channel you provided is not a valid channel")
Skyler Grey75ea9172022-08-06 10:22:23 +010053 .setStatus("Danger")
54 ]
55 });
pineafan708692b2022-07-24 22:16:22 +010056 }
pineafan63fc5e22022-08-04 22:04:10 +010057 channel = channel as Discord.TextChannel;
pineafane23c4ec2022-07-27 21:56:27 +010058 if (channel.guild.id !== interaction.guild.id) {
Skyler Grey75ea9172022-08-06 10:22:23 +010059 return interaction.editReply({
60 embeds: [
61 new EmojiEmbed()
62 .setTitle("Stats Channel")
Skyler Grey11236ba2022-08-08 21:13:33 +010063 .setDescription("You must choose a channel in this server")
Skyler Grey75ea9172022-08-06 10:22:23 +010064 .setStatus("Danger")
65 .setEmoji("CHANNEL.TEXT.DELETE")
66 ]
67 });
pineafan708692b2022-07-24 22:16:22 +010068 }
Skyler Grey75ea9172022-08-06 10:22:23 +010069 let newName = await convertCurlyBracketString(
70 interaction.options.getString("name"),
71 null,
72 null,
73 interaction.guild.name,
74 interaction.guild.members
75 );
pineafan708692b2022-07-24 22:16:22 +010076 if (interaction.options.getChannel("channel").type === "GUILD_TEXT") {
pineafan63fc5e22022-08-04 22:04:10 +010077 newName = newName.toLowerCase().replace(/[\s]/g, "-");
pineafan708692b2022-07-24 22:16:22 +010078 }
pineafan63fc5e22022-08-04 22:04:10 +010079 const confirmation = await new confirmationMessage(interaction)
pineafan62ce1922022-08-25 20:34:45 +010080 .setEmoji("CHANNEL.TEXT.EDIT", "CHANNEL.TEXT.DELETE")
pineafan708692b2022-07-24 22:16:22 +010081 .setTitle("Stats Channel")
Skyler Grey75ea9172022-08-06 10:22:23 +010082 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +010083 `Are you sure you want to set <#${channel.id}> to a stats channel?\n\n*Preview: ${newName.replace(
Skyler Grey75ea9172022-08-06 10:22:23 +010084 /^ +| $/g,
85 ""
86 )}*`
87 )
pineafan708692b2022-07-24 22:16:22 +010088 .setColor("Warning")
89 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010090 .send(true);
91 if (confirmation.cancelled) return;
pineafan708692b2022-07-24 22:16:22 +010092 if (confirmation.success) {
93 try {
pineafan63fc5e22022-08-04 22:04:10 +010094 const name = interaction.options.getString("name");
95 const channel = interaction.options.getChannel("channel");
Skyler Grey75ea9172022-08-06 10:22:23 +010096 await client.database.guilds.write(interaction.guild.id, {
97 [`stats.${channel.id}`]: { name: name, enabled: true }
98 });
Skyler Grey11236ba2022-08-08 21:13:33 +010099 const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +0100100 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100102 type: "statsChannelUpdate",
103 displayName: "Stats Channel Updated",
104 calculateType: "nucleusSettingsUpdated",
105 color: NucleusColors.yellow,
106 emoji: "CHANNEL.TEXT.EDIT",
107 timestamp: new Date().getTime()
108 },
109 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100110 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
111 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
pineafan63fc5e22022-08-04 22:04:10 +0100112 channel: entry(channel.id, renderChannel(channel)),
Skyler Grey75ea9172022-08-06 10:22:23 +0100113 name: entry(
114 interaction.options.getString("name"),
115 `\`${interaction.options.getString("name")}\``
116 )
pineafan63fc5e22022-08-04 22:04:10 +0100117 },
118 hidden: {
119 guild: interaction.guild.id
pineafan708692b2022-07-24 22:16:22 +0100120 }
pineafan63fc5e22022-08-04 22:04:10 +0100121 };
122 log(data);
pineafan708692b2022-07-24 22:16:22 +0100123 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100124 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 return interaction.editReply({
126 embeds: [
127 new EmojiEmbed()
128 .setTitle("Stats Channel")
Skyler Grey11236ba2022-08-08 21:13:33 +0100129 .setDescription("Something went wrong and the stats channel could not be set")
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 .setStatus("Danger")
131 .setEmoji("CHANNEL.TEXT.DELETE")
132 ],
133 components: []
134 });
pineafan708692b2022-07-24 22:16:22 +0100135 }
136 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 return interaction.editReply({
138 embeds: [
139 new EmojiEmbed()
140 .setTitle("Stats Channel")
141 .setDescription("No changes were made")
142 .setStatus("Success")
143 .setEmoji("CHANNEL.TEXT.CREATE")
144 ],
145 components: []
146 });
pineafan708692b2022-07-24 22:16:22 +0100147 }
148 await statsChannelAddCallback(client, interaction.member);
pineafan0bc04162022-07-25 17:22:26 +0100149 }
Skyler Greyad002172022-08-16 18:48:26 +0100150 let timedOut = false;
151 while (!timedOut) {
pineafane23c4ec2022-07-27 21:56:27 +0100152 config = await client.database.guilds.read(interaction.guild.id);
pineafan63fc5e22022-08-04 22:04:10 +0100153 const stats = config.getKey("stats");
TheCodedProf21c08592022-09-13 14:14:43 -0400154 const selectMenu = new SelectMenuBuilder()
pineafan0bc04162022-07-25 17:22:26 +0100155 .setCustomId("remove")
156 .setMinValues(1)
pineafan63fc5e22022-08-04 22:04:10 +0100157 .setMaxValues(Math.max(1, Object.keys(stats).length));
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 await interaction.editReply({
159 embeds: [
160 new EmojiEmbed()
161 .setTitle("Stats Channel")
162 .setDescription(
163 "The following channels update when someone joins or leaves the server. You can select a channel to remove it from the list."
164 )
165 .setStatus("Success")
166 .setEmoji("CHANNEL.TEXT.CREATE")
167 ],
168 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400169 new ActionRowBuilder().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 Object.keys(stats).length
171 ? [
172 selectMenu
Skyler Grey11236ba2022-08-08 21:13:33 +0100173 .setPlaceholder("Select a stats channel to remove, stopping it updating")
Skyler Grey75ea9172022-08-06 10:22:23 +0100174 .addOptions(
175 Object.keys(stats).map((key) => ({
Skyler Grey11236ba2022-08-08 21:13:33 +0100176 label: interaction.guild.channels.cache.get(key).name,
Skyler Grey75ea9172022-08-06 10:22:23 +0100177 value: key,
178 description: `${stats[key].name}`
179 }))
180 )
181 ]
182 : [
183 selectMenu
Skyler Grey11236ba2022-08-08 21:13:33 +0100184 .setPlaceholder("The server has no stats channels")
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 .setDisabled(true)
186 .setOptions([
187 {
188 label: "*Placeholder*",
189 value: "placeholder",
190 description: "No stats channels"
191 }
192 ])
193 ]
194 )
195 ]
196 });
pineafan0bc04162022-07-25 17:22:26 +0100197 let i;
198 try {
199 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100200 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100201 timedOut = true;
202 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100203 }
pineafan63fc5e22022-08-04 22:04:10 +0100204 i.deferUpdate();
pineafan0bc04162022-07-25 17:22:26 +0100205 if (i.customId === "remove") {
pineafan63fc5e22022-08-04 22:04:10 +0100206 const toRemove = i.values;
Skyler Grey75ea9172022-08-06 10:22:23 +0100207 await client.database.guilds.write(
208 interaction.guild.id,
209 null,
210 toRemove.map((k) => `stats.${k}`)
211 );
pineafan0bc04162022-07-25 17:22:26 +0100212 }
pineafan708692b2022-07-24 22:16:22 +0100213 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100214 await interaction.editReply({
Skyler Greyad002172022-08-16 18:48:26 +0100215 embeds: [m.embeds[0]!.setFooter({ text: "Message timed out" })],
Skyler Grey75ea9172022-08-06 10:22:23 +0100216 components: []
217 });
pineafan63fc5e22022-08-04 22:04:10 +0100218};
pineafan708692b2022-07-24 22:16:22 +0100219
PineaFan64486c42022-12-28 09:21:04 +0000220const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 const member = interaction.member as Discord.GuildMember;
222 if (!member.permissions.has("MANAGE_CHANNELS"))
pineafan3a02ea32022-08-11 21:35:04 +0100223 throw new Error("You must have the *Manage Channels* permission to use this command");
pineafan708692b2022-07-24 22:16:22 +0100224 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100225};
pineafan708692b2022-07-24 22:16:22 +0100226
227export { command };
228export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100229export { check };