blob: 838defb32b582daf3d3c4f8a2329933e76d3b4bc [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;
Skyler Grey16ecb172023-03-05 07:30:32 +0000138 await client.memory.forceUpdate(interaction.guild.id);
TheCodedProf1f675042023-02-16 17:01:29 -0500139 break;
140 }
141 case "enabled": {
TheCodedProf267563a2023-01-21 17:00:57 -0500142 await i.deferUpdate();
TheCodedProf1f675042023-02-16 17:01:29 -0500143 ticketData.enabled = !ticketData.enabled;
144 break;
145 }
146 case "setMaxTickets": {
Skyler Grey75ea9172022-08-06 10:22:23 +0100147 await i.showModal(
TheCodedProf1f675042023-02-16 17:01:29 -0500148 new ModalBuilder()
149 .setCustomId("maxTickets")
150 .setTitle("Set max tickets")
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 .addComponents(
TheCodedProf1f675042023-02-16 17:01:29 -0500152 new ActionRowBuilder<TextInputBuilder>().setComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500153 new TextInputBuilder()
TheCodedProf1f675042023-02-16 17:01:29 -0500154 .setLabel("Max tickets - Leave blank for no limit")
155 .setCustomId("maxTickets")
156 .setPlaceholder("Enter a number")
157 .setRequired(false)
TheCodedProf1807fb32023-02-20 14:33:48 -0500158 .setValue(ticketData.maxTickets.toString())
TheCodedProf1f675042023-02-16 17:01:29 -0500159 .setMinLength(1)
160 .setMaxLength(3)
161 .setStyle(TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100162 )
163 )
TheCodedProf1f675042023-02-16 17:01:29 -0500164 )
165 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100166 embeds: [
167 new EmojiEmbed()
TheCodedProf1f675042023-02-16 17:01:29 -0500168 .setTitle("Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100169 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 .setStatus("Success")
171 .setEmoji("GUILD.TICKET.OPEN")
172 ],
173 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500174 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400175 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100176 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100177 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400178 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100179 .setCustomId("back")
180 ])
181 ]
pineafan41d93562022-07-30 22:10:15 +0100182 });
183 let out;
184 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500185 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100186 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100187 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100188 }
TheCodedProf1f675042023-02-16 17:01:29 -0500189 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500190 out = out as ModalSubmitInteraction;
TheCodedProf1807fb32023-02-20 14:33:48 -0500191 const toAdd = out.fields.getTextInputValue("maxTickets");
TheCodedProf1f675042023-02-16 17:01:29 -0500192 if(isNaN(parseInt(toAdd))) {
193 errorMessage = "You entered an invalid number - No changes were made";
194 break;
195 }
196 ticketData.maxTickets = toAdd === "" ? 0 : parseInt(toAdd);
197 break;
198 }
199 case "manageTypes": {
200 await i.deferUpdate();
201 ticketData = await manageTypes(interaction, data.tickets, m);
202 break;
pineafan41d93562022-07-30 22:10:15 +0100203 }
204 }
pineafan6702cef2022-06-13 17:52:37 +0100205 }
206 }
TheCodedProf01cba762023-02-18 15:55:05 -0500207 await interaction.deleteReply()
pineafan63fc5e22022-08-04 22:04:10 +0100208};
pineafan4f164f32022-02-26 22:07:12 +0000209
TheCodedProf1f675042023-02-16 17:01:29 -0500210
211
Skyler Grey11236ba2022-08-08 21:13:33 +0100212async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100213 let timedOut = false;
214 let backPressed = false;
215 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100216 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100217 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100218 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100219 embeds: [
220 new EmojiEmbed()
221 .setTitle("Tickets > Types")
222 .setDescription(
223 "**Custom types enabled**\n\n" +
224 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100225 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100226 "\n\n" +
227 (customTypes === null
228 ? `${getEmojiByName(
229 "TICKETS.REPORT"
230 )} Having no types will disable tickets. Please add at least 1 type or use default types`
231 : "")
pineafan6702cef2022-06-13 17:52:37 +0100232 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 .setStatus("Success")
234 .setEmoji("GUILD.TICKET.OPEN")
235 ],
TheCodedProf1f675042023-02-16 17:01:29 -0500236 components: (customTypes && customTypes.length > 0
Skyler Grey75ea9172022-08-06 10:22:23 +0100237 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500238 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500239 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100240 .setCustomId("removeTypes")
241 .setPlaceholder("Select types to remove")
242 .setMaxValues(customTypes.length)
243 .setMinValues(1)
244 .addOptions(
245 customTypes.map((t) => ({
246 label: t,
247 value: t
248 }))
249 )
250 ])
251 ]
252 : []
253 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500254 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400255 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100256 .setLabel("Back")
257 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400258 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100259 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400260 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100261 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100262 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400263 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100264 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100265 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400266 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100267 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400268 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100269 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100270 ])
271 ])
272 });
273 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100274 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500275 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100276 ticketTypes.forEach((type) => {
277 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500278 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100279 label: capitalize(type),
280 value: type,
TheCodedProf59772f82023-01-18 22:17:16 -0500281 emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100282 default: inUse.includes(type)
283 })
284 );
pineafan63fc5e22022-08-04 22:04:10 +0100285 });
TheCodedProf59772f82023-01-18 22:17:16 -0500286 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500287 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100288 .addOptions(options)
289 .setCustomId("types")
290 .setMaxValues(ticketTypes.length)
291 .setMinValues(1)
292 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100293 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100294 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100295 embeds: [
296 new EmojiEmbed()
297 .setTitle("Tickets > Types")
298 .setDescription(
299 "**Default types enabled**\n\n" +
300 "**Types in use:**\n" +
301 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100302 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100303 .join("\n")
304 )
305 .setStatus("Success")
306 .setEmoji("GUILD.TICKET.OPEN")
307 ],
308 components: [
pineafan6702cef2022-06-13 17:52:37 +0100309 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500310 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400311 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100312 .setLabel("Back")
313 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400314 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100315 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400316 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100317 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400318 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100319 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100320 ])
321 ]
322 });
323 }
324 let i;
325 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000326 i = await m.awaitMessageComponent({
327 time: 300000,
TheCodedProf267563a2023-01-21 17:00:57 -0500328 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 +0000329 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100330 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100331 timedOut = true;
332 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100333 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500334 if (i.isStringSelectMenu() && i.customId === "types") {
TheCodedProf267563a2023-01-21 17:00:57 -0500335 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500336 const types = toHexInteger(i.values, ticketTypes);
pineafan6702cef2022-06-13 17:52:37 +0100337 data.types = types;
TheCodedProf4a6d5712023-01-19 15:54:40 -0500338 } else if (i.isStringSelectMenu() && i.customId === "removeTypes") {
TheCodedProf267563a2023-01-21 17:00:57 -0500339 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500340 const types = i.values;
pineafan6702cef2022-06-13 17:52:37 +0100341 let customTypes = data.customTypes;
342 if (customTypes) {
343 customTypes = customTypes.filter((t) => !types.includes(t));
344 customTypes = customTypes.length > 0 ? customTypes : null;
pineafan6702cef2022-06-13 17:52:37 +0100345 data.customTypes = customTypes;
346 }
TheCodedProf59772f82023-01-18 22:17:16 -0500347 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100348 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500349 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100350 .setCustomId("modal")
351 .setTitle("Enter a name for the new type")
352 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500353 new ActionRowBuilder<TextInputBuilder>().addComponents(
354 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100355 .setCustomId("type")
356 .setLabel("Name")
357 .setMaxLength(100)
358 .setMinLength(1)
359 .setPlaceholder('E.g. "Server Idea"')
360 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500361 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100362 )
363 )
364 );
TheCodedProf1f675042023-02-16 17:01:29 -0500365 await i.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100366 embeds: [
367 new EmojiEmbed()
368 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100369 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100370 .setStatus("Success")
371 .setEmoji("GUILD.TICKET.OPEN")
372 ],
373 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500374 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400375 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100376 .setLabel("Back")
377 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400378 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100379 .setCustomId("back")
380 ])
381 ]
pineafan6702cef2022-06-13 17:52:37 +0100382 });
pineafan4edb7762022-06-26 19:21:04 +0100383 let out;
pineafan6702cef2022-06-13 17:52:37 +0100384 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500385 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100386 } catch (e) {
387 continue;
388 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500389 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500390 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000391 let toAdd = out.fields.getTextInputValue("type");
392 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100393 continue;
394 }
PineaFan638eb132023-01-19 10:41:22 +0000395 toAdd = toAdd.substring(0, 80);
396 try {
TheCodedProf1f675042023-02-16 17:01:29 -0500397 if(!data.customTypes) data.customTypes = [];
TheCodedProf1807fb32023-02-20 14:33:48 -0500398 data.customTypes.push(toAdd);
PineaFan638eb132023-01-19 10:41:22 +0000399 } catch {
400 continue;
401 }
PineaFan638eb132023-01-19 10:41:22 +0000402 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 };