blob: b3875a722f844242d69fe968545589b4a1b95e02 [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
10 .setName("viewas")
11 .setDescription("View the server as a specific member")
pineafan377794f2022-04-18 19:01:01 +010012 .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 => {
18 if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel)
19 })
20 channels = [channels]
21 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))
pineafanc6158ab2022-06-17 16:34:07 +010024 )
25 let autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"]
26 channels = channels.map(c => c.sort((a, b) => {
pineafan4edb7762022-06-26 19:21:04 +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
pineafanc6158ab2022-06-17 16:34:07 +010030 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) => {
34 if (!a[0].parent) return -1
35 if (!b[0].parent) return 1
36 return a[0].parent.position - b[0].parent.position
37 })
pineafanc6158ab2022-06-17 16:34:07 +010038 let 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")
pineafan4edb7762022-06-26 19:21:04 +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 => {
pineafan4edb7762022-06-26 19:21:04 +010053 let channelType = c.type
54 if (interaction.guild.rulesChannelId == c.id) channelType = "RULES"
55 else if ("nsfw" in c && c.nsfw) channelType += "_NSFW"
56 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") + " " +
61 getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")} ${t.name}`).join("\n") + "\n"
62 }return ""
63 })()) : ""
64 }).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 ])
pineafanc6158ab2022-06-17 16:34:07 +010086 ]})
pineafan4edb7762022-06-26 19:21:04 +010087 let i;
88 try {
89 i = await m.awaitMessageComponent({ time: 300000 });
90 } catch (e) { return }
91 i.deferUpdate()
92 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 }
pineafan4f164f32022-02-26 22:07:12 +000096}
97
pineafan4edb7762022-06-26 19:21:04 +010098
pineafan4f164f32022-02-26 22:07:12 +000099const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
pineafan4edb7762022-06-26 19:21:04 +0100100 return true // FIXME FOR RELEASE
101 let member = (interaction.member as GuildMember)
102 if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
103 return true
pineafan4f164f32022-02-26 22:07:12 +0000104}
105
pineafan8b4b17f2022-02-27 20:42:52 +0000106export { command, callback, check };