diff --git a/src/commands/timeout.ts b/src/commands/timeout.ts new file mode 100644 index 0000000..f9073aa --- /dev/null +++ b/src/commands/timeout.ts @@ -0,0 +1,70 @@ +import { CacheType, CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder } from "discord.js"; +import EmbedColours from "../constants/EmbedColours"; +import TimeLengthInput from "../helpers/TimeLengthInput"; +import { Command } from "../type/command"; + +export default class Timeout extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName("timeout") + .setDescription("Timeouts a user out, sending them a DM with the reason if possible") + .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers) + .addUserOption(option => + option + .setName('target') + .setDescription('The user') + .setRequired(true)) + .addStringOption(option => + option + .setName("length") + .setDescription("How long to timeout for? (Example: 24h, 60m)")) + .addStringOption(option => + option + .setName('reason') + .setDescription('The reason')); + } + + public override async execute(interaction: CommandInteraction) { + if (!interaction.guild || !interaction.guildId) return; + + const targetUser = interaction.options.get('target'); + const lengthInput = interaction.options.get('length'); + const reasonInput = interaction.options.get('reason'); + + if (!targetUser || !targetUser.user || !targetUser.member) { + await interaction.reply('Fields are required.'); + return; + } + + if (!lengthInput || !lengthInput.value) { + await interaction.reply('Fields are required.'); + return; + } + + const targetMember = targetUser.member as GuildMember; + const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : null; + + const logEmbed = new EmbedBuilder() + .setColor(EmbedColours.Ok) + .setTitle("Member Timed Out") + .setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``) + .addFields([ + { + name: "Moderator", + value: `<@${interaction.user.id}>`, + }, + { + name: "Reason", + value: reason || "*none*", + }, + { + name: "Until", + value: "TODO", + } + ]); + + const timeLength = new TimeLengthInput(lengthInput.value.toString()); + } +} \ No newline at end of file diff --git a/src/constants/AuditType.ts b/src/constants/AuditType.ts index 4ad8df6..0fd7325 100644 --- a/src/constants/AuditType.ts +++ b/src/constants/AuditType.ts @@ -4,4 +4,5 @@ export enum AuditType { Mute, Kick, Ban, + Timeout, } \ No newline at end of file diff --git a/src/helpers/TimeLengthInput.ts b/src/helpers/TimeLengthInput.ts new file mode 100644 index 0000000..4272a70 --- /dev/null +++ b/src/helpers/TimeLengthInput.ts @@ -0,0 +1,47 @@ +export default class TimeLengthInput { + public readonly value: string; + + constructor(input: string) { + this.value = input; + } + + public GetDays(): number { + return this.GetValue('d'); + } + + public GetHours(): number { + return this.GetValue('h'); + } + + public GetMinutes(): number { + return this.GetValue('m'); + } + + public GetSeconds(): number { + return this.GetValue('s'); + } + + public GetDateFromNow(): Date { + const now = Date.now(); + + const dateFromNow = now + + (1000 * this.GetSeconds()) + + (1000 * 60 * this.GetMinutes()) + + (1000 * 60 * 60 * this.GetHours()) + + (1000 * 60 * 60 * 24 * this.GetDays()); + + return new Date(dateFromNow); + } + + private GetValue(designation: string): number { + const valueSplit = this.value.split(' '); + + const desString = valueSplit.find(x => x.charAt(x.length) == designation); + + if (!desString) return 0; + + const desNumber = Number(desString.substring(0, desString.length - 1)); + + return desNumber; + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index a86ce96..50beeab 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -17,6 +17,7 @@ import Role from "./commands/Role/role"; import ConfigRole from "./commands/Role/config"; import Rules from "./commands/rules"; import Setup from "./commands/setup"; +import Timeout from "./commands/timeout"; import Unmute from "./commands/unmute"; import Warn from "./commands/warn"; @@ -38,6 +39,7 @@ import MessageCreate from "./events/MessageEvents/MessageCreate"; export default class Registry { public static RegisterCommands() { CoreClient.RegisterCommand("about", new About()); + CoreClient.RegisterCommand("audits", new Audits()); CoreClient.RegisterCommand("ban", new Ban()); CoreClient.RegisterCommand("bunny", new Bunny()); CoreClient.RegisterCommand("clear", new Clear()); @@ -48,10 +50,10 @@ export default class Registry { CoreClient.RegisterCommand("kick", new Kick()); CoreClient.RegisterCommand("mute", new Mute()); CoreClient.RegisterCommand("rules", new Rules()); + CoreClient.RegisterCommand("setup", new Setup()); + CoreClient.RegisterCommand("timeout", new Timeout()); CoreClient.RegisterCommand("unmute", new Unmute()); CoreClient.RegisterCommand("warn", new Warn()); - CoreClient.RegisterCommand("setup", new Setup()); - CoreClient.RegisterCommand("audits", new Audits()); CoreClient.RegisterCommand("role", new Role()); CoreClient.RegisterCommand("configrole", new ConfigRole()); diff --git a/src/vylbot.ts b/src/vylbot.ts index 16589c2..e11917d 100644 --- a/src/vylbot.ts +++ b/src/vylbot.ts @@ -2,6 +2,7 @@ import { CoreClient } from "./client/client"; import * as dotenv from "dotenv"; import registry from "./registry"; import { IntentsBitField } from "discord.js"; +import TimeLengthInput from "./helpers/TimeLengthInput"; dotenv.config(); @@ -29,4 +30,14 @@ const client = new CoreClient([ registry.RegisterCommands(); registry.RegisterEvents(); -client.start(); \ No newline at end of file +client.start(); + +const val = ''; + +const timeLength = new TimeLengthInput(val); + +console.log(`Seconds: ${timeLength.GetSeconds()}`); +console.log(`Minutes: ${timeLength.GetMinutes()}`); +console.log(`Hours: ${timeLength.GetHours()}`); +console.log(`Days: ${timeLength.GetDays()}`); +console.log(`From Now: ${timeLength.GetDateFromNow()}`); \ No newline at end of file