blob: 44e6d3bcd5be1311642cdfe2bb99b28f96c85187 [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,
Skyler Greyad002172022-08-16 18:48:26 +010010 MessageSelectOptionData,
TheCodedProf21c08592022-09-13 14:14:43 -040011 SelectMenuInteraction,
12 ButtonStyle
Skyler Grey75ea9172022-08-06 10:22:23 +010013} from "discord.js";
Skyler Greyad002172022-08-16 18:48:26 +010014import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010015import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan377794f2022-04-18 19:01:01 +010016import getEmojiByName from "../../utils/getEmojiByName.js";
17import generateKeyValueList from "../../utils/generateKeyValueList.js";
pineafan34369e62022-05-18 16:52:37 +010018import createPageIndicator from "../../utils/createPageIndicator.js";
pineafan63fc5e22022-08-04 22:04:10 +010019import client from "../../utils/client.js";
pineafan4f164f32022-02-26 22:07:12 +000020
21const command = (builder: SlashCommandSubcommandBuilder) =>
22 builder
pineafan63fc5e22022-08-04 22:04:10 +010023 .setName("about")
24 .setDescription("Shows info about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010025 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010026 option.setName("user").setDescription("The user to get info about | Default: Yourself")
Skyler Grey75ea9172022-08-06 10:22:23 +010027 );
pineafanea063042022-05-19 19:08:44 +010028
29class Embed {
TheCodedProf21c08592022-09-13 14:14:43 -040030 embed: Discord.EmbedBuilder;
pineafanea063042022-05-19 19:08:44 +010031 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010032 description = "";
33 pageId = 0;
TheCodedProf21c08592022-09-13 14:14:43 -040034 setEmbed(embed: Discord.EmbedBuilder) {
Skyler Grey75ea9172022-08-06 10:22:23 +010035 this.embed = embed;
36 return this;
37 }
38 setTitle(title: string) {
39 this.title = title;
40 return this;
41 }
42 setDescription(description: string) {
43 this.description = description;
44 return this;
45 }
46 setPageId(pageId: number) {
47 this.pageId = pageId;
48 return this;
49 }
pineafanea063042022-05-19 19:08:44 +010050}
51
Skyler Grey1a67e182022-08-04 23:05:44 +010052const callback = async (interaction: CommandInteraction): Promise<void> => {
Skyler Greyc634e2b2022-08-06 17:50:48 +010053 if (!interaction.guild) return;
pineafan63fc5e22022-08-04 22:04:10 +010054 const { renderUser, renderDelta } = client.logger;
Skyler Grey11236ba2022-08-08 21:13:33 +010055 const member = (interaction.options.getMember("user") ?? interaction.member) as Discord.GuildMember;
pineafan63fc5e22022-08-04 22:04:10 +010056 const flags: string[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +010057 if (
58 [
59 "438733159748599813", // Pinea
60 "317731855317336067", // Mini
61 "261900651230003201", // Coded
62 "511655498676699136" // Zan
63 ].includes(member.user.id)
64 ) {
65 flags.push("NUCLEUSDEVELOPER");
66 }
67 if (
68 (await client.guilds.cache.get("684492926528651336")?.members.fetch())
Skyler Grey11236ba2022-08-08 21:13:33 +010069 ?.filter((m: GuildMember) => m.roles.cache.has("760896837866749972"))
Skyler Grey75ea9172022-08-06 10:22:23 +010070 ?.map((m: GuildMember) => m.id)
71 .includes(member.user.id)
72 ) {
73 flags.push("CLICKSDEVELOPER");
74 }
75 member.user.flags.toArray().map((flag) => {
pineafan63fc5e22022-08-04 22:04:10 +010076 flags.push(flag.toString());
77 });
Skyler Grey75ea9172022-08-06 10:22:23 +010078 if (member.user.bot) {
79 flags.push("BOT");
80 }
pineafan377794f2022-04-18 19:01:01 +010081 // Check if they are boosting the server
Skyler Grey75ea9172022-08-06 10:22:23 +010082 if (member.premiumSince) {
83 flags.push("BOOSTER");
84 }
pineafan63fc5e22022-08-04 22:04:10 +010085 const nameReplacements = {
Skyler Grey75ea9172022-08-06 10:22:23 +010086 NUCLEUSDEVELOPER: "**Nucleus Developer**",
87 CLICKSDEVELOPER: "Clicks Developer",
88 HOUSE_BRAVERY: "Hypesquad Bravery",
89 HOUSE_BRILLIANCE: "Hypesquad Brilliance",
90 HOUSE_BALANCE: "Hypesquad Balance",
91 HYPESQUAD_EVENTS: "Hypesquad Events",
92 EARLY_SUPPORTER: "Early Supporter",
93 BUGHUNTER_LEVEL_1: "Bug Hunter Level 1",
94 BUGHUNTER_LEVEL_2: "Bug Hunter Level 2",
95 PARTNERED_SERVER_OWNER: "Partnered Server Owner",
96 DISCORD_EMPLOYEE: "Discord Staff",
97 EARLY_VERIFIED_BOT_DEVELOPER: "Verified Bot Developer",
98 BOT: "Bot",
99 BOOSTER: "Server Booster"
pineafan63fc5e22022-08-04 22:04:10 +0100100 };
101 const members = await interaction.guild.members.fetch();
102 const membersArray = [...members.values()];
Skyler Greyc634e2b2022-08-06 17:50:48 +0100103 membersArray.sort((a, b) => {
104 if (a.joinedTimestamp === null) return 1;
105 if (b.joinedTimestamp === null) return -1;
106 return a.joinedTimestamp - b.joinedTimestamp;
107 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100108 const joinPos = membersArray.findIndex((m) => m.id === member.user.id);
pineafan377794f2022-04-18 19:01:01 +0100109
Skyler Grey11236ba2022-08-08 21:13:33 +0100110 const roles = member.roles.cache.filter((r) => r.id !== interaction.guild!.id).sort();
pineafan377794f2022-04-18 19:01:01 +0100111 let s = "";
112 let count = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100113 let ended = false;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100114 for (const roleId in roles) {
115 const string = `<@&${roleId}>, `;
Skyler Grey75ea9172022-08-06 10:22:23 +0100116 if (s.length + string.length > 1000) {
pineafan63fc5e22022-08-04 22:04:10 +0100117 ended = true;
118 s += `and ${roles.size - count} more`;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100119 break;
pineafan63fc5e22022-08-04 22:04:10 +0100120 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100121 count++;
pineafan377794f2022-04-18 19:01:01 +0100122 s += string;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100123 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100124 if (s.length > 0 && !ended) s = s.slice(0, -2);
pineafan377794f2022-04-18 19:01:01 +0100125
pineafan63fc5e22022-08-04 22:04:10 +0100126 let perms = "";
127 const permsArray = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 ADMINISTRATOR: "Administrator",
129 MANAGE_GUILD: "Manage Server",
130 MANAGE_ROLES: "Manage Roles",
131 MANAGE_CHANNELS: "Manage Channels",
132 KICK_MEMBERS: "Kick Members",
133 BAN_MEMBERS: "Ban Members",
134 MODERATE_MEMBERS: "Moderate Members",
135 MANAGE_NICKNAMES: "Manage Nicknames",
136 MANAGE_WEBHOOKS: "Manage Webhooks",
137 MANAGE_MESSAGES: "Manage Messages",
138 VIEW_AUDIT_LOG: "View Audit Log",
139 MENTION_EVERYONE: "Mention Everyone"
pineafan63fc5e22022-08-04 22:04:10 +0100140 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 Object.keys(permsArray).map((perm) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100142 const hasPerm = member.permissions.has(perm as Discord.PermissionString);
143 perms += `${getEmojiByName("CONTROL." + (hasPerm ? "TICK" : "CROSS"))} ${permsArray[perm]}\n`;
pineafan63fc5e22022-08-04 22:04:10 +0100144 });
pineafan377794f2022-04-18 19:01:01 +0100145
pineafanea063042022-05-19 19:08:44 +0100146 let selectPaneOpen = false;
147
pineafan63fc5e22022-08-04 22:04:10 +0100148 const embeds = [
pineafanea063042022-05-19 19:08:44 +0100149 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 .setEmbed(
151 new EmojiEmbed()
152 .setTitle("User Info: General")
153 .setStatus("Success")
154 .setEmoji("MEMBER.JOIN")
155 .setDescription(
156 flags
157 .map((flag) => {
158 if (nameReplacements[flag]) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100159 return getEmojiByName(`BADGES.${flag}`) + " " + nameReplacements[flag];
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 }
161 })
162 .join("\n") +
163 "\n\n" +
164 generateKeyValueList({
165 member: renderUser(member.user),
pineafan3a02ea32022-08-11 21:35:04 +0100166 nickname: member.nickname ?? "*None set*",
Skyler Grey75ea9172022-08-06 10:22:23 +0100167 id: `\`${member.id}\``,
Skyler Grey11236ba2022-08-08 21:13:33 +0100168 "joined the server": renderDelta(member.joinedTimestamp),
169 "joined discord": renderDelta(member.user.createdTimestamp),
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 "boost status": member.premiumSince
Skyler Grey11236ba2022-08-08 21:13:33 +0100171 ? `Started boosting ${renderDelta(member.premiumSinceTimestamp)}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100172 : "*Not boosting*",
173 "join position": `${joinPos + 1}`
174 })
175 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100176 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
177 .setImage((await member.user.fetch()).bannerURL({ format: "gif" }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100178 )
179 .setTitle("General")
180 .setDescription("General information about the user")
181 .setPageId(0),
pineafanea063042022-05-19 19:08:44 +0100182 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100183 .setEmbed(
184 new EmojiEmbed()
185 .setTitle("User Info: Roles")
186 .setStatus("Success")
187 .setEmoji("GUILD.ROLES.CREATE")
188 .setDescription(
189 generateKeyValueList({
190 member: renderUser(member.user),
191 id: `\`${member.id}\``,
192 roles: `${member.roles.cache.size - 1}`
193 }) +
194 "\n" +
195 (s.length > 0 ? s : "*None*") +
196 "\n"
197 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100198 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100199 )
200 .setTitle("Roles")
201 .setDescription("Roles the user has")
202 .setPageId(1),
pineafanea063042022-05-19 19:08:44 +0100203 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100204 .setEmbed(
205 new EmojiEmbed()
206 .setTitle("User Info: Key Permissions")
207 .setStatus("Success")
208 .setEmoji("GUILD.ROLES.CREATE")
209 .setDescription(
210 generateKeyValueList({
211 member: renderUser(member.user),
212 id: `\`${member.id}\``
213 }) +
214 "\n" +
215 perms
216 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100217 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100218 )
219 .setTitle("Key Permissions")
220 .setDescription("Key permissions the user has")
221 .setPageId(2)
pineafan63fc5e22022-08-04 22:04:10 +0100222 ];
Skyler Grey75ea9172022-08-06 10:22:23 +0100223 const m = (await interaction.reply({
224 embeds: LoadingEmbed,
225 fetchReply: true,
226 ephemeral: true
227 })) as Message;
pineafan63fc5e22022-08-04 22:04:10 +0100228 let page = 0;
Skyler Greyad002172022-08-16 18:48:26 +0100229 let timedOut = false;
230 while (!timedOut) {
TheCodedProf21c08592022-09-13 14:14:43 -0400231 const em = new Discord.EmbedBuilder(embeds[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100232 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page));
pineafan63fc5e22022-08-04 22:04:10 +0100233 let selectPane = [];
pineafanea063042022-05-19 19:08:44 +0100234
235 if (selectPaneOpen) {
Skyler Greyad002172022-08-16 18:48:26 +0100236 const options: MessageSelectOptionData[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100237 embeds.forEach((embed) => {
Skyler Greyad002172022-08-16 18:48:26 +0100238 options.push({
239 label: embed.title,
240 value: embed.pageId.toString(),
241 description: embed.description || ""
242 });
pineafan63fc5e22022-08-04 22:04:10 +0100243 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 selectPane = [
TheCodedProf21c08592022-09-13 14:14:43 -0400245 new ActionRowBuilder().addComponents([
246 new Discord.SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 .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([
TheCodedProf21c08592022-09-13 14:14:43 -0400257 new ActionRowBuilder().addComponents([
258 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400260 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100261 .setCustomId("left")
262 .setDisabled(page === 0),
TheCodedProf21c08592022-09-13 14:14:43 -0400263 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100264 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400265 .setStyle(selectPaneOpen ? ButtonStyle.Primary : ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 .setCustomId("select")
267 .setDisabled(false),
TheCodedProf21c08592022-09-13 14:14:43 -0400268 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100269 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
270 .setCustomId("right")
TheCodedProf21c08592022-09-13 14:14:43 -0400271 .setStyle(ButtonStyle.Secondary)
Skyler Greyad002172022-08-16 18:48:26 +0100272 .setDisabled(page === embeds.length - 1)
Skyler Grey75ea9172022-08-06 10:22:23 +0100273 ])
274 ])
pineafan63fc5e22022-08-04 22:04:10 +0100275 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100276 let i: MessageComponentInteraction;
pineafan377794f2022-04-18 19:01:01 +0100277 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 i = await m.awaitMessageComponent({ time: 300000 });
279 } catch {
Skyler Greyad002172022-08-16 18:48:26 +0100280 timedOut = true;
281 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100282 }
pineafan63fc5e22022-08-04 22:04:10 +0100283 i.deferUpdate();
TheCodedProf21c08592022-09-13 14:14:43 -0400284 if ((i.component as Component).customId === "left") {
pineafan377794f2022-04-18 19:01:01 +0100285 if (page > 0) page--;
pineafanea063042022-05-19 19:08:44 +0100286 selectPaneOpen = false;
TheCodedProf21c08592022-09-13 14:14:43 -0400287 } else if ((i.component as Component).customId === "right") {
pineafan377794f2022-04-18 19:01:01 +0100288 if (page < embeds.length - 1) page++;
pineafanea063042022-05-19 19:08:44 +0100289 selectPaneOpen = false;
TheCodedProf21c08592022-09-13 14:14:43 -0400290 } else if ((i.component as Component).customId === "select") {
pineafanea063042022-05-19 19:08:44 +0100291 selectPaneOpen = !selectPaneOpen;
TheCodedProf21c08592022-09-13 14:14:43 -0400292 } else if ((i.component as Component).customId === "page") {
Skyler Grey1a67e182022-08-04 23:05:44 +0100293 page = parseInt((i as SelectMenuInteraction).values[0]);
pineafanea063042022-05-19 19:08:44 +0100294 selectPaneOpen = false;
pineafan377794f2022-04-18 19:01:01 +0100295 }
296 }
TheCodedProf21c08592022-09-13 14:14:43 -0400297 const em = new Discord.EmbedBuilder(embeds[page].embed);
Skyler Greyad002172022-08-16 18:48:26 +0100298 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | Message closed");
Skyler Grey75ea9172022-08-06 10:22:23 +0100299 await interaction.editReply({
300 embeds: [em],
Skyler Greyad002172022-08-16 18:48:26 +0100301 components: []
Skyler Grey75ea9172022-08-06 10:22:23 +0100302 });
pineafan63fc5e22022-08-04 22:04:10 +0100303};
pineafan4f164f32022-02-26 22:07:12 +0000304
Skyler Grey1a67e182022-08-04 23:05:44 +0100305const check = () => {
pineafan4f164f32022-02-26 22:07:12 +0000306 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100307};
pineafan4f164f32022-02-26 22:07:12 +0000308
309export { command };
310export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100311export { check };