blob: 8b2864a33e205d2565bee9d3df29e78746ef6c47 [file] [log] [blame]
Skyler Grey75ea9172022-08-06 10:22:23 +01001import Discord, {
Skyler Grey75ea9172022-08-06 10:22:23 +01002 CommandInteraction,
3 GuildMember,
TheCodedProf21c08592022-09-13 14:14:43 -04004 ActionRowBuilder,
5 ButtonBuilder,
PineaFan1dee28f2023-01-16 22:09:07 +00006 ButtonStyle,
7 NonThreadGuildBasedChannel
Skyler Grey75ea9172022-08-06 10:22:23 +01008} from "discord.js";
PineaFan64486c42022-12-28 09:21:04 +00009import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
PineaFan1dee28f2023-01-16 22:09:07 +000010import type { GuildBasedChannel } from "discord.js";
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> => {
PineaFan1dee28f2023-01-16 22:09:07 +000022 /*
23 * {
24 categoryObject: channel[],
25 categoryObject: channel[],
26 "null": channel[]
27 }
28 */
29
30 const channels: Record<string, GuildBasedChannel[]> = {"": [] as GuildBasedChannel[]};
31
32 interaction.guild!.channels.fetch().then(channelCollection => {
33 channelCollection.forEach(channel => {
34 if (!channel) return; // if no channel
35 if (channel.type === Discord.ChannelType.GuildCategory) {
36 if(!channels[channel!.id]) channels[channel!.id] = [channel];
37 } else if (channel.parent) {
38 if (!channels[channel.parent.id]) channels[channel.parent.id] = [channel];
39 else (channels[channel.parent.id as string])!.push(channel);
40 } else {
41 channels[""]!.push(channel);
42 }
43 });
pineafan63fc5e22022-08-04 22:04:10 +010044 });
PineaFan1dee28f2023-01-16 22:09:07 +000045
46 const member = interaction.options.getMember("member") as Discord.GuildMember;
47 const autoSortBelow = [Discord.ChannelType.GuildVoice, Discord.ChannelType.GuildStageVoice];
48 // for each category, sort its channels. This should be based on the order of the channels, with voice and stage channels sorted below text
49 channels = Object.values(channels).map((c) => {
50 return c.sort((a: GuildBasedChannel, b: GuildBasedChannel) => {
51 if (a.type === Discord.ChannelType.PrivateThread || b.type === Discord.ChannelType.PrivateThread)
52 if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position ?? 0 - b.position ;
Skyler Grey75ea9172022-08-06 10:22:23 +010053 if (autoSortBelow.includes(a.type)) return 1;
54 if (autoSortBelow.includes(b.type)) return -1;
PineaFan1dee28f2023-01-16 22:09:07 +000055 return a - b;
Skyler Grey75ea9172022-08-06 10:22:23 +010056 });
pineafanc6158ab2022-06-17 16:34:07 +010057 }
PineaFan1dee28f2023-01-16 22:09:07 +000058
59
60 //OLD CODE START
61 // const unprocessedChannels: GuildBasedChannel[] = [];
62 // let m;
63 // interaction.guild!.channels.cache.forEach((channel) => {
64 // if (!channel.parent && channel.type !== Discord.ChannelType.GuildCategory) unprocessedChannels.push(channel);
65 // });
66 // let channels: GuildBasedChannel[][] = [unprocessedChannels];
67 // channels = channels.concat(
68 // interaction.guild!.channels.cache
69 // .filter((c) => c.type === Discord.ChannelType.GuildCategory)
70 // .map((c) => (c as CategoryChannel).children.map((c) => c))
71 // );
72 // const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
73 // channels = channels.map((c) =>
74 // c.sort((a, b) => {
75 // if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
76 // if (autoSortBelow.includes(a.type)) return 1;
77 // if (autoSortBelow.includes(b.type)) return -1;
78 // return a.position - b.position;
79 // })
80 // );
81 // // Sort all arrays by the position of the first channels parent position
82 // channels = channels.sort((a, b) => {
83 // if (!a[0].parent) return -1;
84 // if (!b[0].parent) return 1;
85 // return a[0].parent.position - b[0].parent.position;
86 // });
87 // const member = interaction.options.getMember("member") as Discord.GuildMember;
88 // m = await interaction.reply({
89 // embeds: [
90 // new EmojiEmbed()
91 // .setEmoji("MEMBER.JOIN")
92 // .setTitle("Viewing as " + member.displayName)
93 // .setStatus("Success")
94 // ],
95 // ephemeral: true,
96 // fetchReply: true
97 // });
98 // let page = 0;
99 // let timedOut = false;
100 // while (!timedOut) {
101 // m = await interaction.editReply({
102 // embeds: [
103 // new EmojiEmbed()
104 // .setEmoji("MEMBER.JOIN")
105 // .setTitle("Viewing as " + member.displayName)
106 // .setStatus("Success")
107 // .setDescription(
108 // `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` +
109 // "\n" +
110 // channels[page]
111 // .map((c) => {
112 // let channelType = c.type;
113 // if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
114 // else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
115 // return c.permissionsFor(member).has("VIEW_CHANNEL")
116 // ? `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` +
117 // (() => {
118 // if ("threads" in c && c.threads.cache.size > 0) {
119 // return (
120 // c.threads.cache
121 // .map(
122 // (t) =>
123 // ` ${
124 // getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") +
125 // " " +
126 // getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")
127 // } ${t.name}`
128 // )
129 // .join("\n") + "\n"
130 // );
131 // }
132 // return "";
133 // })()
134 // : "";
135 // })
136 // .join("") +
137 // "\n" +
138 // pageIndicator(channels.length, page)
139 // )
140 // ],
141 // components: [
142 // new ActionRowBuilder().addComponents([
143 // new SelectMenuBuilder()
144 // .setOptions(
145 // channels.map((c, index) => ({
146 // label: c[0].parent ? c[0].parent.name : "Uncategorised",
147 // value: index.toString(),
148 // default: page === index
149 // }))
150 // )
151 // .setCustomId("select")
152 // .setMaxValues(1)
153 // .setMinValues(1)
154 // .setPlaceholder("Select a category")
155 // ]),
156 // new ActionRowBuilder().addComponents([
157 // new ButtonBuilder()
158 // .setLabel(
159 // page === 0
160 // ? ""
161 // : channels[page - 1][0].parent
162 // ? channels[page - 1][0].parent.name
163 // : "Uncategorised"
164 // )
165 // .setDisabled(page === 0)
166 // .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
167 // .setStyle(ButtonStyle.Primary)
168 // .setCustomId("previous"),
169 // new ButtonBuilder()
170 // .setLabel(
171 // page === channels.length - 1
172 // ? ""
173 // : channels[page + 1][0].parent
174 // ? channels[page + 1][0].parent.name
175 // : "Uncategorised"
176 // )
177 // .setDisabled(page === channels.length - 1)
178 // .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
179 // .setStyle(ButtonStyle.Primary)
180 // .setCustomId("next")
181 // ])
182 // ]
183 // });
184 // let i;
185 // try {
186 // i = await m.awaitMessageComponent({ time: 300000 });
187 // } catch (e) {
188 // timedOut = true;
189 // continue;
190 // }
191 // i.deferUpdate();
192 // if (i.customId === "next") {
193 // page++;
194 // } else if (i.customId === "previous") {
195 // page--;
196 // } else if (i.customId === "select") {
197 // page = parseInt(i.values[0]);
198 // }
199 // }
200
pineafan63fc5e22022-08-04 22:04:10 +0100201};
pineafan4f164f32022-02-26 22:07:12 +0000202
pineafanbd02b4a2022-08-05 22:01:38 +0100203const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100204 const member = interaction.member as GuildMember;
pineafan3a02ea32022-08-11 21:35:04 +0100205 if (!member.permissions.has("MANAGE_ROLES")) throw new Error("You do not have the *Manage Roles* permission");
pineafan63fc5e22022-08-04 22:04:10 +0100206 return true;
207};
pineafan4f164f32022-02-26 22:07:12 +0000208
Skyler Grey75ea9172022-08-06 10:22:23 +0100209export { command, callback, check };