blob: 64c1ceb60503fa4f0e15820ddf4a20d7141b6d63 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01002import Discord, {
3 CommandInteraction,
4 GuildMember,
5 Message,
6 MessageActionRow,
7 MessageActionRowComponent,
8 MessageButton,
9 MessageComponentInteraction,
10 SelectMenuInteraction
11} from "discord.js";
Skyler Grey11236ba2022-08-08 21:13:33 +010012import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010013import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan377794f2022-04-18 19:01:01 +010014import getEmojiByName from "../../utils/getEmojiByName.js";
15import generateKeyValueList from "../../utils/generateKeyValueList.js";
pineafan34369e62022-05-18 16:52:37 +010016import createPageIndicator from "../../utils/createPageIndicator.js";
pineafan63fc5e22022-08-04 22:04:10 +010017import client from "../../utils/client.js";
pineafan4f164f32022-02-26 22:07:12 +000018
19const command = (builder: SlashCommandSubcommandBuilder) =>
20 builder
pineafan63fc5e22022-08-04 22:04:10 +010021 .setName("about")
22 .setDescription("Shows info about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010023 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010024 option.setName("user").setDescription("The user to get info about | Default: Yourself")
Skyler Grey75ea9172022-08-06 10:22:23 +010025 );
pineafanea063042022-05-19 19:08:44 +010026
27class Embed {
28 embed: Discord.MessageEmbed;
29 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010030 description = "";
31 pageId = 0;
Skyler Grey75ea9172022-08-06 10:22:23 +010032 setEmbed(embed: Discord.MessageEmbed) {
33 this.embed = embed;
34 return this;
35 }
36 setTitle(title: string) {
37 this.title = title;
38 return this;
39 }
40 setDescription(description: string) {
41 this.description = description;
42 return this;
43 }
44 setPageId(pageId: number) {
45 this.pageId = pageId;
46 return this;
47 }
pineafanea063042022-05-19 19:08:44 +010048}
49
Skyler Grey1a67e182022-08-04 23:05:44 +010050const callback = async (interaction: CommandInteraction): Promise<void> => {
Skyler Greyc634e2b2022-08-06 17:50:48 +010051 if (!interaction.guild) return;
pineafan63fc5e22022-08-04 22:04:10 +010052 const { renderUser, renderDelta } = client.logger;
Skyler Grey11236ba2022-08-08 21:13:33 +010053 const member = (interaction.options.getMember("user") ?? interaction.member) as Discord.GuildMember;
pineafan63fc5e22022-08-04 22:04:10 +010054 const flags: string[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +010055 if (
56 [
57 "438733159748599813", // Pinea
58 "317731855317336067", // Mini
59 "261900651230003201", // Coded
60 "511655498676699136" // Zan
61 ].includes(member.user.id)
62 ) {
63 flags.push("NUCLEUSDEVELOPER");
64 }
65 if (
66 (await client.guilds.cache.get("684492926528651336")?.members.fetch())
Skyler Grey11236ba2022-08-08 21:13:33 +010067 ?.filter((m: GuildMember) => m.roles.cache.has("760896837866749972"))
Skyler Grey75ea9172022-08-06 10:22:23 +010068 ?.map((m: GuildMember) => m.id)
69 .includes(member.user.id)
70 ) {
71 flags.push("CLICKSDEVELOPER");
72 }
73 member.user.flags.toArray().map((flag) => {
pineafan63fc5e22022-08-04 22:04:10 +010074 flags.push(flag.toString());
75 });
Skyler Grey75ea9172022-08-06 10:22:23 +010076 if (member.user.bot) {
77 flags.push("BOT");
78 }
pineafan377794f2022-04-18 19:01:01 +010079 // Check if they are boosting the server
Skyler Grey75ea9172022-08-06 10:22:23 +010080 if (member.premiumSince) {
81 flags.push("BOOSTER");
82 }
pineafan63fc5e22022-08-04 22:04:10 +010083 const nameReplacements = {
Skyler Grey75ea9172022-08-06 10:22:23 +010084 NUCLEUSDEVELOPER: "**Nucleus Developer**",
85 CLICKSDEVELOPER: "Clicks Developer",
86 HOUSE_BRAVERY: "Hypesquad Bravery",
87 HOUSE_BRILLIANCE: "Hypesquad Brilliance",
88 HOUSE_BALANCE: "Hypesquad Balance",
89 HYPESQUAD_EVENTS: "Hypesquad Events",
90 EARLY_SUPPORTER: "Early Supporter",
91 BUGHUNTER_LEVEL_1: "Bug Hunter Level 1",
92 BUGHUNTER_LEVEL_2: "Bug Hunter Level 2",
93 PARTNERED_SERVER_OWNER: "Partnered Server Owner",
94 DISCORD_EMPLOYEE: "Discord Staff",
95 EARLY_VERIFIED_BOT_DEVELOPER: "Verified Bot Developer",
96 BOT: "Bot",
97 BOOSTER: "Server Booster"
pineafan63fc5e22022-08-04 22:04:10 +010098 };
99 const members = await interaction.guild.members.fetch();
100 const membersArray = [...members.values()];
Skyler Greyc634e2b2022-08-06 17:50:48 +0100101 membersArray.sort((a, b) => {
102 if (a.joinedTimestamp === null) return 1;
103 if (b.joinedTimestamp === null) return -1;
104 return a.joinedTimestamp - b.joinedTimestamp;
105 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 const joinPos = membersArray.findIndex((m) => m.id === member.user.id);
pineafan377794f2022-04-18 19:01:01 +0100107
Skyler Grey11236ba2022-08-08 21:13:33 +0100108 const roles = member.roles.cache.filter((r) => r.id !== interaction.guild!.id).sort();
pineafan377794f2022-04-18 19:01:01 +0100109 let s = "";
110 let count = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100111 let ended = false;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100112 for (const roleId in roles) {
113 const string = `<@&${roleId}>, `;
Skyler Grey75ea9172022-08-06 10:22:23 +0100114 if (s.length + string.length > 1000) {
pineafan63fc5e22022-08-04 22:04:10 +0100115 ended = true;
116 s += `and ${roles.size - count} more`;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100117 break;
pineafan63fc5e22022-08-04 22:04:10 +0100118 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 count++;
pineafan377794f2022-04-18 19:01:01 +0100120 s += string;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100121 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100122 if (s.length > 0 && !ended) s = s.slice(0, -2);
pineafan377794f2022-04-18 19:01:01 +0100123
pineafan63fc5e22022-08-04 22:04:10 +0100124 let perms = "";
125 const permsArray = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100126 ADMINISTRATOR: "Administrator",
127 MANAGE_GUILD: "Manage Server",
128 MANAGE_ROLES: "Manage Roles",
129 MANAGE_CHANNELS: "Manage Channels",
130 KICK_MEMBERS: "Kick Members",
131 BAN_MEMBERS: "Ban Members",
132 MODERATE_MEMBERS: "Moderate Members",
133 MANAGE_NICKNAMES: "Manage Nicknames",
134 MANAGE_WEBHOOKS: "Manage Webhooks",
135 MANAGE_MESSAGES: "Manage Messages",
136 VIEW_AUDIT_LOG: "View Audit Log",
137 MENTION_EVERYONE: "Mention Everyone"
pineafan63fc5e22022-08-04 22:04:10 +0100138 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100139 Object.keys(permsArray).map((perm) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100140 const hasPerm = member.permissions.has(perm as Discord.PermissionString);
141 perms += `${getEmojiByName("CONTROL." + (hasPerm ? "TICK" : "CROSS"))} ${permsArray[perm]}\n`;
pineafan63fc5e22022-08-04 22:04:10 +0100142 });
pineafan377794f2022-04-18 19:01:01 +0100143
pineafanea063042022-05-19 19:08:44 +0100144 let selectPaneOpen = false;
145
pineafan63fc5e22022-08-04 22:04:10 +0100146 const embeds = [
pineafanea063042022-05-19 19:08:44 +0100147 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100148 .setEmbed(
149 new EmojiEmbed()
150 .setTitle("User Info: General")
151 .setStatus("Success")
152 .setEmoji("MEMBER.JOIN")
153 .setDescription(
154 flags
155 .map((flag) => {
156 if (nameReplacements[flag]) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100157 return getEmojiByName(`BADGES.${flag}`) + " " + nameReplacements[flag];
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 }
159 })
160 .join("\n") +
161 "\n\n" +
162 generateKeyValueList({
163 member: renderUser(member.user),
164 nickname: member.nickname || "*None set*",
165 id: `\`${member.id}\``,
Skyler Grey11236ba2022-08-08 21:13:33 +0100166 "joined the server": renderDelta(member.joinedTimestamp),
167 "joined discord": renderDelta(member.user.createdTimestamp),
Skyler Grey75ea9172022-08-06 10:22:23 +0100168 "boost status": member.premiumSince
Skyler Grey11236ba2022-08-08 21:13:33 +0100169 ? `Started boosting ${renderDelta(member.premiumSinceTimestamp)}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 : "*Not boosting*",
171 "join position": `${joinPos + 1}`
172 })
173 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100174 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
175 .setImage((await member.user.fetch()).bannerURL({ format: "gif" }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100176 )
177 .setTitle("General")
178 .setDescription("General information about the user")
179 .setPageId(0),
pineafanea063042022-05-19 19:08:44 +0100180 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100181 .setEmbed(
182 new EmojiEmbed()
183 .setTitle("User Info: Roles")
184 .setStatus("Success")
185 .setEmoji("GUILD.ROLES.CREATE")
186 .setDescription(
187 generateKeyValueList({
188 member: renderUser(member.user),
189 id: `\`${member.id}\``,
190 roles: `${member.roles.cache.size - 1}`
191 }) +
192 "\n" +
193 (s.length > 0 ? s : "*None*") +
194 "\n"
195 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100196 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100197 )
198 .setTitle("Roles")
199 .setDescription("Roles the user has")
200 .setPageId(1),
pineafanea063042022-05-19 19:08:44 +0100201 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100202 .setEmbed(
203 new EmojiEmbed()
204 .setTitle("User Info: Key Permissions")
205 .setStatus("Success")
206 .setEmoji("GUILD.ROLES.CREATE")
207 .setDescription(
208 generateKeyValueList({
209 member: renderUser(member.user),
210 id: `\`${member.id}\``
211 }) +
212 "\n" +
213 perms
214 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100215 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100216 )
217 .setTitle("Key Permissions")
218 .setDescription("Key permissions the user has")
219 .setPageId(2)
pineafan63fc5e22022-08-04 22:04:10 +0100220 ];
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 const m = (await interaction.reply({
222 embeds: LoadingEmbed,
223 fetchReply: true,
224 ephemeral: true
225 })) as Message;
pineafan63fc5e22022-08-04 22:04:10 +0100226 let page = 0;
227 let breakReason = "";
pineafan377794f2022-04-18 19:01:01 +0100228 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +0100229 const em = new Discord.MessageEmbed(embeds[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100230 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page));
pineafan63fc5e22022-08-04 22:04:10 +0100231 let selectPane = [];
pineafanea063042022-05-19 19:08:44 +0100232
233 if (selectPaneOpen) {
pineafan63fc5e22022-08-04 22:04:10 +0100234 const options = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100235 embeds.forEach((embed) => {
236 options.push(
237 new SelectMenuOption({
238 label: embed.title,
239 value: embed.pageId.toString(),
240 description: embed.description || ""
241 })
242 );
pineafan63fc5e22022-08-04 22:04:10 +0100243 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 selectPane = [
245 new MessageActionRow().addComponents([
246 new Discord.MessageSelectMenu()
247 .addOptions(options)
248 .setCustomId("page")
249 .setMaxValues(1)
250 .setPlaceholder("Choose a page...")
251 ])
252 ];
pineafanea063042022-05-19 19:08:44 +0100253 }
pineafan377794f2022-04-18 19:01:01 +0100254 await interaction.editReply({
pineafan34369e62022-05-18 16:52:37 +0100255 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100256 components: selectPane.concat([
257 new MessageActionRow().addComponents([
258 new MessageButton()
259 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
260 .setStyle("SECONDARY")
261 .setCustomId("left")
262 .setDisabled(page === 0),
263 new MessageButton()
264 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
265 .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
266 .setCustomId("select")
267 .setDisabled(false),
268 new MessageButton()
269 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
270 .setCustomId("right")
271 .setStyle("SECONDARY")
272 .setDisabled(page === embeds.length - 1),
273 new MessageButton()
274 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
275 .setCustomId("close")
276 .setStyle("DANGER")
277 ])
278 ])
pineafan63fc5e22022-08-04 22:04:10 +0100279 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100280 let i: MessageComponentInteraction;
pineafan377794f2022-04-18 19:01:01 +0100281 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100282 i = await m.awaitMessageComponent({ time: 300000 });
283 } catch {
284 breakReason = "Message timed out";
285 break;
286 }
pineafan63fc5e22022-08-04 22:04:10 +0100287 i.deferUpdate();
Skyler Grey1a67e182022-08-04 23:05:44 +0100288 if ((i.component as MessageActionRowComponent).customId === "left") {
pineafan377794f2022-04-18 19:01:01 +0100289 if (page > 0) page--;
pineafanea063042022-05-19 19:08:44 +0100290 selectPaneOpen = false;
Skyler Grey11236ba2022-08-08 21:13:33 +0100291 } else if ((i.component as MessageActionRowComponent).customId === "right") {
pineafan377794f2022-04-18 19:01:01 +0100292 if (page < embeds.length - 1) page++;
pineafanea063042022-05-19 19:08:44 +0100293 selectPaneOpen = false;
Skyler Grey11236ba2022-08-08 21:13:33 +0100294 } else if ((i.component as MessageActionRowComponent).customId === "select") {
pineafanea063042022-05-19 19:08:44 +0100295 selectPaneOpen = !selectPaneOpen;
Skyler Grey11236ba2022-08-08 21:13:33 +0100296 } else if ((i.component as MessageActionRowComponent).customId === "close") {
pineafan167bde32022-05-19 19:33:46 +0100297 breakReason = "Message closed";
pineafan377794f2022-04-18 19:01:01 +0100298 break;
Skyler Grey11236ba2022-08-08 21:13:33 +0100299 } else if ((i.component as MessageActionRowComponent).customId === "page") {
Skyler Grey1a67e182022-08-04 23:05:44 +0100300 page = parseInt((i as SelectMenuInteraction).values[0]);
pineafanea063042022-05-19 19:08:44 +0100301 selectPaneOpen = false;
pineafan377794f2022-04-18 19:01:01 +0100302 } else {
pineafan167bde32022-05-19 19:33:46 +0100303 breakReason = "Message closed";
pineafan377794f2022-04-18 19:01:01 +0100304 break;
305 }
306 }
pineafan63fc5e22022-08-04 22:04:10 +0100307 const em = new Discord.MessageEmbed(embeds[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100308 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | " + breakReason);
Skyler Grey75ea9172022-08-06 10:22:23 +0100309 await interaction.editReply({
310 embeds: [em],
311 components: [
312 new MessageActionRow().addComponents([
313 new MessageButton()
314 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
315 .setStyle("SECONDARY")
316 .setCustomId("left")
317 .setDisabled(true),
318 new MessageButton()
319 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
320 .setStyle("SECONDARY")
321 .setCustomId("select")
322 .setDisabled(true),
323 new MessageButton()
324 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
325 .setCustomId("right")
326 .setStyle("SECONDARY")
327 .setDisabled(true),
328 new MessageButton()
329 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
330 .setCustomId("close")
331 .setStyle("DANGER")
332 .setDisabled(true)
333 ])
334 ]
335 });
pineafan63fc5e22022-08-04 22:04:10 +0100336};
pineafan4f164f32022-02-26 22:07:12 +0000337
Skyler Grey1a67e182022-08-04 23:05:44 +0100338const check = () => {
pineafan4f164f32022-02-26 22:07:12 +0000339 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100340};
pineafan4f164f32022-02-26 22:07:12 +0000341
342export { command };
343export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100344export { check };