blob: 1f53afb145a099f1c7d17cfafd88b3e699b8e9b1 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from '../../utils/defaults.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,
TheCodedProf4a6d5712023-01-19 15:54:40 -050015 APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +010016} from "discord.js";
PineaFan5bea7e12023-01-05 21:20:04 +000017import type { SlashCommandSubcommandBuilder } 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
PineaFan1dee28f2023-01-16 22:09:07 +000026 .setName("about")
27 // .setNameLocalizations({"ru": "info", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"})
pineafan63fc5e22022-08-04 22:04:10 +010028 .setDescription("Shows moderator information about a user")
Skyler Grey75ea9172022-08-06 10:22:23 +010029 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010030 option.setName("user").setDescription("The user to get information about").setRequired(true)
Skyler Grey75ea9172022-08-06 10:22:23 +010031 );
pineafan4edb7762022-06-26 19:21:04 +010032
pineafan3a02ea32022-08-11 21:35:04 +010033const types: Record<string, { emoji: string; text: string }> = {
Skyler Grey75ea9172022-08-06 10:22:23 +010034 warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
35 mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
36 unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
37 join: { emoji: "MEMBER.JOIN", text: "Joined" },
38 leave: { emoji: "MEMBER.LEAVE", text: "Left" },
39 kick: { emoji: "MEMBER.KICK", text: "Kicked" },
40 softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
41 ban: { emoji: "MEMBER.BAN", text: "Banned" },
42 unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
43 purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
44 nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
pineafan63fc5e22022-08-04 22:04:10 +010045};
pineafan4edb7762022-06-26 19:21:04 +010046
47function historyToString(history: HistorySchema) {
pineafan3a02ea32022-08-11 21:35:04 +010048 if (!Object.keys(types).includes(history.type)) throw new Error("Invalid history type");
49 let s = `${getEmojiByName(types[history.type]!.emoji)} ${history.amount ? history.amount + " " : ""}${
50 types[history.type]!.text
Skyler Grey11236ba2022-08-08 21:13:33 +010051 } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
Skyler Grey75ea9172022-08-06 10:22:23 +010052 if (history.moderator) {
53 s += ` by <@${history.moderator}>`;
54 }
55 if (history.reason) {
56 s += `\n**Reason:**\n> ${history.reason}`;
57 }
58 if (history.before) {
59 s += `\n**Before:**\n> ${history.before}`;
60 }
61 if (history.after) {
62 s += `\n**After:**\n> ${history.after}`;
63 }
pineafan4edb7762022-06-26 19:21:04 +010064 return s + "\n";
65}
66
pineafan4edb7762022-06-26 19:21:04 +010067class TimelineSection {
pineafan3a02ea32022-08-11 21:35:04 +010068 name: string = "";
Skyler Grey75ea9172022-08-06 10:22:23 +010069 content: { data: HistorySchema; rendered: string }[] = [];
pineafan4edb7762022-06-26 19:21:04 +010070
Skyler Grey75ea9172022-08-06 10:22:23 +010071 addContent = (content: { data: HistorySchema; rendered: string }) => {
72 this.content.push(content);
73 return this;
74 };
75 contentLength = () => {
76 return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
77 };
pineafan4edb7762022-06-26 19:21:04 +010078 generateName = () => {
pineafan3a02ea32022-08-11 21:35:04 +010079 const first = Math.round(this.content[0]!.data.occurredAt.getTime() / 1000);
80 const last = Math.round(this.content[this.content.length - 1]!.data.occurredAt.getTime() / 1000);
Skyler Grey75ea9172022-08-06 10:22:23 +010081 if (first === last) {
82 return (this.name = `<t:${first}:F>`);
83 }
84 return (this.name = `<t:${first}:F> - <t:${last}:F>`);
pineafan63fc5e22022-08-04 22:04:10 +010085 };
pineafan4edb7762022-06-26 19:21:04 +010086}
87
Skyler Grey75ea9172022-08-06 10:22:23 +010088const monthNames = [
89 "January",
90 "February",
91 "March",
92 "April",
93 "May",
94 "June",
95 "July",
96 "August",
97 "September",
98 "October",
99 "November",
100 "December"
101];
pineafan4edb7762022-06-26 19:21:04 +0100102
pineafan3a02ea32022-08-11 21:35:04 +0100103async function showHistory(member: Discord.GuildMember, interaction: CommandInteraction) {
pineafan4edb7762022-06-26 19:21:04 +0100104 let currentYear = new Date().getFullYear();
pineafan3a02ea32022-08-11 21:35:04 +0100105 let pageIndex: number | null = null;
106 let history, current: TimelineSection;
PineaFan100df682023-01-02 13:26:08 +0000107 history = await client.database.history.read(member.guild.id, member.id, currentYear);
108 history = history
109 .sort(
110 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
111 b.occurredAt.getTime() - a.occurredAt.getTime()
112 )
113 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100114 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000115 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100116 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100117 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100118 let timedOut = false;
119 let showHistorySelected = false;
120 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100121 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100122 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100123 history = history
124 .sort(
125 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
126 b.occurredAt.getTime() - a.occurredAt.getTime()
127 )
128 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100129 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100130 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 if (filteredTypes.length === 0) {
132 tempFilteredTypes = Object.keys(types);
133 }
pineafan3a02ea32022-08-11 21:35:04 +0100134 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100135 }
pineafan4edb7762022-06-26 19:21:04 +0100136 refresh = false;
137 }
pineafan63fc5e22022-08-04 22:04:10 +0100138 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100139 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100140 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100141 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100142 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100143 groups.push(current);
144 current.generateName();
145 current = new TimelineSection();
146 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100147 current.addContent({
148 data: event,
149 rendered: historyToString(event)
150 });
pineafan4edb7762022-06-26 19:21:04 +0100151 });
152 current.generateName();
153 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100154 if (pageIndex === null) {
155 pageIndex = groups.length - 1;
156 }
pineafan4edb7762022-06-26 19:21:04 +0100157 }
pineafan3a02ea32022-08-11 21:35:04 +0100158 if (pageIndex === null) pageIndex = 0;
PineaFana34d04b2023-01-03 22:05:42 +0000159 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = []
160 if (openFilterPane) components = components.concat([
161 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
PineaFan5bea7e12023-01-05 21:20:04 +0000162 new Discord.StringSelectMenuBuilder()
163 .setMinValues(1)
164 .setMaxValues(Object.keys(types).length)
165 .setCustomId("filter")
166 .setPlaceholder("Select events to show")
167 .setOptions(...Object.entries(types).map(([key, value]) => new Discord.StringSelectMenuOptionBuilder()
168 .setLabel(value.text)
169 .setValue(key)
170 .setDefault(filteredTypes.includes(key))
TheCodedProf4a6d5712023-01-19 15:54:40 -0500171 .setEmoji(getEmojiByName(value.emoji, "id") as APIMessageComponentEmoji)
PineaFan5bea7e12023-01-05 21:20:04 +0000172 )))
173 ]);
PineaFana34d04b2023-01-03 22:05:42 +0000174 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
175 new ButtonBuilder()
176 .setCustomId("prevYear")
177 .setLabel((currentYear - 1).toString())
178 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
179 .setStyle(ButtonStyle.Secondary),
180 new ButtonBuilder()
181 .setCustomId("prevPage")
182 .setLabel("Previous page")
183 .setStyle(ButtonStyle.Primary),
PineaFan5bea7e12023-01-05 21:20:04 +0000184 new ButtonBuilder()
185 .setCustomId("today")
186 .setLabel("Today")
187 .setStyle(ButtonStyle.Primary),
PineaFana34d04b2023-01-03 22:05:42 +0000188 new ButtonBuilder()
189 .setCustomId("nextPage")
190 .setLabel("Next page")
191 .setStyle(ButtonStyle.Primary)
192 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
193 new ButtonBuilder()
194 .setCustomId("nextYear")
195 .setLabel((currentYear + 1).toString())
196 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
197 .setStyle(ButtonStyle.Secondary)
198 .setDisabled(currentYear === new Date().getFullYear())
199 ])])
200 components = components.concat([new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
201 new ButtonBuilder()
202 .setLabel("Mod notes")
203 .setCustomId("modNotes")
204 .setStyle(ButtonStyle.Primary)
205 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
206 new ButtonBuilder()
207 .setLabel("Filter")
208 .setCustomId("openFilter")
209 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
210 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
211 ])])
212
Skyler Grey75ea9172022-08-06 10:22:23 +0100213 const end =
214 "\n\nJanuary " +
215 currentYear.toString() +
Skyler Grey11236ba2022-08-08 21:13:33 +0100216 pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
217 (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100218 " " +
219 currentYear.toString();
pineafan4edb7762022-06-26 19:21:04 +0100220 if (groups.length > 0) {
pineafan3a02ea32022-08-11 21:35:04 +0100221 const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
PineaFana34d04b2023-01-03 22:05:42 +0000222 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100223 embeds: [
224 new EmojiEmbed()
225 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100226 .setTitle("Moderation history for " + member.user.username)
Skyler Grey75ea9172022-08-06 10:22:23 +0100227 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100228 `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
Skyler Grey75ea9172022-08-06 10:22:23 +0100229 )
230 .setStatus("Success")
231 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000232 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 })
234 ],
235 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000236 });
pineafan4edb7762022-06-26 19:21:04 +0100237 } else {
PineaFana34d04b2023-01-03 22:05:42 +0000238 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100239 embeds: [
240 new EmojiEmbed()
241 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100242 .setTitle("Moderation history for " + member.user.username)
PineaFana34d04b2023-01-03 22:05:42 +0000243 .setDescription(`**${currentYear}**\n\n*No events*`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 .setStatus("Success")
245 .setFooter({
PineaFana34d04b2023-01-03 22:05:42 +0000246 text: openFilterPane && filteredTypes.length ? "Filters are currently enabled" : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 })
248 ],
249 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000250 })
pineafan4edb7762022-06-26 19:21:04 +0100251 }
pineafan3a02ea32022-08-11 21:35:04 +0100252 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100253 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000254 i = await m.awaitMessageComponent({
255 time: 300000,
256 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
257 });
pineafan4edb7762022-06-26 19:21:04 +0100258 } catch (e) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 interaction.editReply({
260 embeds: [
261 new EmojiEmbed()
262 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100263 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100264 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100265 .setStatus("Danger")
266 .setFooter({ text: "Message timed out" })
267 ]
268 });
Skyler Greyad002172022-08-16 18:48:26 +0100269 timedOut = true;
270 continue;
pineafan4edb7762022-06-26 19:21:04 +0100271 }
pineafan63fc5e22022-08-04 22:04:10 +0100272 i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500273 if (i.customId === "filter" && i.isStringSelectMenu()) {
274 filteredTypes = i.values;
pineafan4edb7762022-06-26 19:21:04 +0100275 pageIndex = null;
276 refresh = true;
277 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 if (i.customId === "prevYear") {
279 currentYear--;
280 pageIndex = null;
281 refresh = true;
282 }
283 if (i.customId === "nextYear") {
284 currentYear++;
285 pageIndex = null;
286 refresh = true;
287 }
pineafan4edb7762022-06-26 19:21:04 +0100288 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100289 pageIndex!--;
290 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100291 pageIndex = null;
292 currentYear--;
293 refresh = true;
294 }
pineafan4edb7762022-06-26 19:21:04 +0100295 }
296 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100297 pageIndex!++;
298 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100299 pageIndex = 0;
300 currentYear++;
301 refresh = true;
302 }
pineafan4edb7762022-06-26 19:21:04 +0100303 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100304 if (i.customId === "today") {
305 currentYear = new Date().getFullYear();
306 pageIndex = null;
307 refresh = true;
308 }
309 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100310 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100311 }
312 if (i.customId === "openFilter") {
313 openFilterPane = !openFilterPane;
314 refresh = true;
315 }
pineafan4edb7762022-06-26 19:21:04 +0100316 }
Skyler Greyad002172022-08-16 18:48:26 +0100317 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100318}
319
pineafan3a02ea32022-08-11 21:35:04 +0100320const callback = async (interaction: CommandInteraction): Promise<unknown> => {
321 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100322 const member = interaction.options.getMember("user") as Discord.GuildMember;
323 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000324 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100325 ephemeral: true,
326 fetchReply: true
327 });
pineafan4edb7762022-06-26 19:21:04 +0100328 let note;
329 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100330 let timedOut = false;
331 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100332 note = await client.database.notes.read(member.guild.id, member.id);
PineaFana34d04b2023-01-03 22:05:42 +0000333 if (firstLoad && !note) { await showHistory(member, interaction); }
pineafan4edb7762022-06-26 19:21:04 +0100334 firstLoad = false;
pineafan3a02ea32022-08-11 21:35:04 +0100335 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100336 embeds: [
337 new EmojiEmbed()
338 .setEmoji("MEMBER.JOIN")
339 .setTitle("Mod notes for " + member.user.username)
340 .setDescription(note ? note : "*No note set*")
341 .setStatus("Success")
342 ],
343 components: [
PineaFan100df682023-01-02 13:26:08 +0000344 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400345 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100346 .setLabel(`${note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400347 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100348 .setCustomId("modify")
349 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400350 new ButtonBuilder()
PineaFana34d04b2023-01-03 22:05:42 +0000351 .setLabel("Moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400352 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100353 .setCustomId("history")
354 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
355 ])
356 ]
pineafan3a02ea32022-08-11 21:35:04 +0100357 })) as Message;
358 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100359 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000360 i = await m.awaitMessageComponent({
361 time: 300000,
362 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
363 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100364 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100365 timedOut = true;
366 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100367 }
pineafan4edb7762022-06-26 19:21:04 +0100368 if (i.customId === "modify") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100369 await i.showModal(
PineaFan100df682023-01-02 13:26:08 +0000370 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100371 .setCustomId("modal")
372 .setTitle("Editing moderator note")
373 .addComponents(
PineaFana34d04b2023-01-03 22:05:42 +0000374 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
375 new Discord.TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100376 .setCustomId("note")
377 .setLabel("Note")
378 .setMaxLength(4000)
379 .setRequired(false)
PineaFana34d04b2023-01-03 22:05:42 +0000380 .setStyle(TextInputStyle.Paragraph)
381 .setValue(note ? note : " ")
Skyler Grey75ea9172022-08-06 10:22:23 +0100382 )
383 )
384 );
pineafan4edb7762022-06-26 19:21:04 +0100385 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100386 embeds: [
387 new EmojiEmbed()
388 .setTitle("Mod notes for " + member.user.username)
Skyler Grey11236ba2022-08-08 21:13:33 +0100389 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100390 .setStatus("Success")
391 .setEmoji("GUILD.TICKET.OPEN")
392 ],
393 components: [
PineaFan100df682023-01-02 13:26:08 +0000394 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400395 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100396 .setLabel("Back")
397 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400398 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100399 .setCustomId("back")
400 ])
401 ]
pineafan4edb7762022-06-26 19:21:04 +0100402 });
403 let out;
404 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100405 out = await modalInteractionCollector(
406 m,
pineafan3a02ea32022-08-11 21:35:04 +0100407 (m: Interaction) =>
408 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId === interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100409 (m) => m.customId === "modify"
410 );
411 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100412 timedOut = true;
413 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100414 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500415 if (out === null || out.isButton()) {
pineafan3a02ea32022-08-11 21:35:04 +0100416 continue;
417 } else if (out instanceof ModalSubmitInteraction) {
PineaFana34d04b2023-01-03 22:05:42 +0000418 let toAdd = out.fields.getTextInputValue("note") || null;
419 if (toAdd === " ") toAdd = null;
420 if (toAdd) toAdd = toAdd.trim();
Skyler Grey11236ba2022-08-08 21:13:33 +0100421 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100422 } else {
423 continue;
424 }
pineafan4edb7762022-06-26 19:21:04 +0100425 } else if (i.customId === "history") {
426 i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100427 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100428 }
429 }
pineafan63fc5e22022-08-04 22:04:10 +0100430};
pineafan4edb7762022-06-26 19:21:04 +0100431
pineafanbd02b4a2022-08-05 22:01:38 +0100432const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100433 const member = interaction.member as GuildMember;
PineaFan100df682023-01-02 13:26:08 +0000434 if (!member.permissions.has("ModerateMembers"))
PineaFan0d06edc2023-01-17 22:10:31 +0000435 return "You do not have the *Moderate Members* permission";
pineafan63fc5e22022-08-04 22:04:10 +0100436 return true;
437};
pineafan4edb7762022-06-26 19:21:04 +0100438
439export { command };
440export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100441export { check };