diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts index 0000844..b91f065 100644 --- a/src/commands/mod/slowmode.ts +++ b/src/commands/mod/slowmode.ts @@ -1,53 +1,57 @@ -import { CommandInteraction } from "discord.js"; +import humanizeDuration from 'humanize-duration'; +import { CommandInteraction, GuildMember, TextChannel } from "discord.js"; import { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import { WrappedCheck } from "jshaiku"; -import humanizeDuration from 'humanize-duration'; +import keyValueList from "../../utils/generateKeyValueList.js"; +import confirmationMessage from "../../utils/confirmationMessage.js"; +import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js"; const command = (builder: SlashCommandSubcommandBuilder) => builder .setName("slowmode") .setDescription("Manages slowmode in a channel") - .addIntegerOption(option => option.setName("seconds").setDescription("The seconds between messages").setRequired(false)) - .addIntegerOption(option => option.setName("minutes").setDescription("The minutes between messages").setRequired(false)) - .addIntegerOption(option => option.setName("hours").setDescription("The hours between messages").setRequired(false)) - -const callback = (interaction: CommandInteraction) => { - let seconds = interaction.option.getInteger("seconds") - let minutes = interaction.option.getInteger("minutes") - let hours = interaction.option.getInteger("hours") - let totalTime = seconds + (minutes * 60) + (hours * 60 * 60) + .addStringOption(option => option.setName("time").setDescription("The delay between messages").setRequired(false).addChoices([ + ["Off", "0"], + ["5 seconds", "5"], ["10 seconds", "10"], ["15 seconds", "15"], ["30 seconds", "30"], + ["1 minute", "60"], ["2 minutes", "120"], ["5 minutes", "300"], ["10 minutes", "600"], + ["15 minutes", "900"], ["30 minutes", "1800"], + ["1 hour", "3600"], ["2 hours", "7200"], ["6 hours", "21600"] + ])) +const callback = async (interaction: CommandInteraction) => { + let time = parseInt(interaction.options.getString("time") ?? "0"); + if (time === 0 && (interaction.channel as TextChannel).rateLimitPerUser === 0) { time = 10 } let confirmation = await new confirmationMessage(interaction) - .setEmoji("PUNISH.SLOWMODE.RED") + .setEmoji("CHANNEL.SLOWMODE.RED") .setTitle("Slowmode") .setDescription(keyValueList({ - "delay": `${totalTime ? humanizeDuration(totalTime * 1000) : "*No delay*"}` + "time": time ? humanizeDuration(time * 1000, { round: true }) : "No delay", }) - + `Are you sure you want to enable slowmode in this channel?`) + + `Are you sure you want to set the slowmode in this channel?`) .setColor("Danger") // pluralize("day", interaction.options.getInteger("delete")) // const pluralize = (word: string, count: number) => { return count === 1 ? word : word + "s" } .send() if (confirmation.success) { try { - await interaction.setRateLimitPerUser(totalTime, "Nucleus slowmode") - } catch { - return await interaction.editReply({embeds: [new generateEmojiEmbed() - .setEmoji("PUNISH.SLOWMODE.RED") + (interaction.channel as TextChannel).setRateLimitPerUser(time) + } catch (e) { + await interaction.editReply({embeds: [new generateEmojiEmbed() + .setEmoji("CHANNEL.SLOWMODE.RED") .setTitle(`Slowmode`) - .setDescription("Something went wrong and the slowmode could not be set.") + .setDescription("An error occurred while setting the slowmode") .setStatus("Danger") ], components: []}) } await interaction.editReply({embeds: [new generateEmojiEmbed() - .setEmoji("PUNISH.NICKNAME.GREEN") + .setEmoji(`CHANNEL.SLOWMODE.GREEN`) .setTitle(`Slowmode`) .setDescription("The channel slowmode was set successfully") .setStatus("Success") ], components: []}) } else { await interaction.editReply({embeds: [new generateEmojiEmbed() - .setEmoji("PUNISH.SLOWMODE.GREEN") + .setEmoji("CHANNEL.SLOWMODE.GREEN") .setTitle(`Slowmode`) .setDescription("No changes were made") .setStatus("Success") @@ -57,12 +61,9 @@ const callback = (interaction: CommandInteraction) => { const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => { let member = (interaction.member as GuildMember) - let me = (interaction.guild.me as GuildMember) - // Check if Nucleus can edit the channel - if (! me.permission.has("MANAGE_CHANNELS")) throw "I do not have permission to edit this channel" - // Allow the owner to set any channel - if (member.id == interaction.guild.ownerId) return true - // Check if the user has manage_channels permission + // Check if Nucleus can set the slowmode + if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the `manage_channels` permission"; + // Check if the user has manage_channel permission if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the `manage_channels` permission"; // Allow slowmode return true diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts index f8fedda..29d3bef 100644 --- a/src/commands/mod/softban.ts +++ b/src/commands/mod/softban.ts @@ -102,7 +102,7 @@ const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => { // Do not allow softbanning Nucleus if (member.id == me.id) throw "I cannot softban myself" // Allow the owner to ban anyone - if (member.id == ownerId) return true + if (member.id == interaction.guild.ownerId) return true // Check if the user has ban_members permission if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission"; // Check if the user is below on the role list diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts index b78f458..bdd73c4 100644 --- a/src/commands/user/about.ts +++ b/src/commands/user/about.ts @@ -160,6 +160,7 @@ const callback = async (interaction: CommandInteraction) => { let m m = await interaction.reply({embeds: [new generateEmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true}); let page = 0 + let breakReason = "" while (true) { let em = new Discord.MessageEmbed(embeds[page].embed) em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page)); @@ -209,7 +210,7 @@ const callback = async (interaction: CommandInteraction) => { let i try { i = await m.awaitMessageComponent({time: 600000}); - } catch { break } + } catch { breakReason = "Message timed out"; break } i.deferUpdate() if (i.component.customId == "left") { if (page > 0) page--; @@ -220,15 +221,19 @@ const callback = async (interaction: CommandInteraction) => { } else if (i.component.customId == "select") { selectPaneOpen = !selectPaneOpen; } else if (i.component.customId == "close") { + breakReason = "Message closed"; break; } else if (i.component.customId == "page") { page = parseInt(i.values[0]); selectPaneOpen = false; } else { + breakReason = "Message closed"; break; } } - await interaction.editReply({embeds: [m.embeds[0]], components: [new MessageActionRow().addComponents([ + let em = new Discord.MessageEmbed(embeds[page].embed) + em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | " + breakReason); + await interaction.editReply({embeds: [em], components: [new MessageActionRow().addComponents([ new MessageButton() .setEmoji(getEmojiByName("CONTROL.LEFT", "id")) .setStyle("SECONDARY") @@ -247,7 +252,7 @@ const callback = async (interaction: CommandInteraction) => { new MessageButton() .setEmoji(getEmojiByName("CONTROL.CROSS", "id")) .setCustomId("close") - .setStyle("PRIMARY") + .setStyle("DANGER") .setDisabled(true) ])]}) } diff --git a/src/config/emojis.json b/src/config/emojis.json index 12741f2..8264198 100644 --- a/src/config/emojis.json +++ b/src/config/emojis.json @@ -39,6 +39,7 @@ "DOWN": "963409199549796352", "DOWNLOAD": "947959513032585236", "TICKET": "973253514488860683", + "MENU": "976580327835320410", "PILL": { "TICK": "753314339082993832", "CROSS": "753314339389309100" diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts index 8281ead..3226a43 100644 --- a/src/utils/confirmationMessage.ts +++ b/src/utils/confirmationMessage.ts @@ -31,6 +31,7 @@ class confirmationMessage { setEmoji(emoji: string) { this.emoji = emoji; return this } setDescription(description: string) { this.description = description; return this } setColor(color: string) { this.color = color; return this } + setInverted(inverted: boolean) { this.inverted = inverted; return this } addCustomCallback(title: string, disabled: boolean, callback: () => any, callbackClicked: string) { this.customButtonTitle = title; this.customButtonDisabled = disabled;