blob: a5bf5eab525c1434c7b3c8d5f2cda86d92690252 [file] [log] [blame]
pineafan4edb7762022-06-26 19:21:04 +01001import Discord, { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
pineafan4f164f32022-02-26 22:07:12 +00002import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan4f164f32022-02-26 22:07:12 +00004import { WrappedCheck } from "jshaiku";
pineafanc6158ab2022-06-17 16:34:07 +01005import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan4edb7762022-06-26 19:21:04 +01006import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4f164f32022-02-26 22:07:12 +00007
8const command = (builder: SlashCommandSubcommandBuilder) =>
9 builder
pineafan63fc5e22022-08-04 22:04:10 +010010 .setName("viewas")
11 .setDescription("View the server as a specific member")
12 .addUserOption(option => option.setName("member").setDescription("The member to view as").setRequired(true));
pineafan4f164f32022-02-26 22:07:12 +000013
pineafan4edb7762022-06-26 19:21:04 +010014const callback = async (interaction: CommandInteraction): Promise<any> => {
15 let channels = [];
16 let m;
pineafanc6158ab2022-06-17 16:34:07 +010017 interaction.guild.channels.cache.forEach(channel => {
pineafan63fc5e22022-08-04 22:04:10 +010018 if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel);
19 });
20 channels = [channels];
pineafanc6158ab2022-06-17 16:34:07 +010021 channels = channels.concat(interaction.guild.channels.cache
pineafan377794f2022-04-18 19:01:01 +010022 .filter(c => c.type === "GUILD_CATEGORY")
23 .map(c => (c as CategoryChannel).children.map(c => c))
pineafan63fc5e22022-08-04 22:04:10 +010024 );
25 const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
pineafanc6158ab2022-06-17 16:34:07 +010026 channels = channels.map(c => c.sort((a, b) => {
pineafan63fc5e22022-08-04 22:04:10 +010027 if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
28 if (autoSortBelow.includes(a.type)) return 1;
29 if (autoSortBelow.includes(b.type)) return -1;
30 return a.position - b.position;
31 }));
pineafan4edb7762022-06-26 19:21:04 +010032 // Sort all arrays by the position of the first channels parent position
33 channels = channels.sort((a, b) => {
pineafan63fc5e22022-08-04 22:04:10 +010034 if (!a[0].parent) return -1;
35 if (!b[0].parent) return 1;
36 return a[0].parent.position - b[0].parent.position;
37 });
38 const member = interaction.options.getMember("member") as Discord.GuildMember;
pineafan4edb7762022-06-26 19:21:04 +010039 m = await interaction.reply({embeds: [new EmojiEmbed()
pineafanc6158ab2022-06-17 16:34:07 +010040 .setEmoji("MEMBER.JOIN")
41 .setTitle("Viewing as " + member.displayName)
42 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +010043 ], ephemeral: true, fetchReply: true});
pineafanc6158ab2022-06-17 16:34:07 +010044 let page = 0;
45 while (true) {
pineafan4edb7762022-06-26 19:21:04 +010046 m = await interaction.editReply({embeds: [new EmojiEmbed()
pineafanc6158ab2022-06-17 16:34:07 +010047 .setEmoji("MEMBER.JOIN")
48 .setTitle("Viewing as " + member.displayName)
49 .setStatus("Success")
50 .setDescription(
pineafan4edb7762022-06-26 19:21:04 +010051 `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` + "\n" +
pineafanc6158ab2022-06-17 16:34:07 +010052 channels[page].map(c => {
pineafan63fc5e22022-08-04 22:04:10 +010053 let channelType = c.type;
54 if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
55 else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
pineafan4edb7762022-06-26 19:21:04 +010056 return c.permissionsFor(member).has("VIEW_CHANNEL") ? (
57 `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` + (() => {
58 if ("threads" in c && c.threads.cache.size > 0) {
59 return c.threads.cache.map(t => ` ${
60 getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") + " " +
pineafan63fc5e22022-08-04 22:04:10 +010061 getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")} ${t.name}`).join("\n") + "\n";
62 }return "";
63 })()) : "";
pineafan4edb7762022-06-26 19:21:04 +010064 }).join("") + "\n" + pageIndicator(channels.length, page)
pineafanc6158ab2022-06-17 16:34:07 +010065 )
pineafan4edb7762022-06-26 19:21:04 +010066 ], components: [
67 new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(channels.map((c, index) => ({
68 label: c[0].parent ? c[0].parent.name : "Uncategorised",
69 value: index.toString(),
70 default: page === index
71 }))).setCustomId("select").setMaxValues(1).setMinValues(1).setPlaceholder("Select a category")]),
72 new MessageActionRow().addComponents([
73 new MessageButton()
74 .setLabel(page === 0 ? "" : (channels[page - 1][0].parent ? channels[page - 1][0].parent.name : "Uncategorised"))
75 .setDisabled(page === 0)
76 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
77 .setStyle("PRIMARY")
78 .setCustomId("previous"),
79 new MessageButton()
80 .setLabel(page === channels.length - 1 ? "" : (channels[page + 1][0].parent ? channels[page + 1][0].parent.name : "Uncategorised"))
81 .setDisabled(page === channels.length - 1)
82 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
83 .setStyle("PRIMARY")
84 .setCustomId("next")
85 ])
pineafan63fc5e22022-08-04 22:04:10 +010086 ]});
pineafan4edb7762022-06-26 19:21:04 +010087 let i;
88 try {
89 i = await m.awaitMessageComponent({ time: 300000 });
pineafan63fc5e22022-08-04 22:04:10 +010090 } catch (e) { return; }
91 i.deferUpdate();
pineafan4edb7762022-06-26 19:21:04 +010092 if (i.customId === "next") { page++; }
93 else if (i.customId === "previous") { page--; }
94 else if (i.customId === "select") { page = parseInt(i.values[0]); }
pineafanc6158ab2022-06-17 16:34:07 +010095 }
pineafan63fc5e22022-08-04 22:04:10 +010096};
pineafan4f164f32022-02-26 22:07:12 +000097
pineafan4edb7762022-06-26 19:21:04 +010098
pineafan4f164f32022-02-26 22:07:12 +000099const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
pineafan63fc5e22022-08-04 22:04:10 +0100100 const member = (interaction.member as GuildMember);
pineafane23c4ec2022-07-27 21:56:27 +0100101 if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the *Manage Roles* permission";
pineafan63fc5e22022-08-04 22:04:10 +0100102 return true;
103};
pineafan4f164f32022-02-26 22:07:12 +0000104
pineafan8b4b17f2022-02-27 20:42:52 +0000105export { command, callback, check };