blob: 3d718dc2a1db7eb54deb427e32f986ff25dc4701 [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) =>
33 builder
34 .setName("tickets")
TheCodedProf1f675042023-02-16 17:01:29 -050035 .setDescription("Shows settings for tickets")
pineafan4f164f32022-02-26 22:07:12 +000036
pineafan3a02ea32022-08-11 21:35:04 +010037const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana00db1b2023-01-02 15:32:54 +000038 if (!interaction.guild) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010039 let m = (await interaction.reply({
40 embeds: LoadingEmbed,
41 ephemeral: true,
42 fetchReply: true
43 })) as Message;
PineaFan638eb132023-01-19 10:41:22 +000044 const data = await client.database.guilds.read(interaction.guild.id);
45 data.tickets.customTypes = (data.tickets.customTypes ?? []).filter(
Skyler Grey11236ba2022-08-08 21:13:33 +010046 (value: string, index: number, array: string[]) => array.indexOf(value) === index
Skyler Grey75ea9172022-08-06 10:22:23 +010047 );
TheCodedProf1f675042023-02-16 17:01:29 -050048 let ticketData = (await client.database.guilds.read(interaction.guild.id)).tickets
49 let changesMade = false;
Skyler Greyad002172022-08-16 18:48:26 +010050 let timedOut = false;
TheCodedProf1f675042023-02-16 17:01:29 -050051 let errorMessage = "";
Skyler Greyad002172022-08-16 18:48:26 +010052 while (!timedOut) {
TheCodedProf1f675042023-02-16 17:01:29 -050053 const embed: EmojiEmbed = new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010054 .setTitle("Tickets")
55 .setDescription(
TheCodedProf1f675042023-02-16 17:01:29 -050056 `${ticketData.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${
57 ticketData.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${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")}` +
60 ((await interaction.guild.channels.fetch(ticketData.category!))!.type === ChannelType.GuildCategory ?
61 `**Category:** ` : `**Channel:** `) + // TODO: Notify if permissions are wrong
62 `${ticketData.category ? `<#${ticketData.category}>` : "*None set*"}\n` +
63 `**Max Tickets:** ${ticketData.maxTickets ? ticketData.maxTickets : "*No limit*"}\n` +
64 `**Support Ping:** ${ticketData.supportRole ? `<@&${ticketData.supportRole}>` : "*None set*"}\n\n` +
65 (ticketData.useCustom && ticketData.customTypes === null ? `${getEmojiByName("TICKETS.REPORT")} ` : "") +
66 `${ticketData.useCustom ? "Custom" : "Default"} types in use` +
Skyler Grey75ea9172022-08-06 10:22:23 +010067 "\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +010068 `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
pineafan6702cef2022-06-13 17:52:37 +010069 )
70 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +010071 .setEmoji("GUILD.TICKET.OPEN");
TheCodedProf1f675042023-02-16 17:01:29 -050072 if (errorMessage) embed.setFooter({text: errorMessage, iconURL: LinkWarningFooter.iconURL});
Skyler Grey75ea9172022-08-06 10:22:23 +010073 m = (await interaction.editReply({
74 embeds: [embed],
75 components: [
TheCodedProf1f675042023-02-16 17:01:29 -050076 new ActionRowBuilder<ButtonBuilder>().addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -040077 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050078 .setLabel("Tickets " + (ticketData.enabled ? "enabled" : "disabled"))
79 .setEmoji(getEmojiByName("CONTROL." + (ticketData.enabled ? "TICK" : "CROSS"), "id"))
80 .setStyle(ticketData.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +010081 .setCustomId("enabled"),
TheCodedProf21c08592022-09-13 14:14:43 -040082 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050083 .setLabel("Set max tickets")
84 .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
85 .setStyle(ButtonStyle.Primary)
86 .setCustomId("setMaxTickets")
87 .setDisabled(!ticketData.enabled),
TheCodedProf21c08592022-09-13 14:14:43 -040088 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010089 .setLabel("Manage types")
90 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -040091 .setStyle(ButtonStyle.Secondary)
TheCodedProf1f675042023-02-16 17:01:29 -050092 .setCustomId("manageTypes")
93 .setDisabled(!ticketData.enabled),
TheCodedProf21c08592022-09-13 14:14:43 -040094 new ButtonBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -050095 .setLabel("Save")
96 .setEmoji(getEmojiByName("ICONS.SAVE", "id"))
97 .setStyle(ButtonStyle.Success)
98 .setCustomId("save")
99 .setDisabled(!changesMade)
100 ),
101 new ActionRowBuilder<RoleSelectMenuBuilder>().addComponents(
102 new RoleSelectMenuBuilder()
103 .setCustomId("supportRole")
104 .setPlaceholder("Select a support role")
105 .setDisabled(!ticketData.enabled)
106 ),
107 new ActionRowBuilder<ChannelSelectMenuBuilder>().addComponents(
108 new ChannelSelectMenuBuilder()
109 .setCustomId("category")
110 .setPlaceholder("Select a category or channel")
111 .setDisabled(!ticketData.enabled)
112 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100113 ]
TheCodedProf1f675042023-02-16 17:01:29 -0500114 }));
115 let i: RoleSelectMenuInteraction | ButtonInteraction | ChannelSelectMenuInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100116 try {
TheCodedProf1f675042023-02-16 17:01:29 -0500117 i = await m.awaitMessageComponent<2 | 6 | 8>({
PineaFan0d06edc2023-01-17 22:10:31 +0000118 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -0500119 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 +0000120 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100121 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100122 timedOut = true;
123 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100124 }
TheCodedProf1f675042023-02-16 17:01:29 -0500125 changesMade = true;
126 if (i.isRoleSelectMenu()) {
127 await i.deferUpdate();
128 ticketData.supportRole = i.values[0] ?? null;
129 } else if (i.isChannelSelectMenu()) {
130 await i.deferUpdate();
131 ticketData.category = i.values[0] ?? null;
132 } else {
133 switch(i.customId) {
134 case "save": {
TheCodedProf267563a2023-01-21 17:00:57 -0500135 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500136 await client.database.guilds.write(interaction.guild.id, { tickets: ticketData });
137 changesMade = false;
138 break;
139 }
140 case "enabled": {
TheCodedProf267563a2023-01-21 17:00:57 -0500141 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500142 ticketData.enabled = !ticketData.enabled;
143 break;
144 }
145 case "setMaxTickets": {
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 await i.showModal(
TheCodedProf1f675042023-02-16 17:01:29 -0500147 new ModalBuilder()
148 .setCustomId("maxTickets")
149 .setTitle("Set max tickets")
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 .addComponents(
TheCodedProf1f675042023-02-16 17:01:29 -0500151 new ActionRowBuilder<TextInputBuilder>().setComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500152 new TextInputBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -0500153 .setLabel("Max tickets - Leave blank for no limit")
154 .setCustomId("maxTickets")
155 .setPlaceholder("Enter a number")
156 .setRequired(false)
157 .setValue(ticketData.maxTickets.toString() ?? "")
158 .setMinLength(1)
159 .setMaxLength(3)
160 .setStyle(TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100161 )
162 )
TheCodedProf1f675042023-02-16 17:01:29 -0500163 )
164 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100165 embeds: [
166 new EmojiEmbed()
TheCodedProf1f675042023-02-16 17:01:29 -0500167 .setTitle("Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100168 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100169 .setStatus("Success")
170 .setEmoji("GUILD.TICKET.OPEN")
171 ],
172 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500173 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400174 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100176 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400177 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100178 .setCustomId("back")
179 ])
180 ]
pineafan41d93562022-07-30 22:10:15 +0100181 });
182 let out;
183 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100184 out = await modalInteractionCollector(
185 m,
TheCodedProf1f675042023-02-16 17:01:29 -0500186 (m) => m.user.id === interaction.user.id,
187 (m) => m.customId === "back"
Skyler Grey75ea9172022-08-06 10:22:23 +0100188 );
189 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100190 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100191 }
TheCodedProf1f675042023-02-16 17:01:29 -0500192 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500193 out = out as ModalSubmitInteraction;
TheCodedProf1f675042023-02-16 17:01:29 -0500194 let toAdd = out.fields.getTextInputValue("maxTickets");
195 if(isNaN(parseInt(toAdd))) {
196 errorMessage = "You entered an invalid number - No changes were made";
197 break;
198 }
199 ticketData.maxTickets = toAdd === "" ? 0 : parseInt(toAdd);
200 break;
201 }
202 case "manageTypes": {
203 await i.deferUpdate();
204 ticketData = await manageTypes(interaction, data.tickets, m);
205 break;
pineafan41d93562022-07-30 22:10:15 +0100206 }
207 }
pineafan6702cef2022-06-13 17:52:37 +0100208 }
209 }
pineafan63fc5e22022-08-04 22:04:10 +0100210};
pineafan4f164f32022-02-26 22:07:12 +0000211
TheCodedProf1f675042023-02-16 17:01:29 -0500212
213
Skyler Grey11236ba2022-08-08 21:13:33 +0100214async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100215 let timedOut = false;
216 let backPressed = false;
217 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100218 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100219 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100220 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 embeds: [
222 new EmojiEmbed()
223 .setTitle("Tickets > Types")
224 .setDescription(
225 "**Custom types enabled**\n\n" +
226 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100227 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100228 "\n\n" +
229 (customTypes === null
230 ? `${getEmojiByName(
231 "TICKETS.REPORT"
232 )} Having no types will disable tickets. Please add at least 1 type or use default types`
233 : "")
pineafan6702cef2022-06-13 17:52:37 +0100234 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100235 .setStatus("Success")
236 .setEmoji("GUILD.TICKET.OPEN")
237 ],
TheCodedProf1f675042023-02-16 17:01:29 -0500238 components: (customTypes && customTypes.length > 0
Skyler Grey75ea9172022-08-06 10:22:23 +0100239 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500240 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500241 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100242 .setCustomId("removeTypes")
243 .setPlaceholder("Select types to remove")
244 .setMaxValues(customTypes.length)
245 .setMinValues(1)
246 .addOptions(
247 customTypes.map((t) => ({
248 label: t,
249 value: t
250 }))
251 )
252 ])
253 ]
254 : []
255 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500256 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400257 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100258 .setLabel("Back")
259 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400260 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100261 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400262 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100263 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100264 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400265 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100266 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100267 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400268 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100269 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400270 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100271 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100272 ])
273 ])
274 });
275 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100276 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500277 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 ticketTypes.forEach((type) => {
279 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500280 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 label: capitalize(type),
282 value: type,
TheCodedProf59772f82023-01-18 22:17:16 -0500283 emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100284 default: inUse.includes(type)
285 })
286 );
pineafan63fc5e22022-08-04 22:04:10 +0100287 });
TheCodedProf59772f82023-01-18 22:17:16 -0500288 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500289 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100290 .addOptions(options)
291 .setCustomId("types")
292 .setMaxValues(ticketTypes.length)
293 .setMinValues(1)
294 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100295 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100296 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100297 embeds: [
298 new EmojiEmbed()
299 .setTitle("Tickets > Types")
300 .setDescription(
301 "**Default types enabled**\n\n" +
302 "**Types in use:**\n" +
303 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100304 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100305 .join("\n")
306 )
307 .setStatus("Success")
308 .setEmoji("GUILD.TICKET.OPEN")
309 ],
310 components: [
pineafan6702cef2022-06-13 17:52:37 +0100311 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500312 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400313 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100314 .setLabel("Back")
315 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400316 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100317 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400318 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100319 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400320 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100321 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100322 ])
323 ]
324 });
325 }
326 let i;
327 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000328 i = await m.awaitMessageComponent({
329 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -0500330 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 +0000331 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100333 timedOut = true;
334 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100335 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500336 if (i.isStringSelectMenu() && i.customId === "types") {
TheCodedProf267563a2023-01-21 17:00:57 -0500337 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500338 const types = toHexInteger(i.values, ticketTypes);
pineafan6702cef2022-06-13 17:52:37 +0100339 data.types = types;
TheCodedProf4a6d5712023-01-19 15:54:40 -0500340 } else if (i.isStringSelectMenu() && i.customId === "removeTypes") {
TheCodedProf267563a2023-01-21 17:00:57 -0500341 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500342 const types = i.values;
pineafan6702cef2022-06-13 17:52:37 +0100343 let customTypes = data.customTypes;
344 if (customTypes) {
345 customTypes = customTypes.filter((t) => !types.includes(t));
346 customTypes = customTypes.length > 0 ? customTypes : null;
pineafan6702cef2022-06-13 17:52:37 +0100347 data.customTypes = customTypes;
348 }
TheCodedProf59772f82023-01-18 22:17:16 -0500349 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100350 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500351 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100352 .setCustomId("modal")
353 .setTitle("Enter a name for the new type")
354 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500355 new ActionRowBuilder<TextInputBuilder>().addComponents(
356 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100357 .setCustomId("type")
358 .setLabel("Name")
359 .setMaxLength(100)
360 .setMinLength(1)
361 .setPlaceholder('E.g. "Server Idea"')
362 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500363 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100364 )
365 )
366 );
TheCodedProf1f675042023-02-16 17:01:29 -0500367 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100368 embeds: [
369 new EmojiEmbed()
370 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100371 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100372 .setStatus("Success")
373 .setEmoji("GUILD.TICKET.OPEN")
374 ],
375 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500376 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400377 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100378 .setLabel("Back")
379 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400380 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100381 .setCustomId("back")
382 ])
383 ]
pineafan6702cef2022-06-13 17:52:37 +0100384 });
pineafan4edb7762022-06-26 19:21:04 +0100385 let out;
pineafan6702cef2022-06-13 17:52:37 +0100386 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100387 out = await modalInteractionCollector(
388 m,
TheCodedProf1f675042023-02-16 17:01:29 -0500389 (m) => m.user.id === interaction.user.id,
390 (m) => m.customId === "back"
Skyler Grey75ea9172022-08-06 10:22:23 +0100391 );
392 } catch (e) {
393 continue;
394 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500395 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500396 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000397 let toAdd = out.fields.getTextInputValue("type");
398 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100399 continue;
400 }
PineaFan638eb132023-01-19 10:41:22 +0000401 toAdd = toAdd.substring(0, 80);
402 try {
TheCodedProf1f675042023-02-16 17:01:29 -0500403 if(!data.customTypes) data.customTypes = [];
404 data.customTypes?.push(toAdd);
PineaFan638eb132023-01-19 10:41:22 +0000405 } catch {
406 continue;
407 }
408 data.customTypes = data.customTypes ?? [];
409 if (!data.customTypes.includes(toAdd)) {
410 data.customTypes.push(toAdd);
411 }
TheCodedProf59772f82023-01-18 22:17:16 -0500412 } else if ((i.component as ButtonComponent).customId === "switchToDefault") {
PineaFanb0d0c242023-02-05 10:59:45 +0000413 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500414 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": false }, []);
pineafan6702cef2022-06-13 17:52:37 +0100415 data.useCustom = false;
TheCodedProf59772f82023-01-18 22:17:16 -0500416 } else if ((i.component as ButtonComponent).customId === "switchToCustom") {
TheCodedProf267563a2023-01-21 17:00:57 -0500417 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500418 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": true }, []);
pineafan6702cef2022-06-13 17:52:37 +0100419 data.useCustom = true;
420 } else {
TheCodedProf267563a2023-01-21 17:00:57 -0500421 await i.deferUpdate();
Skyler Greyad002172022-08-16 18:48:26 +0100422 backPressed = true;
pineafan6702cef2022-06-13 17:52:37 +0100423 }
424 }
pineafan63fc5e22022-08-04 22:04:10 +0100425 return data;
pineafan6702cef2022-06-13 17:52:37 +0100426}
427
TheCodedProff86ba092023-01-27 17:10:07 -0500428const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100429 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000430 if (!member.permissions.has("ManageGuild"))
PineaFan0d06edc2023-01-17 22:10:31 +0000431 return "You must have the *Manage Server* permission to use this command";
pineafan6702cef2022-06-13 17:52:37 +0100432 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100433};
pineafan4f164f32022-02-26 22:07:12 +0000434
435export { command };
436export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100437export { check };