blob: 61a01e2f558c290060c8f667d727675d6e7410f8 [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,
15 APIMessageComponentEmoji
Skyler Grey75ea9172022-08-06 10:22:23 +010016} from "discord.js";
PineaFana34d04b2023-01-03 22:05:42 +000017import { SlashCommandSubcommandBuilder, StringSelectMenuOptionBuilder } from "@discordjs/builders";
pineafan4edb7762022-06-26 19:21:04 +010018import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
19import getEmojiByName from "../../utils/getEmojiByName.js";
20import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010021import { modalInteractionCollector } from "../../utils/dualCollector.js";
22import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4edb7762022-06-26 19:21:04 +010023
24const command = (builder: SlashCommandSubcommandBuilder) =>
25 builder
pineafan63fc5e22022-08-04 22:04:10 +010026 .setName("info")
27 .setDescription("Shows moderator information about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010028 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010029 option.setName("user").setDescription("The user to get information about").setRequired(true)
Skyler Grey75ea9172022-08-06 10:22:23 +010030 );
pineafan4edb7762022-06-26 19:21:04 +010031
pineafan3a02ea32022-08-11 21:35:04 +010032const types: Record<string, { emoji: string; text: string }> = {
Skyler Grey75ea9172022-08-06 10:22:23 +010033 warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
34 mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
35 unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
36 join: { emoji: "MEMBER.JOIN", text: "Joined" },
37 leave: { emoji: "MEMBER.LEAVE", text: "Left" },
38 kick: { emoji: "MEMBER.KICK", text: "Kicked" },
39 softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
40 ban: { emoji: "MEMBER.BAN", text: "Banned" },
41 unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
42 purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
43 nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
pineafan63fc5e22022-08-04 22:04:10 +010044};
pineafan4edb7762022-06-26 19:21:04 +010045
46function historyToString(history: HistorySchema) {
pineafan3a02ea32022-08-11 21:35:04 +010047 if (!Object.keys(types).includes(history.type)) throw new Error("Invalid history type");
48 let s = `${getEmojiByName(types[history.type]!.emoji)} ${history.amount ? history.amount + " " : ""}${
49 types[history.type]!.text
Skyler Grey11236ba2022-08-08 21:13:33 +010050 } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
Skyler Grey75ea9172022-08-06 10:22:23 +010051 if (history.moderator) {
52 s += ` by <@${history.moderator}>`;
53 }
54 if (history.reason) {
55 s += `\n**Reason:**\n> ${history.reason}`;
56 }
57 if (history.before) {
58 s += `\n**Before:**\n> ${history.before}`;
59 }
60 if (history.after) {
61 s += `\n**After:**\n> ${history.after}`;
62 }
pineafan4edb7762022-06-26 19:21:04 +010063 return s + "\n";
64}
65
pineafan4edb7762022-06-26 19:21:04 +010066class TimelineSection {
pineafan3a02ea32022-08-11 21:35:04 +010067 name: string = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010068 content: { data: HistorySchema; rendered: string }[] = [];
pineafan4edb7762022-06-26 19:21:04 +010069
Skyler Grey75ea9172022-08-06 10:22:23 +010070 addContent = (content: { data: HistorySchema; rendered: string }) => {
71 this.content.push(content);
72 return this;
73 };
74 contentLength = () => {
75 return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
76 };
pineafan4edb7762022-06-26 19:21:04 +010077 generateName = () => {
pineafan3a02ea32022-08-11 21:35:04 +010078 const first = Math.round(this.content[0]!.data.occurredAt.getTime() / 1000);
79 const last = Math.round(this.content[this.content.length - 1]!.data.occurredAt.getTime() / 1000);
Skyler Grey75ea9172022-08-06 10:22:23 +010080 if (first === last) {
81 return (this.name = `<t:${first}:F>`);
82 }
83 return (this.name = `<t:${first}:F> - <t:${last}:F>`);
pineafan63fc5e22022-08-04 22:04:10 +010084 };
pineafan4edb7762022-06-26 19:21:04 +010085}
86
Skyler Grey75ea9172022-08-06 10:22:23 +010087const monthNames = [
88 "January",
89 "February",
90 "March",
91 "April",
92 "May",
93 "June",
94 "July",
95 "August",
96 "September",
97 "October",
98 "November",
99 "December"
100];
pineafan4edb7762022-06-26 19:21:04 +0100101
pineafan3a02ea32022-08-11 21:35:04 +0100102async function showHistory(member: Discord.GuildMember, interaction: CommandInteraction) {
pineafan4edb7762022-06-26 19:21:04 +0100103 let currentYear = new Date().getFullYear();
pineafan3a02ea32022-08-11 21:35:04 +0100104 let pageIndex: number | null = null;
105 let history, current: TimelineSection;
PineaFan100df682023-01-02 13:26:08 +0000106 history = await client.database.history.read(member.guild.id, member.id, currentYear);
107 history = history
108 .sort(
109 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
110 b.occurredAt.getTime() - a.occurredAt.getTime()
111 )
112 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100113 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000114 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100115 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100116 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100117 let timedOut = false;
118 let showHistorySelected = false;
119 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100120 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100121 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100122 history = history
123 .sort(
124 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
125 b.occurredAt.getTime() - a.occurredAt.getTime()
126 )
127 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100128 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100129 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 if (filteredTypes.length === 0) {
131 tempFilteredTypes = Object.keys(types);
132 }
pineafan3a02ea32022-08-11 21:35:04 +0100133 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100134 }
pineafan4edb7762022-06-26 19:21:04 +0100135 refresh = false;
136 }
pineafan63fc5e22022-08-04 22:04:10 +0100137 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100138 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100139 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100140 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100141 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100142 groups.push(current);
143 current.generateName();
144 current = new TimelineSection();
145 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 current.addContent({
147 data: event,
148 rendered: historyToString(event)
149 });
pineafan4edb7762022-06-26 19:21:04 +0100150 });
151 current.generateName();
152 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100153 if (pageIndex === null) {
154 pageIndex = groups.length - 1;
155 }
pineafan4edb7762022-06-26 19:21:04 +0100156 }
pineafan3a02ea32022-08-11 21:35:04 +0100157 if (pageIndex === null) pageIndex = 0;
PineaFana34d04b2023-01-03 22:05:42 +0000158 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = []
159 if (openFilterPane) components = components.concat([
160 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
161 new Discord.StringSelectMenuBuilder().setOptions(
PineaFan9dac7af2023-01-04 22:05:45 +0000162 // ...Object.entries(types).map(([key, value]) => new StringSelectMenuOptionBuilder()
163 // .setLabel(value.text)
164 // .setValue(key)
165 // .setDefault(filteredTypes.includes(key))
166 // .setEmoji(client.emojis.resolve(getEmojiByName(value.emoji, "id"))! as APIMessageComponentEmoji)
167 // )
168 ...Object.entries(types).map(([key, value]) => ({
169 label: value.text,
170 value: key,
171 default: filteredTypes.includes(key),
172 emoji: client.emojis.resolve(getEmojiByName(value.emoji, "id"))! as APIMessageComponentEmoji
173 }))
PineaFana34d04b2023-01-03 22:05:42 +0000174 )
175 .setMinValues(1)
176 .setMaxValues(Object.keys(types).length)
177 .setCustomId("filter")
178 .setPlaceholder("Select events to show")
179 )
180 ])
181 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
182 new ButtonBuilder()
183 .setCustomId("prevYear")
184 .setLabel((currentYear - 1).toString())
185 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
186 .setStyle(ButtonStyle.Secondary),
187 new ButtonBuilder()
188 .setCustomId("prevPage")
189 .setLabel("Previous page")
190 .setStyle(ButtonStyle.Primary),
191 new ButtonBuilder().setCustomId("today").setLabel("Today").setStyle(ButtonStyle.Primary),
192 new ButtonBuilder()
193 .setCustomId("nextPage")
194 .setLabel("Next page")
195 .setStyle(ButtonStyle.Primary)
196 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
197 new ButtonBuilder()
198 .setCustomId("nextYear")
199 .setLabel((currentYear + 1).toString())
200 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
201 .setStyle(ButtonStyle.Secondary)
202 .setDisabled(currentYear === new Date().getFullYear())
203 ])])
204 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
205 new ButtonBuilder()
206 .setLabel("Mod notes")
207 .setCustomId("modNotes")
208 .setStyle(ButtonStyle.Primary)
209 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
210 new ButtonBuilder()
211 .setLabel("Filter")
212 .setCustomId("openFilter")
213 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
214 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
215 ])])
216
Skyler Grey75ea9172022-08-06 10:22:23 +0100217 const end =
218 "\n\nJanuary " +
219 currentYear.toString() +
Skyler Grey11236ba2022-08-08 21:13:33 +0100220 pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
221 (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100222 " " +
223 currentYear.toString();
pineafan4edb7762022-06-26 19:21:04 +0100224 if (groups.length > 0) {
pineafan3a02ea32022-08-11 21:35:04 +0100225 const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
PineaFana34d04b2023-01-03 22:05:42 +0000226 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100227 embeds: [
228 new EmojiEmbed()
229 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100230 .setTitle("Moderation history for " + member.user.username)
Skyler Grey75ea9172022-08-06 10:22:23 +0100231 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100232 `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 )
234 .setStatus("Success")
235 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000236 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100237 })
238 ],
239 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000240 });
pineafan4edb7762022-06-26 19:21:04 +0100241 } else {
PineaFana34d04b2023-01-03 22:05:42 +0000242 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100243 embeds: [
244 new EmojiEmbed()
245 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100246 .setTitle("Moderation history for " + member.user.username)
PineaFana34d04b2023-01-03 22:05:42 +0000247 .setDescription(`**${currentYear}**\n\n*No events*`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100248 .setStatus("Success")
249 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000250 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100251 })
252 ],
253 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000254 })
pineafan4edb7762022-06-26 19:21:04 +0100255 }
pineafan3a02ea32022-08-11 21:35:04 +0100256 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100257 try {
258 i = await m.awaitMessageComponent({ time: 300000 });
259 } catch (e) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100260 interaction.editReply({
261 embeds: [
262 new EmojiEmbed()
263 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100264 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100265 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 .setStatus("Danger")
267 .setFooter({ text: "Message timed out" })
268 ]
269 });
Skyler Greyad002172022-08-16 18:48:26 +0100270 timedOut = true;
271 continue;
pineafan4edb7762022-06-26 19:21:04 +0100272 }
pineafan63fc5e22022-08-04 22:04:10 +0100273 i.deferUpdate();
pineafan4edb7762022-06-26 19:21:04 +0100274 if (i.customId === "filter") {
PineaFan100df682023-01-02 13:26:08 +0000275 filteredTypes = (i as StringSelectMenuInteraction).values;
pineafan4edb7762022-06-26 19:21:04 +0100276 pageIndex = null;
277 refresh = true;
278 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100279 if (i.customId === "prevYear") {
280 currentYear--;
281 pageIndex = null;
282 refresh = true;
283 }
284 if (i.customId === "nextYear") {
285 currentYear++;
286 pageIndex = null;
287 refresh = true;
288 }
pineafan4edb7762022-06-26 19:21:04 +0100289 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100290 pageIndex!--;
291 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100292 pageIndex = null;
293 currentYear--;
294 refresh = true;
295 }
pineafan4edb7762022-06-26 19:21:04 +0100296 }
297 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100298 pageIndex!++;
299 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100300 pageIndex = 0;
301 currentYear++;
302 refresh = true;
303 }
pineafan4edb7762022-06-26 19:21:04 +0100304 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100305 if (i.customId === "today") {
306 currentYear = new Date().getFullYear();
307 pageIndex = null;
308 refresh = true;
309 }
310 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100311 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100312 }
313 if (i.customId === "openFilter") {
314 openFilterPane = !openFilterPane;
315 refresh = true;
316 }
pineafan4edb7762022-06-26 19:21:04 +0100317 }
Skyler Greyad002172022-08-16 18:48:26 +0100318 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100319}
320
pineafan3a02ea32022-08-11 21:35:04 +0100321const callback = async (interaction: CommandInteraction): Promise<unknown> => {
322 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100323 const member = interaction.options.getMember("user") as Discord.GuildMember;
324 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000325 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100326 ephemeral: true,
327 fetchReply: true
328 });
pineafan4edb7762022-06-26 19:21:04 +0100329 let note;
330 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100331 let timedOut = false;
332 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100333 note = await client.database.notes.read(member.guild.id, member.id);
PineaFana34d04b2023-01-03 22:05:42 +0000334 if (firstLoad && !note) { await showHistory(member, interaction); }
pineafan4edb7762022-06-26 19:21:04 +0100335 firstLoad = false;
pineafan3a02ea32022-08-11 21:35:04 +0100336 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100337 embeds: [
338 new EmojiEmbed()
339 .setEmoji("MEMBER.JOIN")
340 .setTitle("Mod notes for " + member.user.username)
341 .setDescription(note ? note : "*No note set*")
342 .setStatus("Success")
343 ],
344 components: [
PineaFan100df682023-01-02 13:26:08 +0000345 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400346 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100347 .setLabel(`${note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400348 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100349 .setCustomId("modify")
350 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400351 new ButtonBuilder()
PineaFana34d04b2023-01-03 22:05:42 +0000352 .setLabel("Moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400353 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100354 .setCustomId("history")
355 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
356 ])
357 ]
pineafan3a02ea32022-08-11 21:35:04 +0100358 })) as Message;
359 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100360 try {
361 i = await m.awaitMessageComponent({ time: 300000 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100362 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100363 timedOut = true;
364 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 }
pineafan4edb7762022-06-26 19:21:04 +0100366 if (i.customId === "modify") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100367 await i.showModal(
PineaFan100df682023-01-02 13:26:08 +0000368 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100369 .setCustomId("modal")
370 .setTitle("Editing moderator note")
371 .addComponents(
PineaFana34d04b2023-01-03 22:05:42 +0000372 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
373 new Discord.TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100374 .setCustomId("note")
375 .setLabel("Note")
376 .setMaxLength(4000)
377 .setRequired(false)
PineaFana34d04b2023-01-03 22:05:42 +0000378 .setStyle(TextInputStyle.Paragraph)
379 .setValue(note ? note : " ")
Skyler Grey75ea9172022-08-06 10:22:23 +0100380 )
381 )
382 );
pineafan4edb7762022-06-26 19:21:04 +0100383 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100384 embeds: [
385 new EmojiEmbed()
386 .setTitle("Mod notes for " + member.user.username)
Skyler Grey11236ba2022-08-08 21:13:33 +0100387 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100388 .setStatus("Success")
389 .setEmoji("GUILD.TICKET.OPEN")
390 ],
391 components: [
PineaFan100df682023-01-02 13:26:08 +0000392 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400393 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100394 .setLabel("Back")
395 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400396 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100397 .setCustomId("back")
398 ])
399 ]
pineafan4edb7762022-06-26 19:21:04 +0100400 });
401 let out;
402 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100403 out = await modalInteractionCollector(
404 m,
pineafan3a02ea32022-08-11 21:35:04 +0100405 (m: Interaction) =>
406 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId === interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100407 (m) => m.customId === "modify"
408 );
409 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100410 timedOut = true;
411 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100412 }
pineafan3a02ea32022-08-11 21:35:04 +0100413 if (out === null) {
414 continue;
415 } else if (out instanceof ModalSubmitInteraction) {
PineaFana34d04b2023-01-03 22:05:42 +0000416 let toAdd = out.fields.getTextInputValue("note") || null;
417 if (toAdd === " ") toAdd = null;
418 if (toAdd) toAdd = toAdd.trim();
Skyler Grey11236ba2022-08-08 21:13:33 +0100419 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100420 } else {
421 continue;
422 }
pineafan4edb7762022-06-26 19:21:04 +0100423 } else if (i.customId === "history") {
424 i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100425 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100426 }
427 }
pineafan63fc5e22022-08-04 22:04:10 +0100428};
pineafan4edb7762022-06-26 19:21:04 +0100429
pineafanbd02b4a2022-08-05 22:01:38 +0100430const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100431 const member = interaction.member as GuildMember;
PineaFan100df682023-01-02 13:26:08 +0000432 if (!member.permissions.has("ModerateMembers"))
pineafan3a02ea32022-08-11 21:35:04 +0100433 throw new Error("You do not have the *Moderate Members* permission");
pineafan63fc5e22022-08-04 22:04:10 +0100434 return true;
435};
pineafan4edb7762022-06-26 19:21:04 +0100436
437export { command };
438export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100439export { check };