blob: 12c414f58518a36f22565fa580ea16056dba4d93 [file] [log] [blame]
pineafan3a02ea32022-08-11 21:35:04 +01001import type { HistorySchema } from "../../utils/database.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01002import Discord, {
3 CommandInteraction,
4 GuildMember,
pineafan3a02ea32022-08-11 21:35:04 +01005 Interaction,
6 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04007 ActionRowBuilder,
8 ButtonBuilder,
pineafan3a02ea32022-08-11 21:35:04 +01009 MessageComponentInteraction,
10 ModalSubmitInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -040011 TextInputComponent,
PineaFan100df682023-01-02 13:26:08 +000012 ButtonStyle,
13 StringSelectMenuInteraction
Skyler Grey75ea9172022-08-06 10:22:23 +010014} from "discord.js";
pineafan3a02ea32022-08-11 21:35:04 +010015import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010016import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
17import getEmojiByName from "../../utils/getEmojiByName.js";
18import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010019import { modalInteractionCollector } from "../../utils/dualCollector.js";
20import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4edb7762022-06-26 19:21:04 +010021
22const command = (builder: SlashCommandSubcommandBuilder) =>
23 builder
pineafan63fc5e22022-08-04 22:04:10 +010024 .setName("info")
25 .setDescription("Shows moderator information about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010026 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010027 option.setName("user").setDescription("The user to get information about").setRequired(true)
Skyler Grey75ea9172022-08-06 10:22:23 +010028 );
pineafan4edb7762022-06-26 19:21:04 +010029
pineafan3a02ea32022-08-11 21:35:04 +010030const types: Record<string, { emoji: string; text: string }> = {
Skyler Grey75ea9172022-08-06 10:22:23 +010031 warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
32 mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
33 unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
34 join: { emoji: "MEMBER.JOIN", text: "Joined" },
35 leave: { emoji: "MEMBER.LEAVE", text: "Left" },
36 kick: { emoji: "MEMBER.KICK", text: "Kicked" },
37 softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
38 ban: { emoji: "MEMBER.BAN", text: "Banned" },
39 unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
40 purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
41 nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
pineafan63fc5e22022-08-04 22:04:10 +010042};
pineafan4edb7762022-06-26 19:21:04 +010043
44function historyToString(history: HistorySchema) {
pineafan3a02ea32022-08-11 21:35:04 +010045 if (!Object.keys(types).includes(history.type)) throw new Error("Invalid history type");
46 let s = `${getEmojiByName(types[history.type]!.emoji)} ${history.amount ? history.amount + " " : ""}${
47 types[history.type]!.text
Skyler Grey11236ba2022-08-08 21:13:33 +010048 } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
Skyler Grey75ea9172022-08-06 10:22:23 +010049 if (history.moderator) {
50 s += ` by <@${history.moderator}>`;
51 }
52 if (history.reason) {
53 s += `\n**Reason:**\n> ${history.reason}`;
54 }
55 if (history.before) {
56 s += `\n**Before:**\n> ${history.before}`;
57 }
58 if (history.after) {
59 s += `\n**After:**\n> ${history.after}`;
60 }
pineafan4edb7762022-06-26 19:21:04 +010061 return s + "\n";
62}
63
pineafan4edb7762022-06-26 19:21:04 +010064class TimelineSection {
pineafan3a02ea32022-08-11 21:35:04 +010065 name: string = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010066 content: { data: HistorySchema; rendered: string }[] = [];
pineafan4edb7762022-06-26 19:21:04 +010067
Skyler Grey75ea9172022-08-06 10:22:23 +010068 addContent = (content: { data: HistorySchema; rendered: string }) => {
69 this.content.push(content);
70 return this;
71 };
72 contentLength = () => {
73 return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
74 };
pineafan4edb7762022-06-26 19:21:04 +010075 generateName = () => {
pineafan3a02ea32022-08-11 21:35:04 +010076 const first = Math.round(this.content[0]!.data.occurredAt.getTime() / 1000);
77 const last = Math.round(this.content[this.content.length - 1]!.data.occurredAt.getTime() / 1000);
Skyler Grey75ea9172022-08-06 10:22:23 +010078 if (first === last) {
79 return (this.name = `<t:${first}:F>`);
80 }
81 return (this.name = `<t:${first}:F> - <t:${last}:F>`);
pineafan63fc5e22022-08-04 22:04:10 +010082 };
pineafan4edb7762022-06-26 19:21:04 +010083}
84
Skyler Grey75ea9172022-08-06 10:22:23 +010085const monthNames = [
86 "January",
87 "February",
88 "March",
89 "April",
90 "May",
91 "June",
92 "July",
93 "August",
94 "September",
95 "October",
96 "November",
97 "December"
98];
pineafan4edb7762022-06-26 19:21:04 +010099
pineafan3a02ea32022-08-11 21:35:04 +0100100async function showHistory(member: Discord.GuildMember, interaction: CommandInteraction) {
pineafan4edb7762022-06-26 19:21:04 +0100101 let currentYear = new Date().getFullYear();
pineafan3a02ea32022-08-11 21:35:04 +0100102 let pageIndex: number | null = null;
103 let history, current: TimelineSection;
PineaFan100df682023-01-02 13:26:08 +0000104 history = await client.database.history.read(member.guild.id, member.id, currentYear);
105 history = history
106 .sort(
107 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
108 b.occurredAt.getTime() - a.occurredAt.getTime()
109 )
110 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100111 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000112 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100113 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100114 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100115 let timedOut = false;
116 let showHistorySelected = false;
117 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100118 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100119 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100120 history = history
121 .sort(
122 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
123 b.occurredAt.getTime() - a.occurredAt.getTime()
124 )
125 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100126 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100127 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100128 if (filteredTypes.length === 0) {
129 tempFilteredTypes = Object.keys(types);
130 }
pineafan3a02ea32022-08-11 21:35:04 +0100131 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100132 }
pineafan4edb7762022-06-26 19:21:04 +0100133 refresh = false;
134 }
pineafan63fc5e22022-08-04 22:04:10 +0100135 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100136 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100137 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100138 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100139 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100140 groups.push(current);
141 current.generateName();
142 current = new TimelineSection();
143 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100144 current.addContent({
145 data: event,
146 rendered: historyToString(event)
147 });
pineafan4edb7762022-06-26 19:21:04 +0100148 });
149 current.generateName();
150 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 if (pageIndex === null) {
152 pageIndex = groups.length - 1;
153 }
pineafan4edb7762022-06-26 19:21:04 +0100154 }
pineafan3a02ea32022-08-11 21:35:04 +0100155 if (pageIndex === null) pageIndex = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100156 const components = (
Skyler Grey75ea9172022-08-06 10:22:23 +0100157 openFilterPane
158 ? [
PineaFan100df682023-01-02 13:26:08 +0000159 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -0400160 new Discord.SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100161 .setOptions(
162 Object.entries(types).map(([key, value]) => ({
163 label: value.text,
164 value: key,
165 default: filteredTypes.includes(key),
Skyler Grey11236ba2022-08-08 21:13:33 +0100166 emoji: client.emojis.resolve(getEmojiByName(value.emoji, "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100167 }))
168 )
169 .setMinValues(1)
170 .setMaxValues(Object.keys(types).length)
171 .setCustomId("filter")
172 .setPlaceholder("Select at least one event")
PineaFan100df682023-01-02 13:26:08 +0000173 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100174 ]
175 : []
176 ).concat([
PineaFan100df682023-01-02 13:26:08 +0000177 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400178 new ButtonBuilder()
pineafan4edb7762022-06-26 19:21:04 +0100179 .setCustomId("prevYear")
180 .setLabel((currentYear - 1).toString())
181 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400182 .setStyle(ButtonStyle.Secondary),
183 new ButtonBuilder().setCustomId("prevPage").setLabel("Previous page").setStyle(ButtonStyle.Primary),
184 new ButtonBuilder().setCustomId("today").setLabel("Today").setStyle(ButtonStyle.Primary),
185 new ButtonBuilder()
pineafan4edb7762022-06-26 19:21:04 +0100186 .setCustomId("nextPage")
187 .setLabel("Next page")
TheCodedProf21c08592022-09-13 14:14:43 -0400188 .setStyle(ButtonStyle.Primary)
Skyler Grey11236ba2022-08-08 21:13:33 +0100189 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
TheCodedProf21c08592022-09-13 14:14:43 -0400190 new ButtonBuilder()
pineafan4edb7762022-06-26 19:21:04 +0100191 .setCustomId("nextYear")
192 .setLabel((currentYear + 1).toString())
193 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400194 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100195 .setDisabled(currentYear === new Date().getFullYear())
Skyler Grey75ea9172022-08-06 10:22:23 +0100196 ]),
PineaFan100df682023-01-02 13:26:08 +0000197 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400198 new ButtonBuilder()
pineafan4edb7762022-06-26 19:21:04 +0100199 .setLabel("Mod notes")
200 .setCustomId("modNotes")
TheCodedProf21c08592022-09-13 14:14:43 -0400201 .setStyle(ButtonStyle.Primary)
pineafan4edb7762022-06-26 19:21:04 +0100202 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400203 new ButtonBuilder()
pineafan4edb7762022-06-26 19:21:04 +0100204 .setLabel("Filter")
205 .setCustomId("openFilter")
TheCodedProf21c08592022-09-13 14:14:43 -0400206 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
pineafan4edb7762022-06-26 19:21:04 +0100207 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
208 ])
pineafan63fc5e22022-08-04 22:04:10 +0100209 ]);
Skyler Grey75ea9172022-08-06 10:22:23 +0100210 const end =
211 "\n\nJanuary " +
212 currentYear.toString() +
Skyler Grey11236ba2022-08-08 21:13:33 +0100213 pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
214 (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100215 " " +
216 currentYear.toString();
pineafan4edb7762022-06-26 19:21:04 +0100217 if (groups.length > 0) {
pineafan3a02ea32022-08-11 21:35:04 +0100218 const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
219 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100220 embeds: [
221 new EmojiEmbed()
222 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100223 .setTitle("Moderation history for " + member.user.username)
Skyler Grey75ea9172022-08-06 10:22:23 +0100224 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100225 `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
Skyler Grey75ea9172022-08-06 10:22:23 +0100226 )
227 .setStatus("Success")
228 .setFooter({
Skyler Grey11236ba2022-08-08 21:13:33 +0100229 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : ""
Skyler Grey75ea9172022-08-06 10:22:23 +0100230 })
231 ],
232 components: components
pineafan3a02ea32022-08-11 21:35:04 +0100233 })) as Message;
pineafan4edb7762022-06-26 19:21:04 +0100234 } else {
pineafan3a02ea32022-08-11 21:35:04 +0100235 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 embeds: [
237 new EmojiEmbed()
238 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100239 .setTitle("Moderation history for " + member.user.username)
240 .setDescription(`**${currentYear}**\n\n*No events*` + "\n\n" + end)
Skyler Grey75ea9172022-08-06 10:22:23 +0100241 .setStatus("Success")
242 .setFooter({
Skyler Grey11236ba2022-08-08 21:13:33 +0100243 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : ""
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 })
245 ],
246 components: components
pineafan3a02ea32022-08-11 21:35:04 +0100247 })) as Message;
pineafan4edb7762022-06-26 19:21:04 +0100248 }
pineafan3a02ea32022-08-11 21:35:04 +0100249 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100250 try {
251 i = await m.awaitMessageComponent({ time: 300000 });
252 } catch (e) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100253 interaction.editReply({
254 embeds: [
255 new EmojiEmbed()
256 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100257 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100258 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 .setStatus("Danger")
260 .setFooter({ text: "Message timed out" })
261 ]
262 });
Skyler Greyad002172022-08-16 18:48:26 +0100263 timedOut = true;
264 continue;
pineafan4edb7762022-06-26 19:21:04 +0100265 }
pineafan63fc5e22022-08-04 22:04:10 +0100266 i.deferUpdate();
pineafan4edb7762022-06-26 19:21:04 +0100267 if (i.customId === "filter") {
PineaFan100df682023-01-02 13:26:08 +0000268 filteredTypes = (i as StringSelectMenuInteraction).values;
pineafan4edb7762022-06-26 19:21:04 +0100269 pageIndex = null;
270 refresh = true;
271 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 if (i.customId === "prevYear") {
273 currentYear--;
274 pageIndex = null;
275 refresh = true;
276 }
277 if (i.customId === "nextYear") {
278 currentYear++;
279 pageIndex = null;
280 refresh = true;
281 }
pineafan4edb7762022-06-26 19:21:04 +0100282 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100283 pageIndex!--;
284 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100285 pageIndex = null;
286 currentYear--;
287 refresh = true;
288 }
pineafan4edb7762022-06-26 19:21:04 +0100289 }
290 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100291 pageIndex!++;
292 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100293 pageIndex = 0;
294 currentYear++;
295 refresh = true;
296 }
pineafan4edb7762022-06-26 19:21:04 +0100297 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100298 if (i.customId === "today") {
299 currentYear = new Date().getFullYear();
300 pageIndex = null;
301 refresh = true;
302 }
303 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100304 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100305 }
306 if (i.customId === "openFilter") {
307 openFilterPane = !openFilterPane;
308 refresh = true;
309 }
pineafan4edb7762022-06-26 19:21:04 +0100310 }
Skyler Greyad002172022-08-16 18:48:26 +0100311 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100312}
313
pineafan3a02ea32022-08-11 21:35:04 +0100314const callback = async (interaction: CommandInteraction): Promise<unknown> => {
315 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100316 const member = interaction.options.getMember("user") as Discord.GuildMember;
317 await interaction.reply({
Skyler Grey11236ba2022-08-08 21:13:33 +0100318 embeds: [new EmojiEmbed().setEmoji("NUCLEUS.LOADING").setTitle("Downloading Data").setStatus("Danger")],
Skyler Grey75ea9172022-08-06 10:22:23 +0100319 ephemeral: true,
320 fetchReply: true
321 });
pineafan4edb7762022-06-26 19:21:04 +0100322 let note;
323 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100324 let timedOut = false;
325 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100326 note = await client.database.notes.read(member.guild.id, member.id);
Skyler Grey75ea9172022-08-06 10:22:23 +0100327 if (firstLoad && !note) {
328 await showHistory(member, interaction);
329 }
pineafan4edb7762022-06-26 19:21:04 +0100330 firstLoad = false;
pineafan3a02ea32022-08-11 21:35:04 +0100331 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 embeds: [
333 new EmojiEmbed()
334 .setEmoji("MEMBER.JOIN")
335 .setTitle("Mod notes for " + member.user.username)
336 .setDescription(note ? note : "*No note set*")
337 .setStatus("Success")
338 ],
339 components: [
PineaFan100df682023-01-02 13:26:08 +0000340 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400341 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100342 .setLabel(`${note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400343 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100344 .setCustomId("modify")
345 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400346 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100347 .setLabel("View moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400348 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100349 .setCustomId("history")
350 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
351 ])
352 ]
pineafan3a02ea32022-08-11 21:35:04 +0100353 })) as Message;
354 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100355 try {
356 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100357 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100358 timedOut = true;
359 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100360 }
pineafan4edb7762022-06-26 19:21:04 +0100361 if (i.customId === "modify") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100362 await i.showModal(
PineaFan100df682023-01-02 13:26:08 +0000363 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100364 .setCustomId("modal")
365 .setTitle("Editing moderator note")
366 .addComponents(
PineaFan100df682023-01-02 13:26:08 +0000367 new ActionRowBuilder<Discord.TextInputComponent>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100368 new TextInputComponent()
369 .setCustomId("note")
370 .setLabel("Note")
371 .setMaxLength(4000)
372 .setRequired(false)
373 .setStyle("PARAGRAPH")
374 .setValue(note ? note : "")
375 )
376 )
377 );
pineafan4edb7762022-06-26 19:21:04 +0100378 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100379 embeds: [
380 new EmojiEmbed()
381 .setTitle("Mod notes for " + member.user.username)
Skyler Grey11236ba2022-08-08 21:13:33 +0100382 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100383 .setStatus("Success")
384 .setEmoji("GUILD.TICKET.OPEN")
385 ],
386 components: [
PineaFan100df682023-01-02 13:26:08 +0000387 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400388 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100389 .setLabel("Back")
390 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400391 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100392 .setCustomId("back")
393 ])
394 ]
pineafan4edb7762022-06-26 19:21:04 +0100395 });
396 let out;
397 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100398 out = await modalInteractionCollector(
399 m,
pineafan3a02ea32022-08-11 21:35:04 +0100400 (m: Interaction) =>
401 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId === interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100402 (m) => m.customId === "modify"
403 );
404 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100405 timedOut = true;
406 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100407 }
pineafan3a02ea32022-08-11 21:35:04 +0100408 if (out === null) {
409 continue;
410 } else if (out instanceof ModalSubmitInteraction) {
pineafan63fc5e22022-08-04 22:04:10 +0100411 const toAdd = out.fields.getTextInputValue("note") || null;
Skyler Grey11236ba2022-08-08 21:13:33 +0100412 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100413 } else {
414 continue;
415 }
pineafan4edb7762022-06-26 19:21:04 +0100416 } else if (i.customId === "history") {
417 i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100418 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100419 }
420 }
pineafan63fc5e22022-08-04 22:04:10 +0100421};
pineafan4edb7762022-06-26 19:21:04 +0100422
pineafanbd02b4a2022-08-05 22:01:38 +0100423const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100424 const member = interaction.member as GuildMember;
PineaFan100df682023-01-02 13:26:08 +0000425 if (!member.permissions.has("ModerateMembers"))
pineafan3a02ea32022-08-11 21:35:04 +0100426 throw new Error("You do not have the *Moderate Members* permission");
pineafan63fc5e22022-08-04 22:04:10 +0100427 return true;
428};
pineafan4edb7762022-06-26 19:21:04 +0100429
430export { command };
431export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100432export { check };