blob: af74475434350d2992ea19b70942d557f7c498f0 [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 {
TheCodedProf01cba762023-02-18 15:55:05 -0500184 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100186 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100187 }
TheCodedProf1f675042023-02-16 17:01:29 -0500188 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500189 out = out as ModalSubmitInteraction;
TheCodedProf1f675042023-02-16 17:01:29 -0500190 let toAdd = out.fields.getTextInputValue("maxTickets");
191 if(isNaN(parseInt(toAdd))) {
192 errorMessage = "You entered an invalid number - No changes were made";
193 break;
194 }
195 ticketData.maxTickets = toAdd === "" ? 0 : parseInt(toAdd);
196 break;
197 }
198 case "manageTypes": {
199 await i.deferUpdate();
200 ticketData = await manageTypes(interaction, data.tickets, m);
201 break;
pineafan41d93562022-07-30 22:10:15 +0100202 }
203 }
pineafan6702cef2022-06-13 17:52:37 +0100204 }
205 }
TheCodedProf01cba762023-02-18 15:55:05 -0500206 await interaction.deleteReply()
pineafan63fc5e22022-08-04 22:04:10 +0100207};
pineafan4f164f32022-02-26 22:07:12 +0000208
TheCodedProf1f675042023-02-16 17:01:29 -0500209
210
Skyler Grey11236ba2022-08-08 21:13:33 +0100211async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100212 let timedOut = false;
213 let backPressed = false;
214 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100215 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100216 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100217 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100218 embeds: [
219 new EmojiEmbed()
220 .setTitle("Tickets > Types")
221 .setDescription(
222 "**Custom types enabled**\n\n" +
223 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100224 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100225 "\n\n" +
226 (customTypes === null
227 ? `${getEmojiByName(
228 "TICKETS.REPORT"
229 )} Having no types will disable tickets. Please add at least 1 type or use default types`
230 : "")
pineafan6702cef2022-06-13 17:52:37 +0100231 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100232 .setStatus("Success")
233 .setEmoji("GUILD.TICKET.OPEN")
234 ],
TheCodedProf1f675042023-02-16 17:01:29 -0500235 components: (customTypes && customTypes.length > 0
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500237 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500238 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100239 .setCustomId("removeTypes")
240 .setPlaceholder("Select types to remove")
241 .setMaxValues(customTypes.length)
242 .setMinValues(1)
243 .addOptions(
244 customTypes.map((t) => ({
245 label: t,
246 value: t
247 }))
248 )
249 ])
250 ]
251 : []
252 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500253 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400254 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100255 .setLabel("Back")
256 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400257 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100258 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400259 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100260 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100261 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400262 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100263 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100264 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400265 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100266 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400267 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100268 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100269 ])
270 ])
271 });
272 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100273 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500274 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100275 ticketTypes.forEach((type) => {
276 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500277 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 label: capitalize(type),
279 value: type,
TheCodedProf59772f82023-01-18 22:17:16 -0500280 emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 default: inUse.includes(type)
282 })
283 );
pineafan63fc5e22022-08-04 22:04:10 +0100284 });
TheCodedProf59772f82023-01-18 22:17:16 -0500285 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500286 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100287 .addOptions(options)
288 .setCustomId("types")
289 .setMaxValues(ticketTypes.length)
290 .setMinValues(1)
291 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100292 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100293 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100294 embeds: [
295 new EmojiEmbed()
296 .setTitle("Tickets > Types")
297 .setDescription(
298 "**Default types enabled**\n\n" +
299 "**Types in use:**\n" +
300 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100301 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100302 .join("\n")
303 )
304 .setStatus("Success")
305 .setEmoji("GUILD.TICKET.OPEN")
306 ],
307 components: [
pineafan6702cef2022-06-13 17:52:37 +0100308 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500309 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400310 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100311 .setLabel("Back")
312 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400313 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100314 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400315 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100316 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400317 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100318 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100319 ])
320 ]
321 });
322 }
323 let i;
324 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000325 i = await m.awaitMessageComponent({
326 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -0500327 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 +0000328 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100329 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100330 timedOut = true;
331 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500333 if (i.isStringSelectMenu() && i.customId === "types") {
TheCodedProf267563a2023-01-21 17:00:57 -0500334 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500335 const types = toHexInteger(i.values, ticketTypes);
pineafan6702cef2022-06-13 17:52:37 +0100336 data.types = types;
TheCodedProf4a6d5712023-01-19 15:54:40 -0500337 } else if (i.isStringSelectMenu() && i.customId === "removeTypes") {
TheCodedProf267563a2023-01-21 17:00:57 -0500338 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500339 const types = i.values;
pineafan6702cef2022-06-13 17:52:37 +0100340 let customTypes = data.customTypes;
341 if (customTypes) {
342 customTypes = customTypes.filter((t) => !types.includes(t));
343 customTypes = customTypes.length > 0 ? customTypes : null;
pineafan6702cef2022-06-13 17:52:37 +0100344 data.customTypes = customTypes;
345 }
TheCodedProf59772f82023-01-18 22:17:16 -0500346 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100347 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500348 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100349 .setCustomId("modal")
350 .setTitle("Enter a name for the new type")
351 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500352 new ActionRowBuilder<TextInputBuilder>().addComponents(
353 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100354 .setCustomId("type")
355 .setLabel("Name")
356 .setMaxLength(100)
357 .setMinLength(1)
358 .setPlaceholder('E.g. "Server Idea"')
359 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500360 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100361 )
362 )
363 );
TheCodedProf1f675042023-02-16 17:01:29 -0500364 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 embeds: [
366 new EmojiEmbed()
367 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100368 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100369 .setStatus("Success")
370 .setEmoji("GUILD.TICKET.OPEN")
371 ],
372 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500373 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400374 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100375 .setLabel("Back")
376 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400377 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100378 .setCustomId("back")
379 ])
380 ]
pineafan6702cef2022-06-13 17:52:37 +0100381 });
pineafan4edb7762022-06-26 19:21:04 +0100382 let out;
pineafan6702cef2022-06-13 17:52:37 +0100383 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500384 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100385 } catch (e) {
386 continue;
387 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500388 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500389 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000390 let toAdd = out.fields.getTextInputValue("type");
391 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100392 continue;
393 }
PineaFan638eb132023-01-19 10:41:22 +0000394 toAdd = toAdd.substring(0, 80);
395 try {
TheCodedProf1f675042023-02-16 17:01:29 -0500396 if(!data.customTypes) data.customTypes = [];
397 data.customTypes?.push(toAdd);
PineaFan638eb132023-01-19 10:41:22 +0000398 } catch {
399 continue;
400 }
401 data.customTypes = data.customTypes ?? [];
402 if (!data.customTypes.includes(toAdd)) {
403 data.customTypes.push(toAdd);
404 }
TheCodedProf59772f82023-01-18 22:17:16 -0500405 } else if ((i.component as ButtonComponent).customId === "switchToDefault") {
PineaFanb0d0c242023-02-05 10:59:45 +0000406 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500407 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": false }, []);
pineafan6702cef2022-06-13 17:52:37 +0100408 data.useCustom = false;
TheCodedProf59772f82023-01-18 22:17:16 -0500409 } else if ((i.component as ButtonComponent).customId === "switchToCustom") {
TheCodedProf267563a2023-01-21 17:00:57 -0500410 await i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500411 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": true }, []);
pineafan6702cef2022-06-13 17:52:37 +0100412 data.useCustom = true;
413 } else {
TheCodedProf267563a2023-01-21 17:00:57 -0500414 await i.deferUpdate();
Skyler Greyad002172022-08-16 18:48:26 +0100415 backPressed = true;
pineafan6702cef2022-06-13 17:52:37 +0100416 }
417 }
pineafan63fc5e22022-08-04 22:04:10 +0100418 return data;
pineafan6702cef2022-06-13 17:52:37 +0100419}
420
TheCodedProff86ba092023-01-27 17:10:07 -0500421const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100422 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000423 if (!member.permissions.has("ManageGuild"))
PineaFan0d06edc2023-01-17 22:10:31 +0000424 return "You must have the *Manage Server* permission to use this command";
pineafan6702cef2022-06-13 17:52:37 +0100425 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100426};
pineafan4f164f32022-02-26 22:07:12 +0000427
428export { command };
429export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100430export { check };