blob: c0025d80611571661b09b8813b2e6f884757e2b9 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../utils/defaults.js";
pineafan6702cef2022-06-13 17:52:37 +01002import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan4edb7762022-06-26 19:21:04 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01004import Discord, {
5 CommandInteraction,
Skyler Grey75ea9172022-08-06 10:22:23 +01006 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04007 ActionRowBuilder,
TheCodedProf21c08592022-09-13 14:14:43 -04008 ButtonBuilder,
TheCodedProfa16d1672023-01-18 18:58:34 -05009 StringSelectMenuBuilder,
TheCodedProf59772f82023-01-18 22:17:16 -050010 ButtonStyle,
11 TextInputBuilder,
12 ButtonComponent,
TheCodedProf59772f82023-01-18 22:17:16 -050013 ModalSubmitInteraction,
TheCodedProf1f675042023-02-16 17:01:29 -050014 APIMessageComponentEmoji,
15 RoleSelectMenuBuilder,
16 ChannelSelectMenuBuilder,
17 RoleSelectMenuInteraction,
18 ButtonInteraction,
19 ChannelSelectMenuInteraction,
20 TextInputStyle,
21 ModalBuilder,
22 ChannelType
Skyler Grey75ea9172022-08-06 10:22:23 +010023} from "discord.js";
TheCodedProff86ba092023-01-27 17:10:07 -050024import { SlashCommandSubcommandBuilder, StringSelectMenuOptionBuilder } from "discord.js";
pineafan6702cef2022-06-13 17:52:37 +010025import client from "../../utils/client.js";
Skyler Grey11236ba2022-08-08 21:13:33 +010026import { toHexInteger, toHexArray, tickets as ticketTypes } from "../../utils/calculate.js";
pineafan63fc5e22022-08-04 22:04:10 +010027import { capitalize } from "../../utils/generateKeyValueList.js";
pineafan6702cef2022-06-13 17:52:37 +010028import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan3a02ea32022-08-11 21:35:04 +010029import type { GuildConfig } from "../../utils/database.js";
TheCodedProf1f675042023-02-16 17:01:29 -050030import { LinkWarningFooter } from "../../utils/defaults.js";
pineafan4f164f32022-02-26 22:07:12 +000031
Skyler Grey75ea9172022-08-06 10:22:23 +010032const command = (builder: SlashCommandSubcommandBuilder) =>
Skyler Greyda16adf2023-03-05 10:22:12 +000033 builder.setName("tickets").setDescription("Shows settings for tickets");
pineafan4f164f32022-02-26 22:07:12 +000034
pineafan3a02ea32022-08-11 21:35:04 +010035const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana00db1b2023-01-02 15:32:54 +000036 if (!interaction.guild) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010037 let m = (await interaction.reply({
38 embeds: LoadingEmbed,
39 ephemeral: true,
40 fetchReply: true
41 })) as Message;
PineaFan638eb132023-01-19 10:41:22 +000042 const data = await client.database.guilds.read(interaction.guild.id);
43 data.tickets.customTypes = (data.tickets.customTypes ?? []).filter(
Skyler Grey11236ba2022-08-08 21:13:33 +010044 (value: string, index: number, array: string[]) => array.indexOf(value) === index
Skyler Grey75ea9172022-08-06 10:22:23 +010045 );
Skyler Greyda16adf2023-03-05 10:22:12 +000046 let ticketData = (await client.database.guilds.read(interaction.guild.id)).tickets;
TheCodedProf1f675042023-02-16 17:01:29 -050047 let changesMade = false;
Skyler Greyad002172022-08-16 18:48:26 +010048 let timedOut = false;
TheCodedProf1f675042023-02-16 17:01:29 -050049 let errorMessage = "";
Skyler Greyad002172022-08-16 18:48:26 +010050 while (!timedOut) {
TheCodedProf1f675042023-02-16 17:01:29 -050051 const embed: EmojiEmbed = new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010052 .setTitle("Tickets")
53 .setDescription(
TheCodedProf1f675042023-02-16 17:01:29 -050054 `${ticketData.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${
Skyler Greyda16adf2023-03-05 10:22:12 +000055 ticketData.enabled
56 ? `${getEmojiByName("CONTROL.TICK")} Yes`
57 : `${getEmojiByName("CONTROL.CROSS")} No`
Skyler Grey75ea9172022-08-06 10:22:23 +010058 }\n` +
TheCodedProf1f675042023-02-16 17:01:29 -050059 `${ticketData.category ? "" : getEmojiByName("TICKETS.REPORT")}` +
Skyler Greyda16adf2023-03-05 10:22:12 +000060 ((await interaction.guild.channels.fetch(ticketData.category!))!.type === ChannelType.GuildCategory
61 ? `**Category:** `
62 : `**Channel:** `) + // TODO: Notify if permissions are wrong
TheCodedProf1f675042023-02-16 17:01:29 -050063 `${ticketData.category ? `<#${ticketData.category}>` : "*None set*"}\n` +
64 `**Max Tickets:** ${ticketData.maxTickets ? ticketData.maxTickets : "*No limit*"}\n` +
65 `**Support Ping:** ${ticketData.supportRole ? `<@&${ticketData.supportRole}>` : "*None set*"}\n\n` +
Skyler Greyda16adf2023-03-05 10:22:12 +000066 (ticketData.useCustom && ticketData.customTypes === null
67 ? `${getEmojiByName("TICKETS.REPORT")} `
68 : "") +
TheCodedProf1f675042023-02-16 17:01:29 -050069 `${ticketData.useCustom ? "Custom" : "Default"} types in use` +
Skyler Grey75ea9172022-08-06 10:22:23 +010070 "\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010071 `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
pineafan6702cef2022-06-13 17:52:37 +010072 )
73 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +010074 .setEmoji("GUILD.TICKET.OPEN");
Skyler Greyda16adf2023-03-05 10:22:12 +000075 if (errorMessage) embed.setFooter({ text: errorMessage, iconURL: LinkWarningFooter.iconURL });
76 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010077 embeds: [embed],
78 components: [
TheCodedProf1f675042023-02-16 17:01:29 -050079 new ActionRowBuilder<ButtonBuilder>().addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -040080 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050081 .setLabel("Tickets " + (ticketData.enabled ? "enabled" : "disabled"))
82 .setEmoji(getEmojiByName("CONTROL." + (ticketData.enabled ? "TICK" : "CROSS"), "id"))
83 .setStyle(ticketData.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +010084 .setCustomId("enabled"),
TheCodedProf21c08592022-09-13 14:14:43 -040085 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050086 .setLabel("Set max tickets")
87 .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
88 .setStyle(ButtonStyle.Primary)
89 .setCustomId("setMaxTickets")
90 .setDisabled(!ticketData.enabled),
TheCodedProf21c08592022-09-13 14:14:43 -040091 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010092 .setLabel("Manage types")
93 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -040094 .setStyle(ButtonStyle.Secondary)
TheCodedProf1f675042023-02-16 17:01:29 -050095 .setCustomId("manageTypes")
96 .setDisabled(!ticketData.enabled),
TheCodedProf21c08592022-09-13 14:14:43 -040097 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050098 .setLabel("Save")
99 .setEmoji(getEmojiByName("ICONS.SAVE", "id"))
100 .setStyle(ButtonStyle.Success)
101 .setCustomId("save")
102 .setDisabled(!changesMade)
103 ),
104 new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
105 new RoleSelectMenuBuilder()
106 .setCustomId("supportRole")
107 .setPlaceholder("Select a support role")
108 .setDisabled(!ticketData.enabled)
109 ),
110 new ActionRowBuilder<ChannelSelectMenuBuilder>().addComponents(
111 new ChannelSelectMenuBuilder()
112 .setCustomId("category")
113 .setPlaceholder("Select a category or channel")
114 .setDisabled(!ticketData.enabled)
115 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100116 ]
Skyler Greyda16adf2023-03-05 10:22:12 +0000117 });
TheCodedProf1f675042023-02-16 17:01:29 -0500118 let i: RoleSelectMenuInteraction | ButtonInteraction | ChannelSelectMenuInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100119 try {
TheCodedProf1f675042023-02-16 17:01:29 -0500120 i = await m.awaitMessageComponent<2 | 6 | 8>({
PineaFan0d06edc2023-01-17 22:10:31 +0000121 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000122 filter: (i) => {
123 return (
124 i.user.id === interaction.user.id &&
125 i.channel!.id === interaction.channel!.id &&
126 i.message.id === m.id
127 );
128 }
PineaFan0d06edc2023-01-17 22:10:31 +0000129 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100131 timedOut = true;
132 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100133 }
TheCodedProf1f675042023-02-16 17:01:29 -0500134 changesMade = true;
135 if (i.isRoleSelectMenu()) {
136 await i.deferUpdate();
137 ticketData.supportRole = i.values[0] ?? null;
138 } else if (i.isChannelSelectMenu()) {
139 await i.deferUpdate();
140 ticketData.category = i.values[0] ?? null;
141 } else {
Skyler Greyda16adf2023-03-05 10:22:12 +0000142 switch (i.customId) {
TheCodedProf1f675042023-02-16 17:01:29 -0500143 case "save": {
TheCodedProf267563a2023-01-21 17:00:57 -0500144 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500145 await client.database.guilds.write(interaction.guild.id, { tickets: ticketData });
146 changesMade = false;
Skyler Grey16ecb172023-03-05 07:30:32 +0000147 await client.memory.forceUpdate(interaction.guild.id);
TheCodedProf1f675042023-02-16 17:01:29 -0500148 break;
149 }
150 case "enabled": {
TheCodedProf267563a2023-01-21 17:00:57 -0500151 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500152 ticketData.enabled = !ticketData.enabled;
153 break;
154 }
155 case "setMaxTickets": {
Skyler Grey75ea9172022-08-06 10:22:23 +0100156 await i.showModal(
TheCodedProf1f675042023-02-16 17:01:29 -0500157 new ModalBuilder()
158 .setCustomId("maxTickets")
159 .setTitle("Set max tickets")
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 .addComponents(
TheCodedProf1f675042023-02-16 17:01:29 -0500161 new ActionRowBuilder<TextInputBuilder>().setComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500162 new TextInputBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -0500163 .setLabel("Max tickets - Leave blank for no limit")
164 .setCustomId("maxTickets")
165 .setPlaceholder("Enter a number")
166 .setRequired(false)
TheCodedProf1807fb32023-02-20 14:33:48 -0500167 .setValue(ticketData.maxTickets.toString())
TheCodedProf1f675042023-02-16 17:01:29 -0500168 .setMinLength(1)
169 .setMaxLength(3)
170 .setStyle(TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100171 )
172 )
Skyler Greyda16adf2023-03-05 10:22:12 +0000173 );
TheCodedProf1f675042023-02-16 17:01:29 -0500174 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 embeds: [
176 new EmojiEmbed()
TheCodedProf1f675042023-02-16 17:01:29 -0500177 .setTitle("Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100178 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100179 .setStatus("Success")
180 .setEmoji("GUILD.TICKET.OPEN")
181 ],
182 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500183 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400184 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100186 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400187 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100188 .setCustomId("back")
189 ])
190 ]
pineafan41d93562022-07-30 22:10:15 +0100191 });
192 let out;
193 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500194 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100195 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100196 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100197 }
TheCodedProf1f675042023-02-16 17:01:29 -0500198 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500199 out = out as ModalSubmitInteraction;
TheCodedProf1807fb32023-02-20 14:33:48 -0500200 const toAdd = out.fields.getTextInputValue("maxTickets");
Skyler Greyda16adf2023-03-05 10:22:12 +0000201 if (isNaN(parseInt(toAdd))) {
TheCodedProf1f675042023-02-16 17:01:29 -0500202 errorMessage = "You entered an invalid number - No changes were made";
203 break;
204 }
205 ticketData.maxTickets = toAdd === "" ? 0 : parseInt(toAdd);
206 break;
207 }
208 case "manageTypes": {
209 await i.deferUpdate();
210 ticketData = await manageTypes(interaction, data.tickets, m);
211 break;
pineafan41d93562022-07-30 22:10:15 +0100212 }
213 }
pineafan6702cef2022-06-13 17:52:37 +0100214 }
215 }
Skyler Greyda16adf2023-03-05 10:22:12 +0000216 await interaction.deleteReply();
pineafan63fc5e22022-08-04 22:04:10 +0100217};
pineafan4f164f32022-02-26 22:07:12 +0000218
Skyler Grey11236ba2022-08-08 21:13:33 +0100219async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100220 let timedOut = false;
221 let backPressed = false;
222 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100223 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100224 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100225 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100226 embeds: [
227 new EmojiEmbed()
228 .setTitle("Tickets > Types")
229 .setDescription(
230 "**Custom types enabled**\n\n" +
231 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100232 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 "\n\n" +
234 (customTypes === null
235 ? `${getEmojiByName(
236 "TICKETS.REPORT"
237 )} Having no types will disable tickets. Please add at least 1 type or use default types`
238 : "")
pineafan6702cef2022-06-13 17:52:37 +0100239 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100240 .setStatus("Success")
241 .setEmoji("GUILD.TICKET.OPEN")
242 ],
TheCodedProf1f675042023-02-16 17:01:29 -0500243 components: (customTypes && customTypes.length > 0
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500245 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500246 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 .setCustomId("removeTypes")
248 .setPlaceholder("Select types to remove")
249 .setMaxValues(customTypes.length)
250 .setMinValues(1)
251 .addOptions(
252 customTypes.map((t) => ({
253 label: t,
254 value: t
255 }))
256 )
257 ])
258 ]
259 : []
260 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500261 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400262 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100263 .setLabel("Back")
264 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400265 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100266 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400267 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100268 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100269 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400270 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100271 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100272 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400273 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100274 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400275 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100276 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100277 ])
278 ])
279 });
280 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100281 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500282 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100283 ticketTypes.forEach((type) => {
284 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500285 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100286 label: capitalize(type),
287 value: type,
Skyler Greyda16adf2023-03-05 10:22:12 +0000288 emoji: client.emojis.cache.get(
289 getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")
290 ) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100291 default: inUse.includes(type)
292 })
293 );
pineafan63fc5e22022-08-04 22:04:10 +0100294 });
TheCodedProf59772f82023-01-18 22:17:16 -0500295 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500296 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100297 .addOptions(options)
298 .setCustomId("types")
299 .setMaxValues(ticketTypes.length)
300 .setMinValues(1)
301 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100302 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100303 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100304 embeds: [
305 new EmojiEmbed()
306 .setTitle("Tickets > Types")
307 .setDescription(
308 "**Default types enabled**\n\n" +
309 "**Types in use:**\n" +
310 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100311 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100312 .join("\n")
313 )
314 .setStatus("Success")
315 .setEmoji("GUILD.TICKET.OPEN")
316 ],
317 components: [
pineafan6702cef2022-06-13 17:52:37 +0100318 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500319 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400320 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100321 .setLabel("Back")
322 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400323 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100324 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400325 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100326 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400327 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100328 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100329 ])
330 ]
331 });
332 }
333 let i;
334 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000335 i = await m.awaitMessageComponent({
336 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000337 filter: (i) => {
338 return (
339 i.user.id === interaction.user.id &&
340 i.channel!.id === interaction.channel!.id &&
341 i.message.id === m.id
342 );
343 }
PineaFan0d06edc2023-01-17 22:10:31 +0000344 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100345 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100346 timedOut = true;
347 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100348 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500349 if (i.isStringSelectMenu() && i.customId === "types") {
TheCodedProf267563a2023-01-21 17:00:57 -0500350 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500351 const types = toHexInteger(i.values, ticketTypes);
pineafan6702cef2022-06-13 17:52:37 +0100352 data.types = types;
TheCodedProf4a6d5712023-01-19 15:54:40 -0500353 } else if (i.isStringSelectMenu() && i.customId === "removeTypes") {
TheCodedProf267563a2023-01-21 17:00:57 -0500354 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500355 const types = i.values;
pineafan6702cef2022-06-13 17:52:37 +0100356 let customTypes = data.customTypes;
357 if (customTypes) {
358 customTypes = customTypes.filter((t) => !types.includes(t));
359 customTypes = customTypes.length > 0 ? customTypes : null;
pineafan6702cef2022-06-13 17:52:37 +0100360 data.customTypes = customTypes;
361 }
TheCodedProf59772f82023-01-18 22:17:16 -0500362 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100363 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500364 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 .setCustomId("modal")
366 .setTitle("Enter a name for the new type")
367 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500368 new ActionRowBuilder<TextInputBuilder>().addComponents(
369 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100370 .setCustomId("type")
371 .setLabel("Name")
372 .setMaxLength(100)
373 .setMinLength(1)
374 .setPlaceholder('E.g. "Server Idea"')
375 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500376 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100377 )
378 )
379 );
TheCodedProf1f675042023-02-16 17:01:29 -0500380 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100381 embeds: [
382 new EmojiEmbed()
383 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100384 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100385 .setStatus("Success")
386 .setEmoji("GUILD.TICKET.OPEN")
387 ],
388 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500389 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400390 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100391 .setLabel("Back")
392 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400393 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100394 .setCustomId("back")
395 ])
396 ]
pineafan6702cef2022-06-13 17:52:37 +0100397 });
pineafan4edb7762022-06-26 19:21:04 +0100398 let out;
pineafan6702cef2022-06-13 17:52:37 +0100399 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500400 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100401 } catch (e) {
402 continue;
403 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500404 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500405 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000406 let toAdd = out.fields.getTextInputValue("type");
407 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100408 continue;
409 }
PineaFan638eb132023-01-19 10:41:22 +0000410 toAdd = toAdd.substring(0, 80);
411 try {
Skyler Greyda16adf2023-03-05 10:22:12 +0000412 if (!data.customTypes) data.customTypes = [];
TheCodedProf1807fb32023-02-20 14:33:48 -0500413 data.customTypes.push(toAdd);
PineaFan638eb132023-01-19 10:41:22 +0000414 } catch {
415 continue;
416 }
PineaFan638eb132023-01-19 10:41:22 +0000417 if (!data.customTypes.includes(toAdd)) {
418 data.customTypes.push(toAdd);
419 }
TheCodedProf59772f82023-01-18 22:17:16 -0500420 } else if ((i.component as ButtonComponent).customId === "switchToDefault") {
PineaFanb0d0c242023-02-05 10:59:45 +0000421 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500422 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": false }, []);
pineafan6702cef2022-06-13 17:52:37 +0100423 data.useCustom = false;
TheCodedProf59772f82023-01-18 22:17:16 -0500424 } else if ((i.component as ButtonComponent).customId === "switchToCustom") {
TheCodedProf267563a2023-01-21 17:00:57 -0500425 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500426 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": true }, []);
pineafan6702cef2022-06-13 17:52:37 +0100427 data.useCustom = true;
428 } else {
TheCodedProf267563a2023-01-21 17:00:57 -0500429 await i.deferUpdate();
Skyler Greyad002172022-08-16 18:48:26 +0100430 backPressed = true;
pineafan6702cef2022-06-13 17:52:37 +0100431 }
432 }
pineafan63fc5e22022-08-04 22:04:10 +0100433 return data;
pineafan6702cef2022-06-13 17:52:37 +0100434}
435
TheCodedProff86ba092023-01-27 17:10:07 -0500436const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100437 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000438 if (!member.permissions.has("ManageGuild"))
PineaFan0d06edc2023-01-17 22:10:31 +0000439 return "You must have the *Manage Server* permission to use this command";
pineafan6702cef2022-06-13 17:52:37 +0100440 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100441};
pineafan4f164f32022-02-26 22:07:12 +0000442
443export { command };
444export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100445export { check };