blob: fc656ff5ee6f555f593ad0e78f347963a6511187 [file] [log] [blame]
Skyler Greyda16adf2023-03-05 10:22:12 +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 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04007 ActionRowBuilder,
8 ButtonBuilder,
pineafan3a02ea32022-08-11 21:35:04 +01009 MessageComponentInteraction,
PineaFan100df682023-01-02 13:26:08 +000010 ButtonStyle,
PineaFana34d04b2023-01-03 22:05:42 +000011 TextInputStyle,
TheCodedProf4a6d5712023-01-19 15:54:40 -050012 APIMessageComponentEmoji,
TheCodedProff86ba092023-01-27 17:10:07 -050013 SlashCommandSubcommandBuilder
Skyler Grey75ea9172022-08-06 10:22:23 +010014} from "discord.js";
pineafan4edb7762022-06-26 19:21:04 +010015import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
16import getEmojiByName from "../../utils/getEmojiByName.js";
17import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010018import { modalInteractionCollector } from "../../utils/dualCollector.js";
19import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4edb7762022-06-26 19:21:04 +010020
21const command = (builder: SlashCommandSubcommandBuilder) =>
22 builder
PineaFan1dee28f2023-01-16 22:09:07 +000023 .setName("about")
24 // .setNameLocalizations({"ru": "info", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"})
pineafan63fc5e22022-08-04 22:04:10 +010025 .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
Skyler Greyda16adf2023-03-05 10:22:12 +0000106 .sort((a: { occurredAt: Date }, b: { occurredAt: Date }) => b.occurredAt.getTime() - a.occurredAt.getTime())
PineaFan100df682023-01-02 13:26:08 +0000107 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100108 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000109 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100110 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100111 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100112 let timedOut = false;
113 let showHistorySelected = false;
114 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100115 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100116 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100117 history = history
118 .sort(
119 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
120 b.occurredAt.getTime() - a.occurredAt.getTime()
121 )
122 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100123 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100124 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100125 if (filteredTypes.length === 0) {
126 tempFilteredTypes = Object.keys(types);
127 }
pineafan3a02ea32022-08-11 21:35:04 +0100128 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100129 }
pineafan4edb7762022-06-26 19:21:04 +0100130 refresh = false;
131 }
pineafan63fc5e22022-08-04 22:04:10 +0100132 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100133 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100134 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100135 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100136 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100137 groups.push(current);
138 current.generateName();
139 current = new TimelineSection();
140 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 current.addContent({
142 data: event,
143 rendered: historyToString(event)
144 });
pineafan4edb7762022-06-26 19:21:04 +0100145 });
146 current.generateName();
147 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100148 if (pageIndex === null) {
149 pageIndex = groups.length - 1;
150 }
pineafan4edb7762022-06-26 19:21:04 +0100151 }
pineafan3a02ea32022-08-11 21:35:04 +0100152 if (pageIndex === null) pageIndex = 0;
Skyler Greyda16adf2023-03-05 10:22:12 +0000153 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = [];
154 if (openFilterPane)
155 components = components.concat([
156 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
157 new Discord.StringSelectMenuBuilder()
158 .setMinValues(1)
159 .setMaxValues(Object.keys(types).length)
160 .setCustomId("filter")
161 .setPlaceholder("Select events to show")
162 .setOptions(
163 ...Object.entries(types).map(([key, value]) =>
164 new Discord.StringSelectMenuOptionBuilder()
165 .setLabel(value.text)
166 .setValue(key)
167 .setDefault(filteredTypes.includes(key))
168 .setEmoji(getEmojiByName(value.emoji, "id") as APIMessageComponentEmoji)
169 )
170 )
171 )
172 ]);
173 components = components.concat([
174 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().setCustomId("prevPage").setLabel("Previous page").setStyle(ButtonStyle.Primary),
181 new ButtonBuilder().setCustomId("today").setLabel("Today").setStyle(ButtonStyle.Primary),
182 new ButtonBuilder()
183 .setCustomId("nextPage")
184 .setLabel("Next page")
185 .setStyle(ButtonStyle.Primary)
186 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
187 new ButtonBuilder()
188 .setCustomId("nextYear")
189 .setLabel((currentYear + 1).toString())
190 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
191 .setStyle(ButtonStyle.Secondary)
192 .setDisabled(currentYear === new Date().getFullYear())
193 ])
PineaFan5bea7e12023-01-05 21:20:04 +0000194 ]);
Skyler Greyda16adf2023-03-05 10:22:12 +0000195 components = components.concat([
196 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
197 new ButtonBuilder()
198 .setLabel("Mod notes")
199 .setCustomId("modNotes")
200 .setStyle(ButtonStyle.Primary)
201 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
202 new ButtonBuilder()
203 .setLabel("Filter")
204 .setCustomId("openFilter")
205 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
206 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
207 ])
208 ]);
PineaFana34d04b2023-01-03 22:05:42 +0000209
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)]!;
PineaFana34d04b2023-01-03 22:05:42 +0000219 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 Greyda16adf2023-03-05 10:22:12 +0000229 text:
230 openFilterPane && filteredTypes.length
231 ? "Filters are currently enabled"
232 : "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({
Skyler Greyda16adf2023-03-05 10:22:12 +0000246 text:
247 openFilterPane && filteredTypes.length
248 ? "Filters are currently enabled"
249 : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100250 })
251 ],
252 components: components
Skyler Greyda16adf2023-03-05 10:22:12 +0000253 });
pineafan4edb7762022-06-26 19:21:04 +0100254 }
pineafan3a02ea32022-08-11 21:35:04 +0100255 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100256 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000257 i = await m.awaitMessageComponent({
258 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000259 filter: (i) => {
260 return (
261 i.user.id === interaction.user.id &&
262 i.channel!.id === interaction.channel!.id &&
263 i.message.id === m.id
264 );
265 }
PineaFan0d06edc2023-01-17 22:10:31 +0000266 });
pineafan4edb7762022-06-26 19:21:04 +0100267 } catch (e) {
Skyler Greyf4f21c42023-03-08 14:36:29 +0000268 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100269 embeds: [
270 new EmojiEmbed()
271 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100272 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100273 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100274 .setStatus("Danger")
275 .setFooter({ text: "Message timed out" })
276 ]
277 });
Skyler Greyad002172022-08-16 18:48:26 +0100278 timedOut = true;
279 continue;
pineafan4edb7762022-06-26 19:21:04 +0100280 }
TheCodedProf267563a2023-01-21 17:00:57 -0500281 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500282 if (i.customId === "filter" && i.isStringSelectMenu()) {
283 filteredTypes = i.values;
pineafan4edb7762022-06-26 19:21:04 +0100284 pageIndex = null;
285 refresh = true;
286 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100287 if (i.customId === "prevYear") {
288 currentYear--;
289 pageIndex = null;
290 refresh = true;
291 }
292 if (i.customId === "nextYear") {
293 currentYear++;
294 pageIndex = null;
295 refresh = true;
296 }
pineafan4edb7762022-06-26 19:21:04 +0100297 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100298 pageIndex!--;
299 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100300 pageIndex = null;
301 currentYear--;
302 refresh = true;
303 }
pineafan4edb7762022-06-26 19:21:04 +0100304 }
305 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100306 pageIndex!++;
307 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100308 pageIndex = 0;
309 currentYear++;
310 refresh = true;
311 }
pineafan4edb7762022-06-26 19:21:04 +0100312 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100313 if (i.customId === "today") {
314 currentYear = new Date().getFullYear();
315 pageIndex = null;
316 refresh = true;
317 }
318 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100319 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100320 }
321 if (i.customId === "openFilter") {
322 openFilterPane = !openFilterPane;
323 refresh = true;
324 }
pineafan4edb7762022-06-26 19:21:04 +0100325 }
Skyler Greyad002172022-08-16 18:48:26 +0100326 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100327}
328
pineafan3a02ea32022-08-11 21:35:04 +0100329const callback = async (interaction: CommandInteraction): Promise<unknown> => {
330 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100331 const member = interaction.options.getMember("user") as Discord.GuildMember;
332 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000333 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100334 ephemeral: true,
335 fetchReply: true
336 });
pineafan4edb7762022-06-26 19:21:04 +0100337 let note;
338 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100339 let timedOut = false;
340 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100341 note = await client.database.notes.read(member.guild.id, member.id);
Skyler Greyda16adf2023-03-05 10:22:12 +0000342 if (firstLoad && !note) {
343 await showHistory(member, interaction);
344 }
pineafan4edb7762022-06-26 19:21:04 +0100345 firstLoad = false;
pineafan3a02ea32022-08-11 21:35:04 +0100346 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100347 embeds: [
348 new EmojiEmbed()
349 .setEmoji("MEMBER.JOIN")
350 .setTitle("Mod notes for " + member.user.username)
351 .setDescription(note ? note : "*No note set*")
352 .setStatus("Success")
353 ],
354 components: [
PineaFan100df682023-01-02 13:26:08 +0000355 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400356 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100357 .setLabel(`${note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400358 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100359 .setCustomId("modify")
360 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400361 new ButtonBuilder()
PineaFana34d04b2023-01-03 22:05:42 +0000362 .setLabel("Moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400363 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100364 .setCustomId("history")
365 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
366 ])
367 ]
pineafan3a02ea32022-08-11 21:35:04 +0100368 })) as Message;
369 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100370 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000371 i = await m.awaitMessageComponent({
372 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000373 filter: (i) => {
374 return (
375 i.user.id === interaction.user.id &&
376 i.channel!.id === interaction.channel!.id &&
377 i.message.id === m.id
378 );
379 }
PineaFan0d06edc2023-01-17 22:10:31 +0000380 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100381 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100382 timedOut = true;
383 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100384 }
pineafan4edb7762022-06-26 19:21:04 +0100385 if (i.customId === "modify") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100386 await i.showModal(
PineaFan100df682023-01-02 13:26:08 +0000387 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100388 .setCustomId("modal")
389 .setTitle("Editing moderator note")
390 .addComponents(
PineaFana34d04b2023-01-03 22:05:42 +0000391 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
392 new Discord.TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100393 .setCustomId("note")
394 .setLabel("Note")
395 .setMaxLength(4000)
396 .setRequired(false)
PineaFana34d04b2023-01-03 22:05:42 +0000397 .setStyle(TextInputStyle.Paragraph)
398 .setValue(note ? note : " ")
Skyler Grey75ea9172022-08-06 10:22:23 +0100399 )
400 )
401 );
pineafan4edb7762022-06-26 19:21:04 +0100402 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100403 embeds: [
404 new EmojiEmbed()
405 .setTitle("Mod notes for " + member.user.username)
Skyler Grey11236ba2022-08-08 21:13:33 +0100406 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100407 .setStatus("Success")
408 .setEmoji("GUILD.TICKET.OPEN")
409 ],
410 components: [
PineaFan100df682023-01-02 13:26:08 +0000411 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400412 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100413 .setLabel("Back")
414 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400415 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100416 .setCustomId("back")
417 ])
418 ]
pineafan4edb7762022-06-26 19:21:04 +0100419 });
420 let out;
421 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500422 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100423 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100424 timedOut = true;
425 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100426 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500427 if (out === null || out.isButton()) {
pineafan3a02ea32022-08-11 21:35:04 +0100428 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100429 } else {
TheCodedProfe49649c2023-04-23 14:31:00 -0400430 let toAdd = out.fields.getTextInputValue("note").trim() || null;
431 if (toAdd === "") toAdd = null;
432 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100433 }
pineafan4edb7762022-06-26 19:21:04 +0100434 } else if (i.customId === "history") {
TheCodedProf267563a2023-01-21 17:00:57 -0500435 await i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100436 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100437 }
438 }
pineafan63fc5e22022-08-04 22:04:10 +0100439};
pineafan4edb7762022-06-26 19:21:04 +0100440
pineafanbd02b4a2022-08-05 22:01:38 +0100441const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100442 const member = interaction.member as GuildMember;
TheCodedProfa9e3e032023-04-22 17:32:19 -0400443 if (!member.permissions.has("ManageMessages")) return "You do not have the *Manage Messages* permission";
pineafan63fc5e22022-08-04 22:04:10 +0100444 return true;
445};
pineafan4edb7762022-06-26 19:21:04 +0100446
TheCodedProfa112f612023-01-28 18:06:45 -0500447export { command, callback, check };
448export const metadata = {
Skyler Greyda16adf2023-03-05 10:22:12 +0000449 longDescription:
450 "Shows the moderation history (all previous bans, kicks, warns etc.), and moderator notes for a user.",
451 premiumOnly: true
452};