/[sudobot]/trunk/src/commands/moderation/HistoryCommand.ts
ViewVC logotype

Contents of /trunk/src/commands/moderation/HistoryCommand.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 336 - (show annotations)
Mon Jul 29 17:29:36 2024 UTC (8 months, 1 week ago) by rakin
File MIME type: application/typescript
File size: 8907 byte(s)
refactor(moderation): use mongodb
1 import { BanOptions, CommandInteraction, ContextMenuInteraction, EmojiIdentifierResolvable, GuildMember, Interaction, InteractionCollector, Message, MessageActionRow, MessageButton, MessageOptions, ReplyOptions, TextChannel, User } from 'discord.js';
2 import BaseCommand from '../../utils/structures/BaseCommand';
3 import DiscordClient from '../../client/Client';
4 import CommandOptions from '../../types/CommandOptions';
5 import InteractionOptions from '../../types/InteractionOptions';
6 import MessageEmbed from '../../client/MessageEmbed';
7 import getUser from '../../utils/getUser';
8 import getMember from '../../utils/getMember';
9 import History from '../../automod/History';
10 import { fetchEmoji } from '../../utils/Emoji';
11 import Punishment from '../../models/Punishment';
12 import PunishmentType from '../../types/PunishmentType';
13
14 export default class HistoryCommand extends BaseCommand {
15 supportsInteractions: boolean = true;
16 supportsContextMenu = true;
17
18 constructor() {
19 super('history', 'moderation', ['Moderation History']);
20 }
21
22 async genEmbed(client: DiscordClient, msg: Message | Interaction, user: User, page: number = 1) {
23 const limit = 3;
24 const offset = ((page < 1 ? 1 : page) - 1) * limit;
25
26 const logs = await Punishment.find({
27 guild_id: msg.guild!.id,
28 user_id: user.id,
29 }).skip(offset).limit(limit).sort({ createdAt: -1 });
30
31 let str = '';
32
33 const maxPage = Math.ceil((await Punishment.count({
34 guild_id: msg.guild!.id,
35 user_id: user.id,
36 })) / limit);
37
38 const convert = (type: PunishmentType) => {
39 switch (type) {
40 case PunishmentType.BAN:
41 return 'Ban';
42 case PunishmentType.SOFTBAN:
43 return 'Soft Ban';
44 case PunishmentType.TEMPBAN:
45 return 'Temporary Ban';
46 case PunishmentType.SHOT:
47 return 'Shot';
48 case PunishmentType.MUTE:
49 return 'Mute';
50 case PunishmentType.HARDMUTE:
51 return 'Hardmute';
52 case PunishmentType.KICK:
53 return 'Kick';
54 case PunishmentType.WARNING:
55 return 'Warning';
56 case PunishmentType.UNBAN:
57 return 'Unban';
58 case PunishmentType.UNMUTE:
59 return 'Unmute';
60 default:
61 return "Unknown";
62 }
63 };
64
65 for await (const log of logs) {
66 str += `**Case ID**: ${log.id}\n`;
67 str += `Type: ${convert(log.type as PunishmentType)}\n`;
68 str += `Reason: ${log.reason ? (log.reason.trim() === '' ? '*No reason provided*' : log.reason) : '*No reason provided*'}\n`;
69
70 // let mod_tag;
71
72 // try {
73 // const mod = await client.users.fetch(log.get().mod_id);
74
75 // if (!mod)
76 // throw new Error();
77
78 // mod_tag = mod.tag;
79 // }
80 // catch (e) {
81 // mod_tag = log.get().mod_id;
82 // }
83
84 str += `Action Executor: ${log.mod_tag}\n`;
85 str += `Date: ${log.createdAt.toLocaleString('en-US')}\n`;
86
87 // if (log.get().type === PunishmentType.MUTE) {
88 // str += `Duration: ${(log.get().meta ? JSON.parse(log.get().meta) : {})?.time ?? '*No duration set*'}\n`;
89 // }
90
91 if (log.meta) {
92 const json = typeof log.meta === 'string' ? JSON.parse(log.meta) : log.meta;
93
94 if (Object.keys(json).length > 0) {
95 str += "Additional Attributes:\n```\n";
96
97 for (const key in json) {
98 str += `${key}: ${json[key]}\n`;
99 }
100
101 str += '\n```\n';
102 }
103 }
104
105 str += '\n';
106 }
107
108 return {
109 embeds: [
110 new MessageEmbed({
111 author: {
112 name: user.tag,
113 iconURL: user.displayAvatarURL()
114 },
115 title: 'Moderation History',
116 description: str === '' ? 'No history.' : str,
117 timestamp: new Date(),
118 })
119 ],
120 components: [
121 this.createActionRow(page, maxPage)
122 ]
123 };
124 }
125
126 createActionRow(page: number, max: number) {
127 console.log(max);
128
129 const back = new MessageButton({
130 customId: 'history-back-',
131 label: '<<',
132 style: 'PRIMARY'
133 });
134
135 const next = new MessageButton({
136 customId: 'history-next-',
137 label: '>>',
138 style: 'PRIMARY'
139 });
140
141 let nextPage = page + 1;
142 console.log(nextPage);
143
144 if (nextPage > max) {
145 nextPage = max;
146 next.setDisabled(true);
147 }
148 else {
149 next.setDisabled(false);
150 }
151
152 let prevPage = page - 1;
153 console.log(prevPage);
154
155 if (prevPage <= 0) {
156 prevPage = 1;
157 back.setDisabled(true);
158 }
159 else {
160 back.setDisabled(false);
161 }
162
163 next.setCustomId('history-next-' + nextPage);
164 back.setCustomId('history-back-' + prevPage);
165
166 return new MessageActionRow()
167 .addComponents(
168 back,
169 next
170 );
171 }
172
173 async update(client: DiscordClient, interaction: Interaction, message: Message) {
174 console.log('here');
175
176 if (interaction.isButton() && interaction.customId.startsWith('history-')) {
177 const splitted = interaction.customId.split('-');
178
179 if (splitted[2] === undefined || parseInt(splitted[2]) === NaN)
180 return;
181
182 if (splitted[1] === 'next' || splitted[1] === 'back') {
183 const options = await this.genEmbed(client, interaction, (global as any).user, parseInt(splitted[2]));
184 try {
185 await interaction.update(options);
186 }
187 catch (e) {
188 console.log(e);
189 }
190 }
191 }
192 }
193
194 async run(client: DiscordClient, msg: Message | CommandInteraction, options: CommandOptions | InteractionOptions) {
195 if (!options.isInteraction && typeof options.args[0] === 'undefined') {
196 await msg.reply({
197 embeds: [
198 new MessageEmbed()
199 .setColor('#f14a60')
200 .setDescription(`This command requires at least one argument.`)
201 ]
202 });
203
204 return;
205 }
206
207 let user: User | null | undefined;
208
209 if (options.isInteraction) {
210 user = await <User> options.options.getUser('user');
211 }
212 else {
213 try {
214 user = await getUser(client, msg as Message, options);
215
216 if (!user)
217 throw new Error();
218 }
219 catch (e) {
220 console.log(e);
221
222 await msg.reply({
223 embeds: [
224 new MessageEmbed()
225 .setColor('#f14a60')
226 .setDescription(`Invalid user given.`)
227 ]
228 });
229
230 return;
231 }
232 }
233
234 (global as any).user = user;
235
236 let message = <Message> await msg.reply(await this.genEmbed(client, msg, user));
237
238 if (msg instanceof CommandInteraction)
239 message = <Message> await msg.fetchReply();
240
241 const collector = new InteractionCollector(client, {
242 guild: msg.guild!,
243 channel: msg.channel!,
244 max: 20,
245 componentType: 'BUTTON',
246 interactionType: 'MESSAGE_COMPONENT',
247 message,
248 time: 30000,
249 filter(i) {
250 return i.isButton() && i.member?.user.id === msg.member!.user.id;
251 }
252 });
253
254 collector.on('collect', async i => {
255 await this.update(client, i, message);
256 });
257
258 collector.on('end', async () => {
259 try {
260 if (msg instanceof ContextMenuInteraction) {
261 await msg.editReply({
262 components: []
263 });
264 }
265 else {
266 await message.edit({
267 components: []
268 });
269 }
270 }
271 catch (e) {
272 console.log(e);
273 }
274 });
275 }
276 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26