blob: d62a4268f2f21cbf4c8fe69b88857536c1af179a [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,
TheCodedProf21c08592022-09-13 14:14:43 -04006 ActionRowBuilder,
7 Component,
8 ButtonBuilder,
Skyler Grey75ea9172022-08-06 10:22:23 +01009 MessageComponentInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -040010 ButtonStyle
Skyler Grey75ea9172022-08-06 10:22:23 +010011} from "discord.js";
PineaFan100df682023-01-02 13:26:08 +000012import type { 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 {
TheCodedProf21c08592022-09-13 14:14:43 -040028 embed: Discord.EmbedBuilder;
pineafanea063042022-05-19 19:08:44 +010029 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010030 description = "";
31 pageId = 0;
TheCodedProf21c08592022-09-13 14:14:43 -040032 setEmbed(embed: Discord.EmbedBuilder) {
Skyler Grey75ea9172022-08-06 10:22:23 +010033 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),
pineafan3a02ea32022-08-11 21:35:04 +0100164 nickname: member.nickname ?? "*None set*",
Skyler Grey75ea9172022-08-06 10:22:23 +0100165 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;
Skyler Greyad002172022-08-16 18:48:26 +0100227 let timedOut = false;
228 while (!timedOut) {
TheCodedProf21c08592022-09-13 14:14:43 -0400229 const em = new Discord.EmbedBuilder(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) {
Skyler Greyad002172022-08-16 18:48:26 +0100234 const options: MessageSelectOptionData[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100235 embeds.forEach((embed) => {
Skyler Greyad002172022-08-16 18:48:26 +0100236 options.push({
237 label: embed.title,
238 value: embed.pageId.toString(),
239 description: embed.description || ""
240 });
pineafan63fc5e22022-08-04 22:04:10 +0100241 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100242 selectPane = [
TheCodedProf21c08592022-09-13 14:14:43 -0400243 new ActionRowBuilder().addComponents([
244 new Discord.SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100245 .addOptions(options)
246 .setCustomId("page")
247 .setMaxValues(1)
248 .setPlaceholder("Choose a page...")
249 ])
250 ];
pineafanea063042022-05-19 19:08:44 +0100251 }
pineafan377794f2022-04-18 19:01:01 +0100252 await interaction.editReply({
pineafan34369e62022-05-18 16:52:37 +0100253 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100254 components: selectPane.concat([
TheCodedProf21c08592022-09-13 14:14:43 -0400255 new ActionRowBuilder().addComponents([
256 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100257 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400258 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 .setCustomId("left")
260 .setDisabled(page === 0),
TheCodedProf21c08592022-09-13 14:14:43 -0400261 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100262 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400263 .setStyle(selectPaneOpen ? ButtonStyle.Primary : ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100264 .setCustomId("select")
265 .setDisabled(false),
TheCodedProf21c08592022-09-13 14:14:43 -0400266 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100267 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
268 .setCustomId("right")
TheCodedProf21c08592022-09-13 14:14:43 -0400269 .setStyle(ButtonStyle.Secondary)
Skyler Greyad002172022-08-16 18:48:26 +0100270 .setDisabled(page === embeds.length - 1)
Skyler Grey75ea9172022-08-06 10:22:23 +0100271 ])
272 ])
pineafan63fc5e22022-08-04 22:04:10 +0100273 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100274 let i: MessageComponentInteraction;
pineafan377794f2022-04-18 19:01:01 +0100275 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100276 i = await m.awaitMessageComponent({ time: 300000 });
277 } catch {
Skyler Greyad002172022-08-16 18:48:26 +0100278 timedOut = true;
279 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100280 }
pineafan63fc5e22022-08-04 22:04:10 +0100281 i.deferUpdate();
TheCodedProf21c08592022-09-13 14:14:43 -0400282 if ((i.component as Component).customId === "left") {
pineafan377794f2022-04-18 19:01:01 +0100283 if (page > 0) page--;
pineafanea063042022-05-19 19:08:44 +0100284 selectPaneOpen = false;
TheCodedProf21c08592022-09-13 14:14:43 -0400285 } else if ((i.component as Component).customId === "right") {
pineafan377794f2022-04-18 19:01:01 +0100286 if (page < embeds.length - 1) page++;
pineafanea063042022-05-19 19:08:44 +0100287 selectPaneOpen = false;
TheCodedProf21c08592022-09-13 14:14:43 -0400288 } else if ((i.component as Component).customId === "select") {
pineafanea063042022-05-19 19:08:44 +0100289 selectPaneOpen = !selectPaneOpen;
TheCodedProf21c08592022-09-13 14:14:43 -0400290 } else if ((i.component as Component).customId === "page") {
Skyler Grey1a67e182022-08-04 23:05:44 +0100291 page = parseInt((i as SelectMenuInteraction).values[0]);
pineafanea063042022-05-19 19:08:44 +0100292 selectPaneOpen = false;
pineafan377794f2022-04-18 19:01:01 +0100293 }
294 }
TheCodedProf21c08592022-09-13 14:14:43 -0400295 const em = new Discord.EmbedBuilder(embeds[page].embed);
Skyler Greyad002172022-08-16 18:48:26 +0100296 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | Message closed");
Skyler Grey75ea9172022-08-06 10:22:23 +0100297 await interaction.editReply({
298 embeds: [em],
Skyler Greyad002172022-08-16 18:48:26 +0100299 components: []
Skyler Grey75ea9172022-08-06 10:22:23 +0100300 });
pineafan63fc5e22022-08-04 22:04:10 +0100301};
pineafan4f164f32022-02-26 22:07:12 +0000302
Skyler Grey1a67e182022-08-04 23:05:44 +0100303const check = () => {
pineafan4f164f32022-02-26 22:07:12 +0000304 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100305};
pineafan4f164f32022-02-26 22:07:12 +0000306
307export { command };
308export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100309export { check };