blob: 1c493bbc2a4e88bdb7a2531255b6c4d944dd54f3 [file] [log] [blame]
PineaFan538d3752023-01-12 21:48:23 +00001import { Interaction, ButtonBuilder, CommandInteraction, Role, ButtonStyle, ButtonInteraction } from "discord.js";
pineafan63fc5e22022-08-04 22:04:10 +01002import EmojiEmbed from "../utils/generateEmojiEmbed.js";
TheCodedProf21c08592022-09-13 14:14:43 -04003import { ActionRowBuilder, SelectMenuBuilder } from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +01004import getEmojiByName from "../utils/getEmojiByName.js";
5import client from "../utils/client.js";
pineafane23c4ec2022-07-27 21:56:27 +01006import { LoadingEmbed } from "../utils/defaultEmbeds.js";
Skyler Grey11236ba2022-08-08 21:13:33 +01007import type { GuildConfig } from "../utils/database.js";
pineafan813bdf42022-07-24 10:39:10 +01008
Skyler Grey11236ba2022-08-08 21:13:33 +01009export interface RoleMenuSchema {
10 guild: string;
11 guildName: string;
12 guildIcon: string;
13 user: string;
14 username: string;
15 data: GuildConfig["roleMenu"]["options"];
16 interaction: Interaction;
17}
18
PineaFan538d3752023-01-12 21:48:23 +000019export async function callback(interaction: CommandInteraction | ButtonInteraction) {
TheCodedProf21c08592022-09-13 14:14:43 -040020 if(!interaction.guild) return interaction.reply({ content: "This command can only be used in a server.", ephemeral: true });
21 if(!interaction.member) return interaction.reply({ content: "You must be in a server to use this command.", ephemeral: true });
pineafan63fc5e22022-08-04 22:04:10 +010022 const config = await client.database.guilds.read(interaction.guild.id);
Skyler Grey75ea9172022-08-06 10:22:23 +010023 if (!config.roleMenu.enabled)
24 return await interaction.reply({
25 embeds: [
26 new EmojiEmbed()
27 .setTitle("Roles")
28 .setDescription(
29 "Self roles are currently disabled. Please contact a staff member or try again later."
30 )
31 .setStatus("Danger")
32 .setEmoji("CONTROL.BLOCKCROSS")
33 ],
34 ephemeral: true
35 });
36 if (config.roleMenu.options.length === 0)
37 return await interaction.reply({
38 embeds: [
39 new EmojiEmbed()
40 .setTitle("Roles")
Skyler Grey11236ba2022-08-08 21:13:33 +010041 .setDescription("There are no roles available. Please contact a staff member or try again later.")
Skyler Grey75ea9172022-08-06 10:22:23 +010042 .setStatus("Danger")
43 .setEmoji("CONTROL.BLOCKCROSS")
44 ],
45 ephemeral: true
46 });
47 await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
pineafan813bdf42022-07-24 10:39:10 +010048 let m;
49 if (config.roleMenu.allowWebUI) {
pineafan63fc5e22022-08-04 22:04:10 +010050 let code = "";
51 let length = 5;
52 let itt = 0;
Skyler Grey11236ba2022-08-08 21:13:33 +010053 const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
pineafan63fc5e22022-08-04 22:04:10 +010054 let valid = false;
55 while (!valid) {
56 itt += 1;
57 code = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010058 for (let i = 0; i < length; i++) {
59 code += chars.charAt(Math.floor(Math.random() * chars.length));
60 }
pineafan813bdf42022-07-24 10:39:10 +010061 if (code in client.roleMenu) continue;
62 if (itt > 1000) {
pineafan63fc5e22022-08-04 22:04:10 +010063 itt = 0;
64 length += 1;
pineafan813bdf42022-07-24 10:39:10 +010065 continue;
66 }
pineafan63fc5e22022-08-04 22:04:10 +010067 valid = true;
pineafan813bdf42022-07-24 10:39:10 +010068 }
69 client.roleMenu[code] = {
70 guild: interaction.guild.id,
71 guildName: interaction.guild.name,
TheCodedProf21c08592022-09-13 14:14:43 -040072 guildIcon: interaction.guild.iconURL({ extension: "png" }),
pineafan813bdf42022-07-24 10:39:10 +010073 user: interaction.member.user.id,
74 username: interaction.member.user.username,
75 data: config.roleMenu.options,
76 interaction: interaction
77 };
pineafan63fc5e22022-08-04 22:04:10 +010078 let up = true;
Skyler Grey11236ba2022-08-08 21:13:33 +010079 up = false; // FIXME: Role menu does not yet exist, so the web UI is never up
80 /* try {
81 const status = await fetch(client.config.baseUrl).then((res) => res.status);
pineafan63fc5e22022-08-04 22:04:10 +010082 if (status !== 200) up = false;
Skyler Grey75ea9172022-08-06 10:22:23 +010083 } catch {
84 up = false;
Skyler Grey11236ba2022-08-08 21:13:33 +010085 }*/
pineafan813bdf42022-07-24 10:39:10 +010086 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010087 embeds: [
88 new EmojiEmbed()
89 .setTitle("Roles")
90 .setDescription("Select how to choose your roles")
91 .setStatus("Success")
92 .setEmoji("GUILD.GREEN")
93 ],
94 components: [
TheCodedProf21c08592022-09-13 14:14:43 -040095 new ActionRowBuilder().addComponents([
96 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010097 .setLabel("Online")
TheCodedProf21c08592022-09-13 14:14:43 -040098 .setStyle(ButtonStyle.Link)
Skyler Grey75ea9172022-08-06 10:22:23 +010099 .setDisabled(!up)
Skyler Grey11236ba2022-08-08 21:13:33 +0100100 .setURL(`${client.config.baseUrl}nucleus/rolemenu?code=${code}`),
TheCodedProf21c08592022-09-13 14:14:43 -0400101 new ButtonBuilder().setLabel("Manual").setStyle(ButtonStyle.Primary).setCustomId("manual")
Skyler Grey75ea9172022-08-06 10:22:23 +0100102 ])
103 ]
pineafan63fc5e22022-08-04 22:04:10 +0100104 });
pineafan813bdf42022-07-24 10:39:10 +0100105 }
106 let component;
TheCodedProf21c08592022-09-13 14:14:43 -0400107 if (!m) return;
Skyler Grey75ea9172022-08-06 10:22:23 +0100108 try {
109 component = await m.awaitMessageComponent({ time: 300000 });
110 } catch (e) {
111 return;
112 }
pineafan63fc5e22022-08-04 22:04:10 +0100113 component.deferUpdate();
TheCodedProf21c08592022-09-13 14:14:43 -0400114 let rolesToAdd: Role[] = [];
pineafan813bdf42022-07-24 10:39:10 +0100115 for (let i = 0; i < config.roleMenu.options.length; i++) {
pineafan63fc5e22022-08-04 22:04:10 +0100116 const object = config.roleMenu.options[i];
117 const m = await interaction.editReply({
pineafan813bdf42022-07-24 10:39:10 +0100118 embeds: [
119 new EmojiEmbed()
120 .setTitle("Roles")
121 .setEmoji("GUILD.GREEN")
Skyler Grey75ea9172022-08-06 10:22:23 +0100122 .setDescription(
123 `**${object.name}**` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100124 (object.description ? `\n${object.description}` : "") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 `\n\nSelect ${object.min}` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100126 (object.min !== object.max ? ` to ${object.max}` : "") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100127 ` role${object.max === 1 ? "" : "s"} to add.`
128 )
pineafan813bdf42022-07-24 10:39:10 +0100129 .setStatus("Success")
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 .setFooter({
131 text: `Step ${i + 1}/${config.roleMenu.options.length}`
132 })
pineafan813bdf42022-07-24 10:39:10 +0100133 ],
134 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400135 new ActionRowBuilder().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100136 [
TheCodedProf21c08592022-09-13 14:14:43 -0400137 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100138 .setLabel("Cancel")
TheCodedProf21c08592022-09-13 14:14:43 -0400139 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100140 .setCustomId("cancel")
141 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
142 ].concat(
143 object.min === 0
144 ? [
TheCodedProf21c08592022-09-13 14:14:43 -0400145 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 .setLabel("Skip")
TheCodedProf21c08592022-09-13 14:14:43 -0400147 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100148 .setCustomId("skip")
Skyler Grey11236ba2022-08-08 21:13:33 +0100149 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 ]
151 : []
152 )
153 )
154 ].concat([
TheCodedProf21c08592022-09-13 14:14:43 -0400155 new ActionRowBuilder().addComponents([
156 new SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100157 .setPlaceholder(`${object.name}`)
158 .setCustomId("rolemenu")
159 .setMinValues(object.min)
160 .setMaxValues(object.max)
161 .setOptions(
162 object.options.map((o) => {
163 return {
164 label: o.name,
165 description: o.description,
166 value: o.role
167 };
168 })
169 )
170 ])
171 ])
pineafan813bdf42022-07-24 10:39:10 +0100172 });
173 let component;
174 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 component = await m.awaitMessageComponent({ time: 300000 });
pineafan813bdf42022-07-24 10:39:10 +0100176 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100177 return;
pineafan813bdf42022-07-24 10:39:10 +0100178 }
pineafan63fc5e22022-08-04 22:04:10 +0100179 component.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100180 if (component.customId === "rolemenu") {
pineafan63fc5e22022-08-04 22:04:10 +0100181 rolesToAdd = rolesToAdd.concat(component.values);
pineafane23c4ec2022-07-27 21:56:27 +0100182 } else if (component.customId === "cancel") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100183 return await interaction.editReply({
184 embeds: [
185 new EmojiEmbed()
186 .setTitle("Roles")
187 .setDescription("Cancelled. No changes were made.")
188 .setStatus("Danger")
189 .setEmoji("GUILD.RED")
190 ],
191 components: []
192 });
pineafan813bdf42022-07-24 10:39:10 +0100193 }
194 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100195 let rolesToRemove = config.roleMenu.options.map((o) => o.options.map((o) => o.role)).flat();
Skyler Grey75ea9172022-08-06 10:22:23 +0100196 const memberRoles = interaction.member.roles.cache.map((r) => r.id);
Skyler Grey11236ba2022-08-08 21:13:33 +0100197 rolesToRemove = rolesToRemove.filter((r) => memberRoles.includes(r)).filter((r) => !rolesToAdd.includes(r));
Skyler Grey75ea9172022-08-06 10:22:23 +0100198 rolesToAdd = rolesToAdd.filter((r) => !memberRoles.includes(r));
pineafan813bdf42022-07-24 10:39:10 +0100199 try {
pineafan63fc5e22022-08-04 22:04:10 +0100200 await interaction.member.roles.remove(rolesToRemove);
201 await interaction.member.roles.add(rolesToAdd);
pineafan813bdf42022-07-24 10:39:10 +0100202 } catch (e) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100203 return await interaction.reply({
204 embeds: [
205 new EmojiEmbed()
206 .setTitle("Roles")
207 .setDescription(
208 "Something went wrong and your roles were not added. Please contact a staff member or try again later."
209 )
210 .setStatus("Danger")
211 .setEmoji("GUILD.RED")
212 ],
213 components: []
214 });
pineafan813bdf42022-07-24 10:39:10 +0100215 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100216 await interaction.editReply({
217 embeds: [
218 new EmojiEmbed()
219 .setTitle("Roles")
Skyler Grey11236ba2022-08-08 21:13:33 +0100220 .setDescription("Roles have been added. You may close this message.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 .setStatus("Success")
222 .setEmoji("GUILD.GREEN")
223 ],
224 components: []
225 });
pineafan63fc5e22022-08-04 22:04:10 +0100226 return;
pineafan813bdf42022-07-24 10:39:10 +0100227}