blob: a713f55f39b66a02b29e474ca82f74bb20d966b8 [file] [log] [blame]
Skyler Grey75ea9172022-08-06 10:22:23 +01001import Discord, {
2 CategoryChannel,
3 CommandInteraction,
4 GuildMember,
TheCodedProf21c08592022-09-13 14:14:43 -04005 ActionRowBuilder,
6 ButtonBuilder,
7 SelectMenuBuilder,
8 ButtonStyle
Skyler Grey75ea9172022-08-06 10:22:23 +01009} from "discord.js";
PineaFan64486c42022-12-28 09:21:04 +000010import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010011import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafanc6158ab2022-06-17 16:34:07 +010012import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan4edb7762022-06-26 19:21:04 +010013import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4f164f32022-02-26 22:07:12 +000014
15const command = (builder: SlashCommandSubcommandBuilder) =>
16 builder
pineafan63fc5e22022-08-04 22:04:10 +010017 .setName("viewas")
18 .setDescription("View the server as a specific member")
Skyler Grey11236ba2022-08-08 21:13:33 +010019 .addUserOption((option) => option.setName("member").setDescription("The member to view as").setRequired(true));
pineafan4f164f32022-02-26 22:07:12 +000020
pineafanbd02b4a2022-08-05 22:01:38 +010021const callback = async (interaction: CommandInteraction): Promise<void> => {
pineafan4edb7762022-06-26 19:21:04 +010022 let channels = [];
23 let m;
Skyler Grey75ea9172022-08-06 10:22:23 +010024 interaction.guild.channels.cache.forEach((channel) => {
Skyler Grey11236ba2022-08-08 21:13:33 +010025 if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel);
pineafan63fc5e22022-08-04 22:04:10 +010026 });
27 channels = [channels];
Skyler Grey75ea9172022-08-06 10:22:23 +010028 channels = channels.concat(
29 interaction.guild.channels.cache
30 .filter((c) => c.type === "GUILD_CATEGORY")
31 .map((c) => (c as CategoryChannel).children.map((c) => c))
pineafan63fc5e22022-08-04 22:04:10 +010032 );
33 const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
Skyler Grey75ea9172022-08-06 10:22:23 +010034 channels = channels.map((c) =>
35 c.sort((a, b) => {
Skyler Grey11236ba2022-08-08 21:13:33 +010036 if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
Skyler Grey75ea9172022-08-06 10:22:23 +010037 if (autoSortBelow.includes(a.type)) return 1;
38 if (autoSortBelow.includes(b.type)) return -1;
39 return a.position - b.position;
40 })
41 );
pineafan4edb7762022-06-26 19:21:04 +010042 // Sort all arrays by the position of the first channels parent position
43 channels = channels.sort((a, b) => {
pineafan63fc5e22022-08-04 22:04:10 +010044 if (!a[0].parent) return -1;
45 if (!b[0].parent) return 1;
46 return a[0].parent.position - b[0].parent.position;
47 });
Skyler Grey11236ba2022-08-08 21:13:33 +010048 const member = interaction.options.getMember("member") as Discord.GuildMember;
Skyler Grey75ea9172022-08-06 10:22:23 +010049 m = await interaction.reply({
50 embeds: [
51 new EmojiEmbed()
52 .setEmoji("MEMBER.JOIN")
53 .setTitle("Viewing as " + member.displayName)
54 .setStatus("Success")
55 ],
56 ephemeral: true,
57 fetchReply: true
58 });
pineafanc6158ab2022-06-17 16:34:07 +010059 let page = 0;
Skyler Greyad002172022-08-16 18:48:26 +010060 let timedOut = false;
61 while (!timedOut) {
Skyler Grey75ea9172022-08-06 10:22:23 +010062 m = await interaction.editReply({
63 embeds: [
64 new EmojiEmbed()
65 .setEmoji("MEMBER.JOIN")
66 .setTitle("Viewing as " + member.displayName)
67 .setStatus("Success")
68 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +010069 `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` +
Skyler Grey75ea9172022-08-06 10:22:23 +010070 "\n" +
71 channels[page]
72 .map((c) => {
73 let channelType = c.type;
Skyler Grey11236ba2022-08-08 21:13:33 +010074 if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
75 else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
76 return c.permissionsFor(member).has("VIEW_CHANNEL")
77 ? `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` +
Skyler Grey75ea9172022-08-06 10:22:23 +010078 (() => {
Skyler Grey11236ba2022-08-08 21:13:33 +010079 if ("threads" in c && c.threads.cache.size > 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +010080 return (
81 c.threads.cache
82 .map(
83 (t) =>
84 ` ${
Skyler Grey11236ba2022-08-08 21:13:33 +010085 getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") +
Skyler Grey75ea9172022-08-06 10:22:23 +010086 " " +
Skyler Grey11236ba2022-08-08 21:13:33 +010087 getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")
88 } ${t.name}`
Skyler Grey75ea9172022-08-06 10:22:23 +010089 )
90 .join("\n") + "\n"
91 );
92 }
93 return "";
94 })()
95 : "";
96 })
97 .join("") +
98 "\n" +
99 pageIndicator(channels.length, page)
100 )
101 ],
102 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400103 new ActionRowBuilder().addComponents([
104 new SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100105 .setOptions(
106 channels.map((c, index) => ({
Skyler Grey11236ba2022-08-08 21:13:33 +0100107 label: c[0].parent ? c[0].parent.name : "Uncategorised",
Skyler Grey75ea9172022-08-06 10:22:23 +0100108 value: index.toString(),
109 default: page === index
110 }))
111 )
112 .setCustomId("select")
113 .setMaxValues(1)
114 .setMinValues(1)
115 .setPlaceholder("Select a category")
116 ]),
TheCodedProf21c08592022-09-13 14:14:43 -0400117 new ActionRowBuilder().addComponents([
118 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 .setLabel(
120 page === 0
121 ? ""
122 : channels[page - 1][0].parent
123 ? channels[page - 1][0].parent.name
124 : "Uncategorised"
125 )
126 .setDisabled(page === 0)
127 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400128 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100129 .setCustomId("previous"),
TheCodedProf21c08592022-09-13 14:14:43 -0400130 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 .setLabel(
132 page === channels.length - 1
133 ? ""
134 : channels[page + 1][0].parent
135 ? channels[page + 1][0].parent.name
136 : "Uncategorised"
137 )
138 .setDisabled(page === channels.length - 1)
139 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400140 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 .setCustomId("next")
142 ])
143 ]
144 });
pineafan4edb7762022-06-26 19:21:04 +0100145 let i;
146 try {
147 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100148 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100149 timedOut = true;
150 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 }
pineafan63fc5e22022-08-04 22:04:10 +0100152 i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100153 if (i.customId === "next") {
154 page++;
155 } else if (i.customId === "previous") {
156 page--;
157 } else if (i.customId === "select") {
158 page = parseInt(i.values[0]);
159 }
pineafanc6158ab2022-06-17 16:34:07 +0100160 }
pineafan63fc5e22022-08-04 22:04:10 +0100161};
pineafan4f164f32022-02-26 22:07:12 +0000162
pineafanbd02b4a2022-08-05 22:01:38 +0100163const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100164 const member = interaction.member as GuildMember;
pineafan3a02ea32022-08-11 21:35:04 +0100165 if (!member.permissions.has("MANAGE_ROLES")) throw new Error("You do not have the *Manage Roles* permission");
pineafan63fc5e22022-08-04 22:04:10 +0100166 return true;
167};
pineafan4f164f32022-02-26 22:07:12 +0000168
Skyler Grey75ea9172022-08-06 10:22:23 +0100169export { command, callback, check };