blob: 9630288c54307f5de73a5162f12cd74fd8f9cb5f [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,
10 ModalSubmitInteraction,
PineaFan100df682023-01-02 13:26:08 +000011 ButtonStyle,
PineaFana34d04b2023-01-03 22:05:42 +000012 TextInputStyle,
TheCodedProf4a6d5712023-01-19 15:54:40 -050013 APIMessageComponentEmoji,
TheCodedProff86ba092023-01-27 17:10:07 -050014 SlashCommandSubcommandBuilder
Skyler Grey75ea9172022-08-06 10:22:23 +010015} from "discord.js";
pineafan4edb7762022-06-26 19:21:04 +010016import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
17import getEmojiByName from "../../utils/getEmojiByName.js";
18import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010019import { modalInteractionCollector } from "../../utils/dualCollector.js";
20import pageIndicator from "../../utils/createPageIndicator.js";
pineafan4edb7762022-06-26 19:21:04 +010021
22const command = (builder: SlashCommandSubcommandBuilder) =>
23 builder
PineaFan1dee28f2023-01-16 22:09:07 +000024 .setName("about")
25 // .setNameLocalizations({"ru": "info", "zh-CN": "history", "zh-TW": "notes", "pt-BR": "flags"})
pineafan63fc5e22022-08-04 22:04:10 +010026 .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
Skyler Greyda16adf2023-03-05 10:22:12 +0000107 .sort((a: { occurredAt: Date }, b: { occurredAt: Date }) => b.occurredAt.getTime() - a.occurredAt.getTime())
PineaFan100df682023-01-02 13:26:08 +0000108 .reverse();
pineafan3a02ea32022-08-11 21:35:04 +0100109 let m: Message;
PineaFan100df682023-01-02 13:26:08 +0000110 let refresh = false;
pineafan3a02ea32022-08-11 21:35:04 +0100111 let filteredTypes: string[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100112 let openFilterPane = false;
Skyler Greyad002172022-08-16 18:48:26 +0100113 let timedOut = false;
114 let showHistorySelected = false;
115 while (!timedOut && !showHistorySelected) {
pineafan4edb7762022-06-26 19:21:04 +0100116 if (refresh) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100117 history = await client.database.history.read(member.guild.id, member.id, currentYear);
pineafan3a02ea32022-08-11 21:35:04 +0100118 history = history
119 .sort(
120 (a: { occurredAt: Date }, b: { occurredAt: Date }) =>
121 b.occurredAt.getTime() - a.occurredAt.getTime()
122 )
123 .reverse();
pineafan4edb7762022-06-26 19:21:04 +0100124 if (openFilterPane) {
pineafan63fc5e22022-08-04 22:04:10 +0100125 let tempFilteredTypes = filteredTypes;
Skyler Grey75ea9172022-08-06 10:22:23 +0100126 if (filteredTypes.length === 0) {
127 tempFilteredTypes = Object.keys(types);
128 }
pineafan3a02ea32022-08-11 21:35:04 +0100129 history = history.filter((h: { type: string }) => tempFilteredTypes.includes(h.type));
pineafan63fc5e22022-08-04 22:04:10 +0100130 }
pineafan4edb7762022-06-26 19:21:04 +0100131 refresh = false;
132 }
pineafan63fc5e22022-08-04 22:04:10 +0100133 const groups: TimelineSection[] = [];
pineafan4edb7762022-06-26 19:21:04 +0100134 if (history.length > 0) {
pineafan63fc5e22022-08-04 22:04:10 +0100135 current = new TimelineSection();
pineafan3a02ea32022-08-11 21:35:04 +0100136 history.forEach((event: HistorySchema) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100137 if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
pineafan4edb7762022-06-26 19:21:04 +0100138 groups.push(current);
139 current.generateName();
140 current = new TimelineSection();
141 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100142 current.addContent({
143 data: event,
144 rendered: historyToString(event)
145 });
pineafan4edb7762022-06-26 19:21:04 +0100146 });
147 current.generateName();
148 groups.push(current);
Skyler Grey75ea9172022-08-06 10:22:23 +0100149 if (pageIndex === null) {
150 pageIndex = groups.length - 1;
151 }
pineafan4edb7762022-06-26 19:21:04 +0100152 }
pineafan3a02ea32022-08-11 21:35:04 +0100153 if (pageIndex === null) pageIndex = 0;
Skyler Greyda16adf2023-03-05 10:22:12 +0000154 let components: (ActionRowBuilder<Discord.StringSelectMenuBuilder> | ActionRowBuilder<ButtonBuilder>)[] = [];
155 if (openFilterPane)
156 components = components.concat([
157 new ActionRowBuilder<Discord.StringSelectMenuBuilder>().addComponents(
158 new Discord.StringSelectMenuBuilder()
159 .setMinValues(1)
160 .setMaxValues(Object.keys(types).length)
161 .setCustomId("filter")
162 .setPlaceholder("Select events to show")
163 .setOptions(
164 ...Object.entries(types).map(([key, value]) =>
165 new Discord.StringSelectMenuOptionBuilder()
166 .setLabel(value.text)
167 .setValue(key)
168 .setDefault(filteredTypes.includes(key))
169 .setEmoji(getEmojiByName(value.emoji, "id") as APIMessageComponentEmoji)
170 )
171 )
172 )
173 ]);
174 components = components.concat([
175 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
176 new ButtonBuilder()
177 .setCustomId("prevYear")
178 .setLabel((currentYear - 1).toString())
179 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
180 .setStyle(ButtonStyle.Secondary),
181 new ButtonBuilder().setCustomId("prevPage").setLabel("Previous page").setStyle(ButtonStyle.Primary),
182 new ButtonBuilder().setCustomId("today").setLabel("Today").setStyle(ButtonStyle.Primary),
183 new ButtonBuilder()
184 .setCustomId("nextPage")
185 .setLabel("Next page")
186 .setStyle(ButtonStyle.Primary)
187 .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
188 new ButtonBuilder()
189 .setCustomId("nextYear")
190 .setLabel((currentYear + 1).toString())
191 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
192 .setStyle(ButtonStyle.Secondary)
193 .setDisabled(currentYear === new Date().getFullYear())
194 ])
PineaFan5bea7e12023-01-05 21:20:04 +0000195 ]);
Skyler Greyda16adf2023-03-05 10:22:12 +0000196 components = components.concat([
197 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
198 new ButtonBuilder()
199 .setLabel("Mod notes")
200 .setCustomId("modNotes")
201 .setStyle(ButtonStyle.Primary)
202 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
203 new ButtonBuilder()
204 .setLabel("Filter")
205 .setCustomId("openFilter")
206 .setStyle(openFilterPane ? ButtonStyle.Success : ButtonStyle.Primary)
207 .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
208 ])
209 ]);
PineaFana34d04b2023-01-03 22:05:42 +0000210
Skyler Grey75ea9172022-08-06 10:22:23 +0100211 const end =
212 "\n\nJanuary " +
213 currentYear.toString() +
Skyler Grey11236ba2022-08-08 21:13:33 +0100214 pageIndicator(Math.max(groups.length, 1), groups.length === 0 ? 1 : pageIndex) +
215 (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100216 " " +
217 currentYear.toString();
pineafan4edb7762022-06-26 19:21:04 +0100218 if (groups.length > 0) {
pineafan3a02ea32022-08-11 21:35:04 +0100219 const toRender = groups[Math.min(pageIndex, groups.length - 1)]!;
PineaFana34d04b2023-01-03 22:05:42 +0000220 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100221 embeds: [
222 new EmojiEmbed()
223 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100224 .setTitle("Moderation history for " + member.user.username)
Skyler Grey75ea9172022-08-06 10:22:23 +0100225 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100226 `**${toRender.name}**\n\n` + toRender.content.map((c) => c.rendered).join("\n") + end
Skyler Grey75ea9172022-08-06 10:22:23 +0100227 )
228 .setStatus("Success")
229 .setFooter({
Skyler Greyda16adf2023-03-05 10:22:12 +0000230 text:
231 openFilterPane && filteredTypes.length
232 ? "Filters are currently enabled"
233 : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100234 })
235 ],
236 components: components
PineaFana34d04b2023-01-03 22:05:42 +0000237 });
pineafan4edb7762022-06-26 19:21:04 +0100238 } else {
PineaFana34d04b2023-01-03 22:05:42 +0000239 m = await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100240 embeds: [
241 new EmojiEmbed()
242 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100243 .setTitle("Moderation history for " + member.user.username)
PineaFana34d04b2023-01-03 22:05:42 +0000244 .setDescription(`**${currentYear}**\n\n*No events*`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100245 .setStatus("Success")
246 .setFooter({
Skyler Greyda16adf2023-03-05 10:22:12 +0000247 text:
248 openFilterPane && filteredTypes.length
249 ? "Filters are currently enabled"
250 : "No filters selected"
Skyler Grey75ea9172022-08-06 10:22:23 +0100251 })
252 ],
253 components: components
Skyler Greyda16adf2023-03-05 10:22:12 +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 {
PineaFan0d06edc2023-01-17 22:10:31 +0000258 i = await m.awaitMessageComponent({
259 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000260 filter: (i) => {
261 return (
262 i.user.id === interaction.user.id &&
263 i.channel!.id === interaction.channel!.id &&
264 i.message.id === m.id
265 );
266 }
PineaFan0d06edc2023-01-17 22:10:31 +0000267 });
pineafan4edb7762022-06-26 19:21:04 +0100268 } catch (e) {
Skyler Greyf4f21c42023-03-08 14:36:29 +0000269 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100270 embeds: [
271 new EmojiEmbed()
272 .setEmoji("MEMBER.JOIN")
Skyler Grey11236ba2022-08-08 21:13:33 +0100273 .setTitle("Moderation history for " + member.user.username)
pineafan3a02ea32022-08-11 21:35:04 +0100274 .setDescription(m.embeds[0]!.description!)
Skyler Grey75ea9172022-08-06 10:22:23 +0100275 .setStatus("Danger")
276 .setFooter({ text: "Message timed out" })
277 ]
278 });
Skyler Greyad002172022-08-16 18:48:26 +0100279 timedOut = true;
280 continue;
pineafan4edb7762022-06-26 19:21:04 +0100281 }
TheCodedProf267563a2023-01-21 17:00:57 -0500282 await i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500283 if (i.customId === "filter" && i.isStringSelectMenu()) {
284 filteredTypes = i.values;
pineafan4edb7762022-06-26 19:21:04 +0100285 pageIndex = null;
286 refresh = true;
287 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100288 if (i.customId === "prevYear") {
289 currentYear--;
290 pageIndex = null;
291 refresh = true;
292 }
293 if (i.customId === "nextYear") {
294 currentYear++;
295 pageIndex = null;
296 refresh = true;
297 }
pineafan4edb7762022-06-26 19:21:04 +0100298 if (i.customId === "prevPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100299 pageIndex!--;
300 if (pageIndex! < 0) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100301 pageIndex = null;
302 currentYear--;
303 refresh = true;
304 }
pineafan4edb7762022-06-26 19:21:04 +0100305 }
306 if (i.customId === "nextPage") {
pineafan3a02ea32022-08-11 21:35:04 +0100307 pageIndex!++;
308 if (pageIndex! >= groups.length) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100309 pageIndex = 0;
310 currentYear++;
311 refresh = true;
312 }
pineafan4edb7762022-06-26 19:21:04 +0100313 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100314 if (i.customId === "today") {
315 currentYear = new Date().getFullYear();
316 pageIndex = null;
317 refresh = true;
318 }
319 if (i.customId === "modNotes") {
Skyler Greyad002172022-08-16 18:48:26 +0100320 showHistorySelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100321 }
322 if (i.customId === "openFilter") {
323 openFilterPane = !openFilterPane;
324 refresh = true;
325 }
pineafan4edb7762022-06-26 19:21:04 +0100326 }
Skyler Greyad002172022-08-16 18:48:26 +0100327 return timedOut ? 0 : 1;
pineafan4edb7762022-06-26 19:21:04 +0100328}
329
pineafan3a02ea32022-08-11 21:35:04 +0100330const callback = async (interaction: CommandInteraction): Promise<unknown> => {
331 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 const member = interaction.options.getMember("user") as Discord.GuildMember;
333 await interaction.reply({
PineaFana34d04b2023-01-03 22:05:42 +0000334 embeds: LoadingEmbed,
Skyler Grey75ea9172022-08-06 10:22:23 +0100335 ephemeral: true,
336 fetchReply: true
337 });
pineafan4edb7762022-06-26 19:21:04 +0100338 let note;
339 let firstLoad = true;
Skyler Greyad002172022-08-16 18:48:26 +0100340 let timedOut = false;
341 while (!timedOut) {
pineafan4edb7762022-06-26 19:21:04 +0100342 note = await client.database.notes.read(member.guild.id, member.id);
Skyler Greyda16adf2023-03-05 10:22:12 +0000343 if (firstLoad && !note) {
344 await showHistory(member, interaction);
345 }
pineafan4edb7762022-06-26 19:21:04 +0100346 firstLoad = false;
pineafan3a02ea32022-08-11 21:35:04 +0100347 m = (await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100348 embeds: [
349 new EmojiEmbed()
350 .setEmoji("MEMBER.JOIN")
351 .setTitle("Mod notes for " + member.user.username)
352 .setDescription(note ? note : "*No note set*")
353 .setStatus("Success")
354 ],
355 components: [
PineaFan100df682023-01-02 13:26:08 +0000356 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400357 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100358 .setLabel(`${note ? "Modify" : "Create"} note`)
TheCodedProf21c08592022-09-13 14:14:43 -0400359 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100360 .setCustomId("modify")
361 .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
TheCodedProf21c08592022-09-13 14:14:43 -0400362 new ButtonBuilder()
PineaFana34d04b2023-01-03 22:05:42 +0000363 .setLabel("Moderation history")
TheCodedProf21c08592022-09-13 14:14:43 -0400364 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 .setCustomId("history")
366 .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
367 ])
368 ]
pineafan3a02ea32022-08-11 21:35:04 +0100369 })) as Message;
370 let i: MessageComponentInteraction;
pineafan4edb7762022-06-26 19:21:04 +0100371 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000372 i = await m.awaitMessageComponent({
373 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000374 filter: (i) => {
375 return (
376 i.user.id === interaction.user.id &&
377 i.channel!.id === interaction.channel!.id &&
378 i.message.id === m.id
379 );
380 }
PineaFan0d06edc2023-01-17 22:10:31 +0000381 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100382 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100383 timedOut = true;
384 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100385 }
pineafan4edb7762022-06-26 19:21:04 +0100386 if (i.customId === "modify") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100387 await i.showModal(
PineaFan100df682023-01-02 13:26:08 +0000388 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100389 .setCustomId("modal")
390 .setTitle("Editing moderator note")
391 .addComponents(
PineaFana34d04b2023-01-03 22:05:42 +0000392 new ActionRowBuilder<Discord.TextInputBuilder>().addComponents(
393 new Discord.TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100394 .setCustomId("note")
395 .setLabel("Note")
396 .setMaxLength(4000)
397 .setRequired(false)
PineaFana34d04b2023-01-03 22:05:42 +0000398 .setStyle(TextInputStyle.Paragraph)
399 .setValue(note ? note : " ")
Skyler Grey75ea9172022-08-06 10:22:23 +0100400 )
401 )
402 );
pineafan4edb7762022-06-26 19:21:04 +0100403 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100404 embeds: [
405 new EmojiEmbed()
406 .setTitle("Mod notes for " + member.user.username)
Skyler Grey11236ba2022-08-08 21:13:33 +0100407 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100408 .setStatus("Success")
409 .setEmoji("GUILD.TICKET.OPEN")
410 ],
411 components: [
PineaFan100df682023-01-02 13:26:08 +0000412 new ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400413 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100414 .setLabel("Back")
415 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400416 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100417 .setCustomId("back")
418 ])
419 ]
pineafan4edb7762022-06-26 19:21:04 +0100420 });
421 let out;
422 try {
TheCodedProf01cba762023-02-18 15:55:05 -0500423 out = await modalInteractionCollector(m, interaction.user);
Skyler Grey75ea9172022-08-06 10:22:23 +0100424 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100425 timedOut = true;
426 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100427 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500428 if (out === null || out.isButton()) {
pineafan3a02ea32022-08-11 21:35:04 +0100429 continue;
430 } else if (out instanceof ModalSubmitInteraction) {
PineaFana34d04b2023-01-03 22:05:42 +0000431 let toAdd = out.fields.getTextInputValue("note") || null;
432 if (toAdd === " ") toAdd = null;
433 if (toAdd) toAdd = toAdd.trim();
Skyler Grey11236ba2022-08-08 21:13:33 +0100434 await client.database.notes.create(member.guild.id, member.id, toAdd);
Skyler Grey75ea9172022-08-06 10:22:23 +0100435 } else {
436 continue;
437 }
pineafan4edb7762022-06-26 19:21:04 +0100438 } else if (i.customId === "history") {
TheCodedProf267563a2023-01-21 17:00:57 -0500439 await i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100440 if (!(await showHistory(member, interaction))) return;
pineafan4edb7762022-06-26 19:21:04 +0100441 }
442 }
pineafan63fc5e22022-08-04 22:04:10 +0100443};
pineafan4edb7762022-06-26 19:21:04 +0100444
pineafanbd02b4a2022-08-05 22:01:38 +0100445const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100446 const member = interaction.member as GuildMember;
TheCodedProfa9e3e032023-04-22 17:32:19 -0400447 if (!member.permissions.has("ManageMessages")) return "You do not have the *Manage Messages* permission";
pineafan63fc5e22022-08-04 22:04:10 +0100448 return true;
449};
pineafan4edb7762022-06-26 19:21:04 +0100450
TheCodedProfa112f612023-01-28 18:06:45 -0500451export { command, callback, check };
452export const metadata = {
Skyler Greyda16adf2023-03-05 10:22:12 +0000453 longDescription:
454 "Shows the moderation history (all previous bans, kicks, warns etc.), and moderator notes for a user.",
455 premiumOnly: true
456};