blob: 6b5c81e1466769ee28316dc1679feccde47ca218 [file] [log] [blame]
PineaFana34d04b2023-01-03 22:05:42 +00001import { LoadingEmbed } from './../../utils/defaultEmbeds.js';
pineafan3a02ea32022-08-11 21:35:04 +01002import type { HistorySchema } from "../../utils/database.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01003import Discord, {
4 CommandInteraction,
5 GuildMember,
pineafan3a02ea32022-08-11 21:35:04 +01006 Interaction,
7 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04008 ActionRowBuilder,
9 ButtonBuilder,
pineafan3a02ea32022-08-11 21:35:04 +010010 MessageComponentInteraction,
11 ModalSubmitInteraction,
PineaFan100df682023-01-02 13:26:08 +000012 ButtonStyle,
PineaFana34d04b2023-01-03 22:05:42 +000013 StringSelectMenuInteraction,
14 TextInputStyle,
Skyler Grey75ea9172022-08-06 10:22:23 +010015} from "discord.js";
PineaFan5bea7e12023-01-05 21:20:04 +000016import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010017import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
18import getEmojiByName from "../../utils/getEmojiByName.js";
19import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010020import { modalInteractionCollector } from "../../utils/dualCollector.js";
21import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4edb7762022-06-26 19:21:04 +010022
23const command = (builder: SlashCommandSubcommandBuilder) =>
24 builder
pineafan63fc5e22022-08-04 22:04:10 +010025 .setName("info")
26 .setDescription("Shows moderator information about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010027 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010028 option.setName("user").setDescription("The user to get information about").setRequired(true)
Skyler Grey75ea9172022-08-06 10:22:23 +010029 );
pineafan4edb7762022-06-26 19:21:04 +010030
pineafan3a02ea32022-08-11 21:35:04 +010031const types: Record<string, { emoji: string; text: string }> = {
Skyler Grey75ea9172022-08-06 10:22:23 +010032 warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
33 mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
34 unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
35 join: { emoji: "MEMBER.JOIN", text: "Joined" },
36 leave: { emoji: "MEMBER.LEAVE", text: "Left" },
37 kick: { emoji: "MEMBER.KICK", text: "Kicked" },
38 softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
39 ban: { emoji: "MEMBER.BAN", text: "Banned" },
40 unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
41 purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
42 nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
pineafan63fc5e22022-08-04 22:04:10 +010043};
pineafan4edb7762022-06-26 19:21:04 +010044
45function historyToString(history: HistorySchema) {
pineafan3a02ea32022-08-11 21:35:04 +010046 if (!Object.keys(types).includes(history.type)) throw new Error("Invalid history type");
47 let s = `${getEmojiByName(types[history.type]!.emoji)} ${history.amount ? history.amount + " " : ""}${
48 types[history.type]!.text
Skyler Grey11236ba2022-08-08 21:13:33 +010049 } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
Skyler Grey75ea9172022-08-06 10:22:23 +010050 if (history.moderator) {
51 s += ` by <@${history.moderator}>`;
52 }
53 if (history.reason) {
54 s += `\n**Reason:**\n> ${history.reason}`;
55 }
56 if (history.before) {
57 s += `\n**Before:**\n> ${history.before}`;
58 }
59 if (history.after) {
60 s += `\n**After:**\n> ${history.after}`;
61 }
pineafan4edb7762022-06-26 19:21:04 +010062 return s + "\n";
63}
64
pineafan4edb7762022-06-26 19:21:04 +010065class TimelineSection {
pineafan3a02ea32022-08-11 21:35:04 +010066 name: string = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010067 content: { data: HistorySchema; rendered: string }[] = [];
pineafan4edb7762022-06-26 19:21:04 +010068
Skyler Grey75ea9172022-08-06 10:22:23 +010069 addContent = (content: { data: HistorySchema; rendered: string }) => {
70 this.content.push(content);
71 return this;
72 };
73 contentLength = () => {
74 return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
75 };
pineafan4edb7762022-06-26 19:21:04 +010076 generateName = () => {
pineafan3a02ea32022-08-11 21:35:04 +010077 const first = Math.round(this.content[0]!.data.occurredAt.getTime() / 1000);
78 const last = Math.round(this.content[this.content.length - 1]!.data.occurredAt.getTime() / 1000);
Skyler Grey75ea9172022-08-06 10:22:23 +010079 if (first === last) {
80 return (this.name = `<t:${first}:F>`);
81 }
82 return (this.name = `<t:${first}:F> - <t:${last}:F>`);
pineafan63fc5e22022-08-04 22:04:10 +010083 };
pineafan4edb7762022-06-26 19:21:04 +010084}
85
Skyler Grey75ea9172022-08-06 10:22:23 +010086const monthNames = [
87 "January",
88 "February",
89 "March",
90 "April",
91 "May",
92 "June",
93 "July",
94 "August",
95 "September",
96 "October",
97 "November",
98 "December"
99];
pineafan4edb7762022-06-26 19:21:04 +0100100
pineafan3a02ea32022-08-11 21:35:04 +0100101async function showHistory(member: Discord.GuildMember, interaction: CommandInteraction) {
pineafan4edb7762022-06-26 19:21:04 +0100102 let currentYear = new Date().getFullYear();
pineafan3a02ea32022-08-11 21:35:04 +0100103 let pageIndex: number | null = null;
104 let history, current: TimelineSection;
PineaFan100df682023-01-02 13:26:08 +0000105 history = await client.database.history.read(member.guild.id, member.id, currentYear);
106 history = history
107 .sort(
108 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
109 b.occurredAt.getTime() - a.occurredAt.getTime()
110 )
111 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100112 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000113 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100114 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100115 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100116 let timedOut = false;
117 let showHistorySelected = false;
118 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100119 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100120 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100121 history = history
122 .sort(
123 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
124 b.occurredAt.getTime() - a.occurredAt.getTime()
125 )
126 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100127 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100128 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100129 if (filteredTypes.length === 0) {
130 tempFilteredTypes = Object.keys(types);
131 }
pineafan3a02ea32022-08-11 21:35:04 +0100132 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100133 }
pineafan4edb7762022-06-26 19:21:04 +0100134 refresh = false;
135 }
pineafan63fc5e22022-08-04 22:04:10 +0100136 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100137 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100138 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100139 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100140 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100141 groups.push(current);
142 current.generateName();
143 current = new TimelineSection();
144 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100145 current.addContent({
146 data: event,
147 rendered: historyToString(event)
148 });
pineafan4edb7762022-06-26 19:21:04 +0100149 });
150 current.generateName();
151 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100152 if (pageIndex === null) {
153 pageIndex = groups.length - 1;
154 }
pineafan4edb7762022-06-26 19:21:04 +0100155 }
pineafan3a02ea32022-08-11 21:35:04 +0100156 if (pageIndex === null) pageIndex = 0;
PineaFana34d04b2023-01-03 22:05:42 +0000157 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = []
158 if (openFilterPane) components = components.concat([
159 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
PineaFan5bea7e12023-01-05 21:20:04 +0000160 new Discord.StringSelectMenuBuilder()
161 .setMinValues(1)
162 .setMaxValues(Object.keys(types).length)
163 .setCustomId("filter")
164 .setPlaceholder("Select events to show")
165 .setOptions(...Object.entries(types).map(([key, value]) => new Discord.StringSelectMenuOptionBuilder()
166 .setLabel(value.text)
167 .setValue(key)
168 .setDefault(filteredTypes.includes(key))
169 // @ts-expect-error
170 .setEmoji(getEmojiByName(value.emoji, "id")) // FIXME: This gives a type error but is valid
171 )))
172 ]);
PineaFana34d04b2023-01-03 22:05:42 +0000173 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
174 new ButtonBuilder()
175 .setCustomId("prevYear")
176 .setLabel((currentYear - 1).toString())
177 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
178 .setStyle(ButtonStyle.Secondary),
179 new ButtonBuilder()
180 .setCustomId("prevPage")
181 .setLabel("Previous page")
182 .setStyle(ButtonStyle.Primary),
PineaFan5bea7e12023-01-05 21:20:04 +0000183 new ButtonBuilder()
184 .setCustomId("today")
185 .setLabel("Today")
186 .setStyle(ButtonStyle.Primary),
PineaFana34d04b2023-01-03 22:05:42 +0000187 new ButtonBuilder()
188 .setCustomId("nextPage")
189 .setLabel("Next page")
190 .setStyle(ButtonStyle.Primary)
191 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
192 new ButtonBuilder()
193 .setCustomId("nextYear")
194 .setLabel((currentYear + 1).toString())
195 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
196 .setStyle(ButtonStyle.Secondary)
197 .setDisabled(currentYear === new Date().getFullYear())
198 ])])
199 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
200 new ButtonBuilder()
201 .setLabel("Mod notes")
202 .setCustomId("modNotes")
203 .setStyle(ButtonStyle.Primary)
204 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
205 new ButtonBuilder()
206 .setLabel("Filter")
207 .setCustomId("openFilter")
208 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
209 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
210 ])])
211
Skyler Grey75ea9172022-08-06 10:22:23 +0100212 const end =
213 "\n\nJanuary " +
214 currentYear.toString() +
Skyler Grey11236ba2022-08-08 21:13:33 +0100215 pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
216 (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100217 " " +
218 currentYear.toString();
pineafan4edb7762022-06-26 19:21:04 +0100219 if (groups.length > 0) {
pineafan3a02ea32022-08-11 21:35:04 +0100220 const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
PineaFana34d04b2023-01-03 22:05:42 +0000221 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100222 embeds: [
223 new EmojiEmbed()
224 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100225 .setTitle("Moderation history for " + member.user.username)
Skyler Grey75ea9172022-08-06 10:22:23 +0100226 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100227 `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
Skyler Grey75ea9172022-08-06 10:22:23 +0100228 )
229 .setStatus("Success")
230 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000231 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100232 })
233 ],
234 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000235 });
pineafan4edb7762022-06-26 19:21:04 +0100236 } else {
PineaFana34d04b2023-01-03 22:05:42 +0000237 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100238 embeds: [
239 new EmojiEmbed()
240 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100241 .setTitle("Moderation history for " + member.user.username)
PineaFana34d04b2023-01-03 22:05:42 +0000242 .setDescription(`**${currentYear}**\n\n*No events*`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100243 .setStatus("Success")
244 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000245 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100246 })
247 ],
248 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000249 })
pineafan4edb7762022-06-26 19:21:04 +0100250 }
pineafan3a02ea32022-08-11 21:35:04 +0100251 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100252 try {
253 i = await m.awaitMessageComponent({ time: 300000 });
254 } catch (e) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 interaction.editReply({
256 embeds: [
257 new EmojiEmbed()
258 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100259 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100260 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100261 .setStatus("Danger")
262 .setFooter({ text: "Message timed out" })
263 ]
264 });
Skyler Greyad002172022-08-16 18:48:26 +0100265 timedOut = true;
266 continue;
pineafan4edb7762022-06-26 19:21:04 +0100267 }
pineafan63fc5e22022-08-04 22:04:10 +0100268 i.deferUpdate();
pineafan4edb7762022-06-26 19:21:04 +0100269 if (i.customId === "filter") {
PineaFan100df682023-01-02 13:26:08 +0000270 filteredTypes = (i as StringSelectMenuInteraction).values;
pineafan4edb7762022-06-26 19:21:04 +0100271 pageIndex = null;
272 refresh = true;
273 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100274 if (i.customId === "prevYear") {
275 currentYear--;
276 pageIndex = null;
277 refresh = true;
278 }
279 if (i.customId === "nextYear") {
280 currentYear++;
281 pageIndex = null;
282 refresh = true;
283 }
pineafan4edb7762022-06-26 19:21:04 +0100284 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100285 pageIndex!--;
286 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100287 pageIndex = null;
288 currentYear--;
289 refresh = true;
290 }
pineafan4edb7762022-06-26 19:21:04 +0100291 }
292 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100293 pageIndex!++;
294 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100295 pageIndex = 0;
296 currentYear++;
297 refresh = true;
298 }
pineafan4edb7762022-06-26 19:21:04 +0100299 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100300 if (i.customId === "today") {
301 currentYear = new Date().getFullYear();
302 pageIndex = null;
303 refresh = true;
304 }
305 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100306 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100307 }
308 if (i.customId === "openFilter") {
309 openFilterPane = !openFilterPane;
310 refresh = true;
311 }
pineafan4edb7762022-06-26 19:21:04 +0100312 }
Skyler Greyad002172022-08-16 18:48:26 +0100313 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100314}
315
pineafan3a02ea32022-08-11 21:35:04 +0100316const callback = async (interaction: CommandInteraction): Promise<unknown> => {
317 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100318 const member = interaction.options.getMember("user") as Discord.GuildMember;
319 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000320 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100321 ephemeral: true,
322 fetchReply: true
323 });
pineafan4edb7762022-06-26 19:21:04 +0100324 let note;
325 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100326 let timedOut = false;
327 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100328 note = await client.database.notes.read(member.guild.id, member.id);
PineaFana34d04b2023-01-03 22:05:42 +0000329 if (firstLoad && !note) { await showHistory(member, interaction); }
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()
PineaFana34d04b2023-01-03 22:05:42 +0000347 .setLabel("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(
PineaFana34d04b2023-01-03 22:05:42 +0000367 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
368 new Discord.TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100369 .setCustomId("note")
370 .setLabel("Note")
371 .setMaxLength(4000)
372 .setRequired(false)
PineaFana34d04b2023-01-03 22:05:42 +0000373 .setStyle(TextInputStyle.Paragraph)
374 .setValue(note ? note : " ")
Skyler Grey75ea9172022-08-06 10:22:23 +0100375 )
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) {
PineaFana34d04b2023-01-03 22:05:42 +0000411 let toAdd = out.fields.getTextInputValue("note") || null;
412 if (toAdd === " ") toAdd = null;
413 if (toAdd) toAdd = toAdd.trim();
Skyler Grey11236ba2022-08-08 21:13:33 +0100414 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100415 } else {
416 continue;
417 }
pineafan4edb7762022-06-26 19:21:04 +0100418 } else if (i.customId === "history") {
419 i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100420 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100421 }
422 }
pineafan63fc5e22022-08-04 22:04:10 +0100423};
pineafan4edb7762022-06-26 19:21:04 +0100424
pineafanbd02b4a2022-08-05 22:01:38 +0100425const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100426 const member = interaction.member as GuildMember;
PineaFan100df682023-01-02 13:26:08 +0000427 if (!member.permissions.has("ModerateMembers"))
pineafan3a02ea32022-08-11 21:35:04 +0100428 throw new Error("You do not have the *Moderate Members* permission");
pineafan63fc5e22022-08-04 22:04:10 +0100429 return true;
430};
pineafan4edb7762022-06-26 19:21:04 +0100431
432export { command };
433export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100434export { check };