blob: 3328d64515eb51925ce8ca5795d1e25d4a8a4866 [file] [log] [blame]
Skyler Greyda16adf2023-03-05 10:22:12 +00001import { LoadingEmbed } from "../../utils/defaults.js";
TheCodedProfc016f9f2023-04-23 16:01:38 -04002import type { HistorySchema, FlagColors } 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,
TheCodedProfc016f9f2023-04-23 16:01:38 -040013 SlashCommandSubcommandBuilder,
14 StringSelectMenuBuilder,
15 StringSelectMenuOptionBuilder,
16 ContextMenuCommandInteraction
Skyler Grey75ea9172022-08-06 10:22:23 +010017} from "discord.js";
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
Skyler Greyda16adf2023-03-05 10:22:12 +0000109 .sort((a: { occurredAt: Date }, b: { occurredAt: Date }) => b.occurredAt.getTime() - a.occurredAt.getTime())
PineaFan100df682023-01-02 13:26:08 +0000110 .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;
Skyler Greyda16adf2023-03-05 10:22:12 +0000156 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = [];
157 if (openFilterPane)
158 components = components.concat([
159 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
160 new Discord.StringSelectMenuBuilder()
161 .setMinValues(1)
162 .setMaxValues(Object.keys(types).length)
163 .setCustomId("filter")
164 .setPlaceholder("Select events to show")
165 .setOptions(
166 ...Object.entries(types).map(([key, value]) =>
167 new Discord.StringSelectMenuOptionBuilder()
168 .setLabel(value.text)
169 .setValue(key)
170 .setDefault(filteredTypes.includes(key))
171 .setEmoji(getEmojiByName(value.emoji, "id") as APIMessageComponentEmoji)
172 )
173 )
174 )
175 ]);
176 components = components.concat([
177 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
178 new ButtonBuilder()
179 .setCustomId("prevYear")
180 .setLabel((currentYear - 1).toString())
181 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
182 .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()
186 .setCustomId("nextPage")
187 .setLabel("Next page")
188 .setStyle(ButtonStyle.Primary)
189 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
190 new ButtonBuilder()
191 .setCustomId("nextYear")
192 .setLabel((currentYear + 1).toString())
193 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
194 .setStyle(ButtonStyle.Secondary)
195 .setDisabled(currentYear === new Date().getFullYear())
196 ])
PineaFan5bea7e12023-01-05 21:20:04 +0000197 ]);
Skyler Greyda16adf2023-03-05 10:22:12 +0000198 components = components.concat([
199 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 ]);
PineaFana34d04b2023-01-03 22:05:42 +0000212
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({
Skyler Greyda16adf2023-03-05 10:22:12 +0000232 text:
233 openFilterPane && filteredTypes.length
234 ? "Filters are currently enabled"
235 : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 })
237 ],
238 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000239 });
pineafan4edb7762022-06-26 19:21:04 +0100240 } else {
PineaFana34d04b2023-01-03 22:05:42 +0000241 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100242 embeds: [
243 new EmojiEmbed()
244 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100245 .setTitle("Moderation history for " + member.user.username)
PineaFana34d04b2023-01-03 22:05:42 +0000246 .setDescription(`**${currentYear}**\n\n*No events*`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 .setStatus("Success")
248 .setFooter({
Skyler Greyda16adf2023-03-05 10:22:12 +0000249 text:
250 openFilterPane && filteredTypes.length
251 ? "Filters are currently enabled"
252 : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100253 })
254 ],
255 components: components
Skyler Greyda16adf2023-03-05 10:22:12 +0000256 });
pineafan4edb7762022-06-26 19:21:04 +0100257 }
pineafan3a02ea32022-08-11 21:35:04 +0100258 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100259 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000260 i = await m.awaitMessageComponent({
261 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000262 filter: (i) => {
263 return (
264 i.user.id === interaction.user.id &&
265 i.channel!.id === interaction.channel!.id &&
266 i.message.id === m.id
267 );
268 }
PineaFan0d06edc2023-01-17 22:10:31 +0000269 });
pineafan4edb7762022-06-26 19:21:04 +0100270 } catch (e) {
Skyler Greyf4f21c42023-03-08 14:36:29 +0000271 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 embeds: [
273 new EmojiEmbed()
274 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100275 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100276 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100277 .setStatus("Danger")
278 .setFooter({ text: "Message timed out" })
279 ]
280 });
Skyler Greyad002172022-08-16 18:48:26 +0100281 timedOut = true;
282 continue;
pineafan4edb7762022-06-26 19:21:04 +0100283 }
TheCodedProf267563a2023-01-21 17:00:57 -0500284 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500285 if (i.customId === "filter" && i.isStringSelectMenu()) {
286 filteredTypes = i.values;
pineafan4edb7762022-06-26 19:21:04 +0100287 pageIndex = null;
288 refresh = true;
289 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100290 if (i.customId === "prevYear") {
291 currentYear--;
292 pageIndex = null;
293 refresh = true;
294 }
295 if (i.customId === "nextYear") {
296 currentYear++;
297 pageIndex = null;
298 refresh = true;
299 }
pineafan4edb7762022-06-26 19:21:04 +0100300 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100301 pageIndex!--;
302 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100303 pageIndex = null;
304 currentYear--;
305 refresh = true;
306 }
pineafan4edb7762022-06-26 19:21:04 +0100307 }
308 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100309 pageIndex!++;
310 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100311 pageIndex = 0;
312 currentYear++;
313 refresh = true;
314 }
pineafan4edb7762022-06-26 19:21:04 +0100315 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100316 if (i.customId === "today") {
317 currentYear = new Date().getFullYear();
318 pageIndex = null;
319 refresh = true;
320 }
321 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100322 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100323 }
324 if (i.customId === "openFilter") {
325 openFilterPane = !openFilterPane;
326 refresh = true;
327 }
pineafan4edb7762022-06-26 19:21:04 +0100328 }
Skyler Greyad002172022-08-16 18:48:26 +0100329 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100330}
331
Skyler Greyf25451c2023-04-23 21:26:11 +0000332export const noteMenu = async (
333 member: GuildMember,
334 interaction: CommandInteraction | ContextMenuCommandInteraction
335): Promise<unknown> => {
pineafan3a02ea32022-08-11 21:35:04 +0100336 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100337 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000338 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100339 ephemeral: true,
340 fetchReply: true
341 });
pineafan4edb7762022-06-26 19:21:04 +0100342 let note;
Skyler Greyad002172022-08-16 18:48:26 +0100343 let timedOut = false;
344 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100345 note = await client.database.notes.read(member.guild.id, member.id);
TheCodedProfc016f9f2023-04-23 16:01:38 -0400346 const colors: Record<string, Discord.ColorResolvable> = {
347 none: "#424242",
348 red: "#F27878",
349 yellow: "#EDC575",
350 green: "#68D49E",
351 blue: "#6576CC",
352 purple: "#D46899",
353 gray: "#C4C4C4"
Skyler Greyf25451c2023-04-23 21:26:11 +0000354 };
pineafan3a02ea32022-08-11 21:35:04 +0100355 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100356 embeds: [
357 new EmojiEmbed()
TheCodedProfc016f9f2023-04-23 16:01:38 -0400358 .setEmoji(`ICONS.FLAGS.${(note?.flag ?? "none").toUpperCase()}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100359 .setTitle("Mod notes for " + member.user.username)
TheCodedProfc016f9f2023-04-23 16:01:38 -0400360 .setDescription(note?.note ? note.note : "*No note set*")
361 .setColor(colors[note?.flag ?? "none"]!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100362 ],
363 components: [
PineaFan100df682023-01-02 13:26:08 +0000364 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400365 new ButtonBuilder()
TheCodedProfc016f9f2023-04-23 16:01:38 -0400366 .setLabel(`${note?.note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400367 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100368 .setCustomId("modify")
369 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400370 new ButtonBuilder()
PineaFana34d04b2023-01-03 22:05:42 +0000371 .setLabel("Moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400372 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100373 .setCustomId("history")
374 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
TheCodedProfc016f9f2023-04-23 16:01:38 -0400375 ]),
376 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents([
377 new StringSelectMenuBuilder()
378 .setCustomId("flag")
379 .setPlaceholder("Select a flag")
380 .addOptions(
381 new StringSelectMenuOptionBuilder()
382 .setLabel("None")
383 .setDefault(!note?.flag)
384 .setValue("none")
385 .setDescription("Clear")
386 .setEmoji(getEmojiByName("ICONS.FLAGS.NONE", "id")),
387 new StringSelectMenuOptionBuilder()
388 .setLabel("Red")
389 .setDefault(note?.flag === "red")
390 .setValue("red")
391 .setEmoji(getEmojiByName("ICONS.FLAGS.RED", "id")),
392 new StringSelectMenuOptionBuilder()
393 .setLabel("Yellow")
394 .setDefault(note?.flag === "yellow")
395 .setValue("yellow")
396 .setEmoji(getEmojiByName("ICONS.FLAGS.YELLOW", "id")),
397 new StringSelectMenuOptionBuilder()
398 .setLabel("Green")
399 .setDefault(note?.flag === "green")
400 .setValue("green")
401 .setEmoji(getEmojiByName("ICONS.FLAGS.GREEN", "id")),
402 new StringSelectMenuOptionBuilder()
403 .setLabel("Blue")
404 .setDefault(note?.flag === "blue")
405 .setValue("blue")
406 .setEmoji(getEmojiByName("ICONS.FLAGS.BLUE", "id")),
407 new StringSelectMenuOptionBuilder()
408 .setLabel("Purple")
409 .setDefault(note?.flag === "purple")
410 .setValue("purple")
411 .setEmoji(getEmojiByName("ICONS.FLAGS.PURPLE", "id")),
412 new StringSelectMenuOptionBuilder()
413 .setLabel("Gray")
414 .setDefault(note?.flag === "gray")
415 .setValue("gray")
Skyler Greyf25451c2023-04-23 21:26:11 +0000416 .setEmoji(getEmojiByName("ICONS.FLAGS.GRAY", "id"))
TheCodedProfc016f9f2023-04-23 16:01:38 -0400417 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100418 ])
419 ]
pineafan3a02ea32022-08-11 21:35:04 +0100420 })) as Message;
421 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100422 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000423 i = await m.awaitMessageComponent({
424 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000425 filter: (i) => {
426 return (
427 i.user.id === interaction.user.id &&
428 i.channel!.id === interaction.channel!.id &&
429 i.message.id === m.id
430 );
431 }
PineaFan0d06edc2023-01-17 22:10:31 +0000432 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100433 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100434 timedOut = true;
435 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100436 }
TheCodedProfc016f9f2023-04-23 16:01:38 -0400437 if (i.isButton()) {
TheCodedProfc016f9f2023-04-23 16:01:38 -0400438 if (i.customId === "modify") {
439 await i.showModal(
440 new Discord.ModalBuilder()
441 .setCustomId("modal")
442 .setTitle("Editing moderator note")
443 .addComponents(
444 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
445 new Discord.TextInputBuilder()
446 .setCustomId("note")
447 .setLabel("Note")
448 .setMaxLength(4000)
449 .setRequired(false)
450 .setStyle(TextInputStyle.Paragraph)
451 .setValue(note?.note ? note.note : " ")
452 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100453 )
TheCodedProfc016f9f2023-04-23 16:01:38 -0400454 );
455 await interaction.editReply({
456 embeds: [
457 new EmojiEmbed()
458 .setTitle("Mod notes for " + member.user.username)
459 .setDescription("Modal opened. If you can't see it, click back and try again.")
460 .setStatus("Success")
461 .setEmoji("GUILD.TICKET.OPEN")
462 ],
463 components: [
464 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
465 new ButtonBuilder()
466 .setLabel("Back")
467 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
468 .setStyle(ButtonStyle.Primary)
469 .setCustomId("back")
470 ])
471 ]
472 });
473 let out;
474 try {
475 out = await modalInteractionCollector(m, interaction.user);
476 } catch (e) {
477 timedOut = true;
478 continue;
479 }
480 if (out === null || out.isButton()) {
481 continue;
482 } else {
483 let toAdd = out.fields.getTextInputValue("note").trim() || null;
484 if (toAdd === "") toAdd = null;
485 await client.database.notes.create(member.guild.id, member.id, toAdd);
486 }
487 } else if (i.customId === "history") {
488 await i.deferUpdate();
489 if (!(await showHistory(member, interaction))) return;
Skyler Grey75ea9172022-08-06 10:22:23 +0100490 }
TheCodedProfc016f9f2023-04-23 16:01:38 -0400491 } else if (i.isStringSelectMenu()) {
TheCodedProf267563a2023-01-21 17:00:57 -0500492 await i.deferUpdate();
TheCodedProfc016f9f2023-04-23 16:01:38 -0400493 let flag: string | null = i.values[0]!;
494 if (flag === "none") flag = null;
495 await client.database.notes.flag(member.guild.id, member.id, flag as FlagColors | null);
pineafan4edb7762022-06-26 19:21:04 +0100496 }
497 }
Skyler Greyf25451c2023-04-23 21:26:11 +0000498};
TheCodedProfc016f9f2023-04-23 16:01:38 -0400499
500const callback = async (interaction: CommandInteraction): Promise<void> => {
501 const member = interaction.options.getMember("user") as Discord.GuildMember;
502 await noteMenu(member, interaction);
pineafan63fc5e22022-08-04 22:04:10 +0100503};
pineafan4edb7762022-06-26 19:21:04 +0100504
pineafanbd02b4a2022-08-05 22:01:38 +0100505const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100506 const member = interaction.member as GuildMember;
TheCodedProfa9e3e032023-04-22 17:32:19 -0400507 if (!member.permissions.has("ManageMessages")) return "You do not have the *Manage Messages* permission";
pineafan63fc5e22022-08-04 22:04:10 +0100508 return true;
509};
pineafan4edb7762022-06-26 19:21:04 +0100510
TheCodedProfa112f612023-01-28 18:06:45 -0500511export { command, callback, check };
512export const metadata = {
Skyler Greyda16adf2023-03-05 10:22:12 +0000513 longDescription:
514 "Shows the moderation history (all previous bans, kicks, warns etc.), and moderator notes for a user.",
515 premiumOnly: true
516};