blob: 47016309198ce597c29abc440dabb7aae84255ac [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,
Skyler Greyad002172022-08-16 18:48:26 +010010 MessageSelectOptionData,
Skyler Grey75ea9172022-08-06 10:22:23 +010011 SelectMenuInteraction
12} from "discord.js";
Skyler Greyad002172022-08-16 18:48:26 +010013import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010014import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan377794f2022-04-18 19:01:01 +010015import getEmojiByName from "../../utils/getEmojiByName.js";
16import generateKeyValueList from "../../utils/generateKeyValueList.js";
pineafan34369e62022-05-18 16:52:37 +010017import createPageIndicator from "../../utils/createPageIndicator.js";
pineafan63fc5e22022-08-04 22:04:10 +010018import client from "../../utils/client.js";
pineafan4f164f32022-02-26 22:07:12 +000019
20const command = (builder: SlashCommandSubcommandBuilder) =>
21 builder
pineafan63fc5e22022-08-04 22:04:10 +010022 .setName("about")
23 .setDescription("Shows info about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010024 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010025 option.setName("user").setDescription("The user to get info about | Default: Yourself")
Skyler Grey75ea9172022-08-06 10:22:23 +010026 );
pineafanea063042022-05-19 19:08:44 +010027
28class Embed {
29 embed: Discord.MessageEmbed;
30 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010031 description = "";
32 pageId = 0;
Skyler Grey75ea9172022-08-06 10:22:23 +010033 setEmbed(embed: Discord.MessageEmbed) {
34 this.embed = embed;
35 return this;
36 }
37 setTitle(title: string) {
38 this.title = title;
39 return this;
40 }
41 setDescription(description: string) {
42 this.description = description;
43 return this;
44 }
45 setPageId(pageId: number) {
46 this.pageId = pageId;
47 return this;
48 }
pineafanea063042022-05-19 19:08:44 +010049}
50
Skyler Grey1a67e182022-08-04 23:05:44 +010051const callback = async (interaction: CommandInteraction): Promise<void> => {
Skyler Greyc634e2b2022-08-06 17:50:48 +010052 if (!interaction.guild) return;
pineafan63fc5e22022-08-04 22:04:10 +010053 const { renderUser, renderDelta } = client.logger;
Skyler Grey11236ba2022-08-08 21:13:33 +010054 const member = (interaction.options.getMember("user") ?? interaction.member) as Discord.GuildMember;
pineafan63fc5e22022-08-04 22:04:10 +010055 const flags: string[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +010056 if (
57 [
58 "438733159748599813", // Pinea
59 "317731855317336067", // Mini
60 "261900651230003201", // Coded
61 "511655498676699136" // Zan
62 ].includes(member.user.id)
63 ) {
64 flags.push("NUCLEUSDEVELOPER");
65 }
66 if (
67 (await client.guilds.cache.get("684492926528651336")?.members.fetch())
Skyler Grey11236ba2022-08-08 21:13:33 +010068 ?.filter((m: GuildMember) => m.roles.cache.has("760896837866749972"))
Skyler Grey75ea9172022-08-06 10:22:23 +010069 ?.map((m: GuildMember) => m.id)
70 .includes(member.user.id)
71 ) {
72 flags.push("CLICKSDEVELOPER");
73 }
74 member.user.flags.toArray().map((flag) => {
pineafan63fc5e22022-08-04 22:04:10 +010075 flags.push(flag.toString());
76 });
Skyler Grey75ea9172022-08-06 10:22:23 +010077 if (member.user.bot) {
78 flags.push("BOT");
79 }
pineafan377794f2022-04-18 19:01:01 +010080 // Check if they are boosting the server
Skyler Grey75ea9172022-08-06 10:22:23 +010081 if (member.premiumSince) {
82 flags.push("BOOSTER");
83 }
pineafan63fc5e22022-08-04 22:04:10 +010084 const nameReplacements = {
Skyler Grey75ea9172022-08-06 10:22:23 +010085 NUCLEUSDEVELOPER: "**Nucleus Developer**",
86 CLICKSDEVELOPER: "Clicks Developer",
87 HOUSE_BRAVERY: "Hypesquad Bravery",
88 HOUSE_BRILLIANCE: "Hypesquad Brilliance",
89 HOUSE_BALANCE: "Hypesquad Balance",
90 HYPESQUAD_EVENTS: "Hypesquad Events",
91 EARLY_SUPPORTER: "Early Supporter",
92 BUGHUNTER_LEVEL_1: "Bug Hunter Level 1",
93 BUGHUNTER_LEVEL_2: "Bug Hunter Level 2",
94 PARTNERED_SERVER_OWNER: "Partnered Server Owner",
95 DISCORD_EMPLOYEE: "Discord Staff",
96 EARLY_VERIFIED_BOT_DEVELOPER: "Verified Bot Developer",
97 BOT: "Bot",
98 BOOSTER: "Server Booster"
pineafan63fc5e22022-08-04 22:04:10 +010099 };
100 const members = await interaction.guild.members.fetch();
101 const membersArray = [...members.values()];
Skyler Greyc634e2b2022-08-06 17:50:48 +0100102 membersArray.sort((a, b) => {
103 if (a.joinedTimestamp === null) return 1;
104 if (b.joinedTimestamp === null) return -1;
105 return a.joinedTimestamp - b.joinedTimestamp;
106 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 const joinPos = membersArray.findIndex((m) => m.id === member.user.id);
pineafan377794f2022-04-18 19:01:01 +0100108
Skyler Grey11236ba2022-08-08 21:13:33 +0100109 const roles = member.roles.cache.filter((r) => r.id !== interaction.guild!.id).sort();
pineafan377794f2022-04-18 19:01:01 +0100110 let s = "";
111 let count = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100112 let ended = false;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100113 for (const roleId in roles) {
114 const string = `<@&${roleId}>, `;
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 if (s.length + string.length > 1000) {
pineafan63fc5e22022-08-04 22:04:10 +0100116 ended = true;
117 s += `and ${roles.size - count} more`;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100118 break;
pineafan63fc5e22022-08-04 22:04:10 +0100119 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100120 count++;
pineafan377794f2022-04-18 19:01:01 +0100121 s += string;
Skyler Greyc634e2b2022-08-06 17:50:48 +0100122 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100123 if (s.length > 0 && !ended) s = s.slice(0, -2);
pineafan377794f2022-04-18 19:01:01 +0100124
pineafan63fc5e22022-08-04 22:04:10 +0100125 let perms = "";
126 const permsArray = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100127 ADMINISTRATOR: "Administrator",
128 MANAGE_GUILD: "Manage Server",
129 MANAGE_ROLES: "Manage Roles",
130 MANAGE_CHANNELS: "Manage Channels",
131 KICK_MEMBERS: "Kick Members",
132 BAN_MEMBERS: "Ban Members",
133 MODERATE_MEMBERS: "Moderate Members",
134 MANAGE_NICKNAMES: "Manage Nicknames",
135 MANAGE_WEBHOOKS: "Manage Webhooks",
136 MANAGE_MESSAGES: "Manage Messages",
137 VIEW_AUDIT_LOG: "View Audit Log",
138 MENTION_EVERYONE: "Mention Everyone"
pineafan63fc5e22022-08-04 22:04:10 +0100139 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100140 Object.keys(permsArray).map((perm) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100141 const hasPerm = member.permissions.has(perm as Discord.PermissionString);
142 perms += `${getEmojiByName("CONTROL." + (hasPerm ? "TICK" : "CROSS"))} ${permsArray[perm]}\n`;
pineafan63fc5e22022-08-04 22:04:10 +0100143 });
pineafan377794f2022-04-18 19:01:01 +0100144
pineafanea063042022-05-19 19:08:44 +0100145 let selectPaneOpen = false;
146
pineafan63fc5e22022-08-04 22:04:10 +0100147 const embeds = [
pineafanea063042022-05-19 19:08:44 +0100148 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100149 .setEmbed(
150 new EmojiEmbed()
151 .setTitle("User Info: General")
152 .setStatus("Success")
153 .setEmoji("MEMBER.JOIN")
154 .setDescription(
155 flags
156 .map((flag) => {
157 if (nameReplacements[flag]) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100158 return getEmojiByName(`BADGES.${flag}`) + " " + nameReplacements[flag];
Skyler Grey75ea9172022-08-06 10:22:23 +0100159 }
160 })
161 .join("\n") +
162 "\n\n" +
163 generateKeyValueList({
164 member: renderUser(member.user),
pineafan3a02ea32022-08-11 21:35:04 +0100165 nickname: member.nickname ?? "*None set*",
Skyler Grey75ea9172022-08-06 10:22:23 +0100166 id: `\`${member.id}\``,
Skyler Grey11236ba2022-08-08 21:13:33 +0100167 "joined the server": renderDelta(member.joinedTimestamp),
168 "joined discord": renderDelta(member.user.createdTimestamp),
Skyler Grey75ea9172022-08-06 10:22:23 +0100169 "boost status": member.premiumSince
Skyler Grey11236ba2022-08-08 21:13:33 +0100170 ? `Started boosting ${renderDelta(member.premiumSinceTimestamp)}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100171 : "*Not boosting*",
172 "join position": `${joinPos + 1}`
173 })
174 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100175 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
176 .setImage((await member.user.fetch()).bannerURL({ format: "gif" }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100177 )
178 .setTitle("General")
179 .setDescription("General information about the user")
180 .setPageId(0),
pineafanea063042022-05-19 19:08:44 +0100181 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100182 .setEmbed(
183 new EmojiEmbed()
184 .setTitle("User Info: Roles")
185 .setStatus("Success")
186 .setEmoji("GUILD.ROLES.CREATE")
187 .setDescription(
188 generateKeyValueList({
189 member: renderUser(member.user),
190 id: `\`${member.id}\``,
191 roles: `${member.roles.cache.size - 1}`
192 }) +
193 "\n" +
194 (s.length > 0 ? s : "*None*") +
195 "\n"
196 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100197 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100198 )
199 .setTitle("Roles")
200 .setDescription("Roles the user has")
201 .setPageId(1),
pineafanea063042022-05-19 19:08:44 +0100202 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100203 .setEmbed(
204 new EmojiEmbed()
205 .setTitle("User Info: Key Permissions")
206 .setStatus("Success")
207 .setEmoji("GUILD.ROLES.CREATE")
208 .setDescription(
209 generateKeyValueList({
210 member: renderUser(member.user),
211 id: `\`${member.id}\``
212 }) +
213 "\n" +
214 perms
215 )
Skyler Grey11236ba2022-08-08 21:13:33 +0100216 .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
Skyler Grey75ea9172022-08-06 10:22:23 +0100217 )
218 .setTitle("Key Permissions")
219 .setDescription("Key permissions the user has")
220 .setPageId(2)
pineafan63fc5e22022-08-04 22:04:10 +0100221 ];
Skyler Grey75ea9172022-08-06 10:22:23 +0100222 const m = (await interaction.reply({
223 embeds: LoadingEmbed,
224 fetchReply: true,
225 ephemeral: true
226 })) as Message;
pineafan63fc5e22022-08-04 22:04:10 +0100227 let page = 0;
Skyler Greyad002172022-08-16 18:48:26 +0100228 let timedOut = false;
229 while (!timedOut) {
pineafan63fc5e22022-08-04 22:04:10 +0100230 const em = new Discord.MessageEmbed(embeds[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100231 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page));
pineafan63fc5e22022-08-04 22:04:10 +0100232 let selectPane = [];
pineafanea063042022-05-19 19:08:44 +0100233
234 if (selectPaneOpen) {
Skyler Greyad002172022-08-16 18:48:26 +0100235 const options: MessageSelectOptionData[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 embeds.forEach((embed) => {
Skyler Greyad002172022-08-16 18:48:26 +0100237 options.push({
238 label: embed.title,
239 value: embed.pageId.toString(),
240 description: embed.description || ""
241 });
pineafan63fc5e22022-08-04 22:04:10 +0100242 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100243 selectPane = [
244 new MessageActionRow().addComponents([
245 new Discord.MessageSelectMenu()
246 .addOptions(options)
247 .setCustomId("page")
248 .setMaxValues(1)
249 .setPlaceholder("Choose a page...")
250 ])
251 ];
pineafanea063042022-05-19 19:08:44 +0100252 }
pineafan377794f2022-04-18 19:01:01 +0100253 await interaction.editReply({
pineafan34369e62022-05-18 16:52:37 +0100254 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 components: selectPane.concat([
256 new MessageActionRow().addComponents([
257 new MessageButton()
258 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
259 .setStyle("SECONDARY")
260 .setCustomId("left")
261 .setDisabled(page === 0),
262 new MessageButton()
263 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
264 .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
265 .setCustomId("select")
266 .setDisabled(false),
267 new MessageButton()
268 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
269 .setCustomId("right")
270 .setStyle("SECONDARY")
Skyler Greyad002172022-08-16 18:48:26 +0100271 .setDisabled(page === embeds.length - 1)
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 ])
273 ])
pineafan63fc5e22022-08-04 22:04:10 +0100274 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100275 let i: MessageComponentInteraction;
pineafan377794f2022-04-18 19:01:01 +0100276 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100277 i = await m.awaitMessageComponent({ time: 300000 });
278 } catch {
Skyler Greyad002172022-08-16 18:48:26 +0100279 timedOut = true;
280 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 }
pineafan63fc5e22022-08-04 22:04:10 +0100282 i.deferUpdate();
Skyler Grey1a67e182022-08-04 23:05:44 +0100283 if ((i.component as MessageActionRowComponent).customId === "left") {
pineafan377794f2022-04-18 19:01:01 +0100284 if (page > 0) page--;
pineafanea063042022-05-19 19:08:44 +0100285 selectPaneOpen = false;
Skyler Grey11236ba2022-08-08 21:13:33 +0100286 } else if ((i.component as MessageActionRowComponent).customId === "right") {
pineafan377794f2022-04-18 19:01:01 +0100287 if (page < embeds.length - 1) page++;
pineafanea063042022-05-19 19:08:44 +0100288 selectPaneOpen = false;
Skyler Grey11236ba2022-08-08 21:13:33 +0100289 } else if ((i.component as MessageActionRowComponent).customId === "select") {
pineafanea063042022-05-19 19:08:44 +0100290 selectPaneOpen = !selectPaneOpen;
Skyler Grey11236ba2022-08-08 21:13:33 +0100291 } else if ((i.component as MessageActionRowComponent).customId === "page") {
Skyler Grey1a67e182022-08-04 23:05:44 +0100292 page = parseInt((i as SelectMenuInteraction).values[0]);
pineafanea063042022-05-19 19:08:44 +0100293 selectPaneOpen = false;
pineafan377794f2022-04-18 19:01:01 +0100294 }
295 }
pineafan63fc5e22022-08-04 22:04:10 +0100296 const em = new Discord.MessageEmbed(embeds[page].embed);
Skyler Greyad002172022-08-16 18:48:26 +0100297 em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | Message closed");
Skyler Grey75ea9172022-08-06 10:22:23 +0100298 await interaction.editReply({
299 embeds: [em],
Skyler Greyad002172022-08-16 18:48:26 +0100300 components: []
Skyler Grey75ea9172022-08-06 10:22:23 +0100301 });
pineafan63fc5e22022-08-04 22:04:10 +0100302};
pineafan4f164f32022-02-26 22:07:12 +0000303
Skyler Grey1a67e182022-08-04 23:05:44 +0100304const check = () => {
pineafan4f164f32022-02-26 22:07:12 +0000305 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100306};
pineafan4f164f32022-02-26 22:07:12 +0000307
308export { command };
309export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100310export { check };