diff --git a/.gitignore b/.gitignore index 5c041d8b..d41b676d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ # commands.md **/commands.md +# Data +/.data + # Clips /clips diff --git a/base/Guild.js b/base/Guild.js index 0847c62e..b2a41584 100644 --- a/base/Guild.js +++ b/base/Guild.js @@ -41,5 +41,4 @@ module.exports = mongoose.model("Guild", new Schema({ reports: false }}, casesCount: { type: Number, default: 0 }, - autoDeleteModCommands: { type: Boolean, default: false }, })); \ No newline at end of file diff --git a/commands/Administration/config.js b/commands/Administration/config.js index f9d4e03d..59188106 100644 --- a/commands/Administration/config.js +++ b/commands/Administration/config.js @@ -78,10 +78,6 @@ class Config extends BaseCommand { channels: guildData.plugins.automod.ignored.map(ch => ` ${ch}`) }) : interaction.translate("common:DISABLED") }, - { - name: interaction.translate("administration/config:AUTODELETEMOD"), - value: guildData.autoDeleteModCommands ? interaction.translate("administration/config:AUTODELETEMOD_ENABLED") : interaction.translate("administration/config:AUTODELETEMOD_DISABLED") - }, { name: interaction.translate("administration/config:SPECIAL_CHANNELS"), value: interaction.translate("administration/config:NEWS", { diff --git a/commands/Administration/deletemod.js b/commands/Administration/deletemod.js deleted file mode 100644 index e062ffc2..00000000 --- a/commands/Administration/deletemod.js +++ /dev/null @@ -1,45 +0,0 @@ -const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js"); -const BaseCommand = require("../../base/BaseCommand"); - -class Deletemod extends BaseCommand { - /** - * - * @param {import("../../base/JaBa")} client - */ - constructor(client) { - super({ - command: new SlashCommandBuilder() - .setName("deletemod") - .setDescription(client.translate("administration/deletemod:DESCRIPTION")) - .setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild) - .addBooleanOption(option => option.setName("state") - .setDescription(client.translate("common:STATE")) - .setRequired(true)), - aliases: [], - dirname: __dirname, - guildOnly: true - }); - } - /** - * - * @param {import("../../base/JaBa")} client - */ - async onLoad() { - //... - } - /** - * - * @param {import("../../base/JaBa")} client - * @param {import("discord.js").ChatInputCommandInteraction} interaction - * @param {Object} data - */ - async execute(client, interaction, data) { - const state = interaction.options.getBoolean("state"); - - data.guildData.autoDeleteModCommands = state; - await data.guildData.save(); - interaction.success(`administration/deletemod:${state ? "ENABLED" : "DISABLED"}`); - } -} - -module.exports = Deletemod; \ No newline at end of file diff --git a/commands/Economy/marry.js b/commands/Economy/marry.js index 4f3d186f..3fe1ffde 100644 --- a/commands/Economy/marry.js +++ b/commands/Economy/marry.js @@ -95,7 +95,7 @@ class Marry extends BaseCommand { }); const filter = i => i.user.id === member.id; - const collector = interaction.channel.createMessageComponentCollector({ filter, time: (10 * 60 * 1000) }); + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (10 * 60 * 1000) }); collector.on("collect", async i => { if (i.isButton()) { @@ -107,19 +107,10 @@ class Marry extends BaseCommand { collector.on("end", async (_, reason) => { delete pendings[interaction.member.id]; if (reason === "time") { - const row = new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setCustomId("marry_confirm_yes") - .setLabel(interaction.translate("common:ACCEPT")) - .setStyle(ButtonStyle.Success) - .setDisabled(true), - new ButtonBuilder() - .setCustomId("marry_confirm_no") - .setLabel(interaction.translate("common:CANCEL")) - .setStyle(ButtonStyle.Danger) - .setDisabled(true), - ); + row.components.forEach(component => { + component.setDisabled(true); + }); + return interaction.editReply({ components: [row] }); diff --git a/commands/Fun/memes.js b/commands/Fun/memes.js index d6abd064..3d727e07 100644 --- a/commands/Fun/memes.js +++ b/commands/Fun/memes.js @@ -1,4 +1,4 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, ComponentType } = require("discord.js"); +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder } = require("discord.js"); const BaseCommand = require("../../base/BaseCommand"), fetch = require("node-fetch"); @@ -32,6 +32,8 @@ class Memes extends BaseCommand { * @param {Object} data */ async execute(client, interaction) { + await interaction.deferReply(); + const tags = ["memes", "dankmemes", "me_irl", "wholesomememes"].map(tag => JSON.parse(JSON.stringify({ label: tag, @@ -47,45 +49,42 @@ class Memes extends BaseCommand { .addOptions(tags) ); - const msg = await interaction.reply({ + await interaction.editReply({ content: interaction.translate("common:AVAILABLE_OPTIONS"), - components: [row], - fetchReply: true + components: [row] }); - const filter = i => i.customId === "memes_select" && i.user.id === interaction.user.id; - const collector = new InteractionCollector(client, { - filter, - componentType: ComponentType.SelectMenu, - message: msg, - idle: (60 * 1000) - }); + const filter = i => i.user.id === interaction.user.id; + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (2 * 60 * 1000) }); collector.on("collect", async i => { - const tag = i?.values[0]; - const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); + if (i.isSelectMenu() && i.customId === "memes_select") { + i.deferUpdate(); - const embed = new EmbedBuilder() - .setColor(client.config.embed.color) - .setFooter({ - text: client.config.embed.footer - }) - .setTitle(`${res.title}\n${interaction.translate("fun/memes:SUBREDDIT")}: ${res.subreddit}\n${interaction.translate("common:AUTHOR")}: ${res.author}\n${interaction.translate("fun/memes:UPS")}: ${res.ups}`) - .setImage(res.url) - .setTimestamp(); + const tag = i.values[0]; + const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); - await i.update({ - embeds: [embed] - }); - }); + const embed = new EmbedBuilder() + .setColor(client.config.embed.color) + .setFooter({ + text: client.config.embed.footer + }) + .setTitle(res.title) + .setDescription(`${interaction.translate("fun/memes:SUBREDDIT")}: **${res.subreddit}**\n${interaction.translate("common:AUTHOR")}: **${res.author}**\n${interaction.translate("fun/memes:UPS")}: **${res.ups}**`) + .setImage(res.url) + .setTimestamp(); - collector.on("end", (_, reason) => { - if (reason === "idle") { - if (msg) msg.update({ - components: [] + await interaction.editReply({ + embeds: [embed] }); } }); + + collector.on("end", () => { + return interaction.editReply({ + components: [] + }); + }); } } diff --git a/commands/General/activity.js b/commands/General/activity.js index 41bf543e..93ff27fb 100644 --- a/commands/General/activity.js +++ b/commands/General/activity.js @@ -1,4 +1,4 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, PermissionsBitField, ComponentType } = require("discord.js"), +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, PermissionsBitField } = require("discord.js"), { defaultApplications } = require("../../helpers/discordTogether"); const BaseCommand = require("../../base/BaseCommand"); @@ -32,6 +32,8 @@ class Activity extends BaseCommand { * @param {Object} data */ async execute(client, interaction) { + await interaction.deferReply(); + const voice = interaction.member.voice.channel; if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL"); @@ -53,46 +55,43 @@ class Activity extends BaseCommand { .addOptions(activities) ); - const msg = await interaction.reply({ + await interaction.reply({ content: interaction.translate("general/activity:AVAILABLE_ACTIVITIES"), - components: [row], - fetchReply: true + components: [row] }); - const filter = i => i.customId === "activity_select" && i.user.id === interaction.user.id; - const collector = new InteractionCollector(client, { - filter, - componentType: ComponentType.SelectMenu, - message: msg, - idle: (2 * 1000) - }); + const filter = i => i.user.id === interaction.user.id; + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); collector.on("collect", async i => { - const activity = i?.values[0]; + if (i.isSelectMenu() && i.customId === "activity_select") { + const activity = i?.values[0]; - const invite = await client.discordTogether.createTogetherCode(voice.id, activity); - const embed = new EmbedBuilder() - .setTitle(activity) - .setColor(client.config.embed.color) - .setDescription(`**[${interaction.translate("general/activity:CLICK_HERE", { activity: defaultApplications.find(a => a.id === activity).name, channel: voice.name })}](${invite.code})**`) - .setFooter({ - text: client.config.embed.footer - }) - .setTimestamp(); + const invite = await client.discordTogether.createTogetherCode(voice.id, activity); + const embed = new EmbedBuilder() + .setTitle(defaultApplications.find(a => a.id === activity).name) + .setColor(client.config.embed.color) + .setDescription(`**[${interaction.translate("general/activity:CLICK_HERE", { + activity: defaultApplications.find(a => a.id === activity).name, + channel: voice.name + })}](${invite.code})**`) + .setFooter({ + text: client.config.embed.footer + }) + .setTimestamp(); - await i.update({ - embeds: [embed], - components: [] - }); - }); - - collector.on("end", (_, reason) => { - if (reason === "idle") { - if (msg) msg.update({ + await interaction.editReply({ + embeds: [embed], components: [] }); } }); + + collector.on("end", () => { + return interaction.editReply({ + components: [] + }); + }); } } diff --git a/commands/General/help.js b/commands/General/help.js index 72dd2af4..d2cff190 100644 --- a/commands/General/help.js +++ b/commands/General/help.js @@ -1,4 +1,4 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, PermissionsBitField, ComponentType } = require("discord.js"); +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, PermissionsBitField } = require("discord.js"); const BaseCommand = require("../../base/BaseCommand"); class Help extends BaseCommand { @@ -34,14 +34,16 @@ class Help extends BaseCommand { * @param {Object} data */ async execute(client, interaction) { + await interaction.deferReply(); + const commands = [...new Map(client.commands.map(v => [v.constructor.name, v])).values()]; const categories = []; const command = interaction.options.getString("command"); if (command) { - const embed = generateCommandHelp(client, interaction, command); + const embed = generateCommandHelp(interaction, command); - return interaction.reply({ + return interaction.editReply({ embeds: [embed] }); } @@ -68,60 +70,57 @@ class Help extends BaseCommand { .addOptions(categoriesRows) ); - const msg = await interaction.reply({ + await interaction.editReply({ content: interaction.translate("common:AVAILABLE_OPTIONS"), - components: [row], - fetchReply: true + components: [row] }); - const collector = new InteractionCollector(client, { - componentType: ComponentType.SelectMenu, - message: msg, - idle: (2 * 1000) - }); + const filter = i => i.user.id === interaction.user.id; + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); - collector.on("collect", async msg => { - const arg = msg?.values[0]; + collector.on("collect", async i => { + if (i.isSelectMenu() && (i.customId === "help_category_select" || i.customId === "help_commands_select")) { + i.deferUpdate(); - if (categories.find(c => c === arg)) { - const categoryCommands = commands.filter(cmd => cmd.category === arg).map(c => { - return { - label: c.command.name, - value: c.command.name - }; - }); + const arg = i?.values[0]; - const commandsRow = new ActionRowBuilder() - .addComponents( - new SelectMenuBuilder() - .setCustomId("help_commands_select") - .setPlaceholder(client.translate("common:NOTHING_SELECTED")) - .addOptions(categoryCommands) - ); + if (categories.includes(arg)) { + const categoryCommands = commands.filter(cmd => cmd.category === arg).map(c => { + return { + label: c.command.name, + value: c.command.name + }; + }); - await msg.update({ - content: interaction.translate("general/help:COMMANDS_IN", { - category: arg - }), - components: [commandsRow], - fetchReply: true - }); - } else { - const embed = generateCommandHelp(client, interaction, arg); - await msg.update({ - content: null, - components: [], - embeds: [embed] - }); + const commandsRow = new ActionRowBuilder() + .addComponents( + new SelectMenuBuilder() + .setCustomId("help_commands_select") + .setPlaceholder(client.translate("common:NOTHING_SELECTED")) + .addOptions(categoryCommands) + ); + + return await interaction.editReply({ + content: interaction.translate("general/help:COMMANDS_IN", { + category: arg + }), + components: [commandsRow] + }); + } else { + const embed = generateCommandHelp(interaction, arg); + return interaction.editReply({ + content: null, + components: [], + embeds: [embed] + }); + } } }); - collector.on("end", (_, reason) => { - if (reason === "idle") { - if (msg) msg.update({ - components: [] - }); - } + collector.on("end", () => { + return interaction.editReply({ + components: [] + }); }); } } @@ -132,9 +131,9 @@ function getPermName(bitfield = 0) { return null; } -function generateCommandHelp(client, interaction, command) { - const cmd = client.commands.get(command); - if (!cmd) return interaction.error("general/help:NOT_FOUND", { search: command }); +function generateCommandHelp(interaction, command) { + const cmd = interaction.client.commands.get(command); + if (!cmd) return interaction.error("general/help:NOT_FOUND", { search: command }, { edit: true }); const embed = new EmbedBuilder() .setAuthor({ @@ -164,9 +163,9 @@ function generateCommandHelp(client, interaction, command) { value: cmd.command.default_member_permissions > 0 ? interaction.translate(`misc:PERMISSIONS:${getPermName(cmd.command.default_member_permissions)}`) : interaction.translate("general/help:NO_REQUIRED_PERMISSION") } ]) - .setColor(client.config.embed.color) + .setColor(interaction.client.config.embed.color) .setFooter({ - text: client.config.embed.footer + text: interaction.client.config.embed.footer }); return embed; diff --git a/commands/Moderation/clear.js b/commands/Moderation/clear.js index 10ab0895..6c1c3f37 100644 --- a/commands/Moderation/clear.js +++ b/commands/Moderation/clear.js @@ -36,6 +36,8 @@ class Clear extends BaseCommand { * @param {Object} data */ async execute(client, interaction) { + await interaction.deferReply({ ephemeral: true }); + const option = interaction.options.getString("option"); const member = interaction.options.getMember("user"); @@ -52,37 +54,54 @@ class Clear extends BaseCommand { .setStyle(ButtonStyle.Secondary), ); - - await interaction.reply({ + await interaction.editReply({ content: interaction.translate("moderation/clear:ALL_CONFIRM"), - ephemeral: true, components: [row] }); const filter = i => i.user.id === interaction.user.id; - const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 }); + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); collector.on("collect", async i => { if (i.isButton()) { if (i.customId === "clear_confirm_yes") { + i.deferUpdate(); + const position = interaction.channel.position; const newChannel = await interaction.channel.clone(); await interaction.channel.delete(); newChannel.setPosition(position); - await newChannel.send({ + return newChannel.send({ content: interaction.translate("moderation/clear:CHANNEL_CLEARED") }); } else if (i.customId === "clear_confirm_no") { - row.components[0].setDisabled(true); - row.components[1].setDisabled(true); - - i.update({ - content: interaction.translate("misc:SELECT_CANCELED") - }); + i.deferUpdate(); + collector.stop("cancel"); } } }); + + collector.on("end", async (_, reason) => { + if (reason === "cancel") { + row.components.forEach(component => { + component.setDisabled(true); + }); + + interaction.editReply({ + content: interaction.translate("misc:SELECT_CANCELED"), + components: [row] + }); + } else if (reason === "idle") { + row.components.forEach(component => { + component.setDisabled(true); + }); + + interaction.editReply({ + components: [row] + }); + } + }); } else { if (isNaN(option) || parseInt(option) < 1) return interaction.error("misc:OPTION_NAN_ALL", null, { ephemeral: true }); let messages = await interaction.channel.messages.fetch({ diff --git a/commands/Moderation/giveaway.js b/commands/Moderation/giveaway.js index 5537d678..f9c41ad6 100644 --- a/commands/Moderation/giveaway.js +++ b/commands/Moderation/giveaway.js @@ -69,7 +69,7 @@ class Giveaway extends BaseCommand { filter, componentType: ComponentType.SelectMenu, message: msg, - idle: 30 * 1000 + idle: (30 * 1000) }); collector.on("collect", async i => { diff --git a/commands/Moderation/poll.js b/commands/Moderation/poll.js index 6a131c2e..b14154da 100644 --- a/commands/Moderation/poll.js +++ b/commands/Moderation/poll.js @@ -65,7 +65,7 @@ class Poll extends BaseCommand { let mention = null; const filter = i => i.user.id === interaction.user.id; - const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 }); + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); collector.on("collect", async i => { if (i.isButton()) { diff --git a/commands/Music/clips.js b/commands/Music/clips.js index 4fc3b9ec..1d57ab58 100644 --- a/commands/Music/clips.js +++ b/commands/Music/clips.js @@ -1,4 +1,4 @@ -const { SlashCommandBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, ComponentType } = require("discord.js"), +const { SlashCommandBuilder, ActionRowBuilder, SelectMenuBuilder, } = require("discord.js"), { joinVoiceChannel, createAudioResource, createAudioPlayer, getVoiceConnection, AudioPlayerStatus } = require("@discordjs/voice"); const BaseCommand = require("../../base/BaseCommand"), fs = require("fs"); @@ -34,6 +34,8 @@ class Clips extends BaseCommand { */ async execute(client, interaction) { fs.readdir("./clips", async function (err, files) { + await interaction.deferReply(); + if (err) return console.log("Unable to read directory: " + err); const clips = files.map(file => { @@ -52,68 +54,62 @@ class Clips extends BaseCommand { .addOptions(clips) ); - const msg = await interaction.reply({ + await interaction.editReply({ content: interaction.translate("music/clips:AVAILABLE_CLIPS"), - components: [row], - fetchReply: true + components: [row] }); - const filter = i => i.customId === "clips_select" && i.user.id === interaction.user.id; - const collector = new InteractionCollector(client, { - filter, - componentType: ComponentType.SelectMenu, - message: msg, - idle: (2 * 1000) - }); + const filter = i => i.user.id === interaction.user.id; + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); collector.on("collect", async i => { - const clip = i?.values[0]; - const voice = i.member.voice.channel; - if (!voice) return i.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] }); - const queue = client.player.getQueue(i.guild.id); - if (queue) return i.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] }); - if (getVoiceConnection(i.guild.id)) return i.update({ content: interaction.translate("music/clips:ACTIVE_CLIP"), components: [] }); - if (!fs.existsSync(`./clips/${clip}.mp3`)) return i.update({ content: interaction.translate("music/clips:NO_FILE", { file: clip }), components: [] }); + if (i.isSelectMenu() && i.customId === "clips_select") { + const clip = i?.values[0]; + const voice = i.member.voice.channel; + if (!voice) return i.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] }); + const queue = client.player.getQueue(i.guild.id); + if (queue) return i.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] }); + if (getVoiceConnection(i.guild.id)) return i.update({ content: interaction.translate("music/clips:ACTIVE_CLIP"), components: [] }); + if (!fs.existsSync(`./clips/${clip}.mp3`)) return i.update({ content: interaction.translate("music/clips:NO_FILE", { file: clip }), components: [] }); - try { - const connection = joinVoiceChannel({ - channelId: voice.id, - guildId: i.guild.id, - adapterCreator: i.guild.voiceAdapterCreator - }); - - const resource = createAudioResource(fs.createReadStream(`./clips/${clip}.mp3`)); - const player = createAudioPlayer() - .on("error", err => { - connection.destroy(); - console.error(err.message); + try { + const connection = joinVoiceChannel({ + channelId: voice.id, + guildId: interaction.guild.id, + adapterCreator: interaction.guild.voiceAdapterCreator }); - player.play(resource); - connection.subscribe(player); + const resource = createAudioResource(fs.createReadStream(`./clips/${clip}.mp3`)); + const player = createAudioPlayer() + .on("error", err => { + connection.destroy(); + console.error(err.message); + }); - player.on(AudioPlayerStatus.Idle, () => { - connection.destroy(); - }); - } catch (error) { - console.error(error); - } + player.play(resource); + connection.subscribe(player); - await i.update({ - content: interaction.translate("music/clips:PLAYING", { - clip - }), - components: [] - }); - }); + player.on(AudioPlayerStatus.Idle, () => { + connection.destroy(); + }); + } catch (error) { + console.error(error); + } - collector.on("end", (_, reason) => { - if (reason === "idle") { - if (msg) msg.update({ + await interaction.editReply({ + content: interaction.translate("music/clips:PLAYING", { + clip + }), components: [] }); } }); + + collector.on("end", () => { + return interaction.editReply({ + components: [] + }); + }); }); } } diff --git a/commands/Music/loop.js b/commands/Music/loop.js index 6422ce73..1a556412 100644 --- a/commands/Music/loop.js +++ b/commands/Music/loop.js @@ -73,7 +73,7 @@ class Loop extends BaseCommand { const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); collector.on("collect", async i => { - if (i.isSelectMenu()) { + if (i.isSelectMenu() && i.customId === "loop_select") { const type = i?.values[0]; const mode = type === "3" ? QueueRepeatMode.AUTOPLAY : type === "2" ? QueueRepeatMode.QUEUE : diff --git a/commands/Music/queue.js b/commands/Music/queue.js index 7125a860..3ba13b9e 100644 --- a/commands/Music/queue.js +++ b/commands/Music/queue.js @@ -72,7 +72,7 @@ class Queue extends BaseCommand { }); const filter = i => i.user.id === interaction.user.id; - const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (60 * 1000) }); + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (20 * 1000) }); collector.on("collect", async i => { if (i.isButton()) { @@ -143,21 +143,19 @@ class Queue extends BaseCommand { }); } else if (i.customId === "queue_stop") { i.deferUpdate(); - collector.stop(true); + collector.stop(); } } }); - collector.on("end", async (_, reason) => { - if (reason) { - row.components.forEach(component => { - component.setDisabled(true); - }); + collector.on("end", () => { + row.components.forEach(component => { + component.setDisabled(true); + }); - return interaction.editReply({ - components: [row] - }); - } + return interaction.editReply({ + components: [row] + }); }); } } diff --git a/commands/NSFW/nsfw.js b/commands/NSFW/nsfw.js index db54d7e5..77675b43 100644 --- a/commands/NSFW/nsfw.js +++ b/commands/NSFW/nsfw.js @@ -1,4 +1,4 @@ -const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder, InteractionCollector, ComponentType } = require("discord.js"); +const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, SelectMenuBuilder } = require("discord.js"); const BaseCommand = require("../../base/BaseCommand"), fetch = require("node-fetch"); @@ -32,6 +32,8 @@ class NSFW extends BaseCommand { * @param {Object} data */ async execute(client, interaction) { + await interaction.deferReply({ ephemeral: true }); + if (!interaction.channel.nsfw) return interaction.replyT("misc:NSFW_COMMAND", null, { ephemeral: true }); const tags = ["hentai", "ecchi", "lewdanimegirls", "hentaifemdom", "animefeets", "animebooty", "biganimetiddies", "sideoppai", "ahegao"].map(tag => @@ -49,46 +51,43 @@ class NSFW extends BaseCommand { .addOptions(tags) ); - const msg = await interaction.reply({ + await interaction.editReply({ content: interaction.translate("common:AVAILABLE_OPTIONS"), ephemeral: true, - components: [row], - fetchReply: true + components: [row] }); - const filter = i => i.customId === "nsfw_select" && i.user.id === interaction.user.id; - const collector = new InteractionCollector(client, { - filter, - componentType: ComponentType.SelectMenu, - message: msg, - idle: (60 * 1000) - }); + const filter = i => i.user.id === interaction.user.id; + const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (2 * 60 * 1000) }); collector.on("collect", async i => { - const tag = i?.values[0]; - const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); + if (i.isSelectMenu() && i.customId === "nsfw_select") { + i.deferUpdate(); - const embed = new EmbedBuilder() - .setColor(client.config.embed.color) - .setFooter({ - text: client.config.embed.footer - }) - .setTitle(`${res.title}\n${interaction.translate("fun/memes:SUBREDDIT")}: ${res.subreddit}\n${interaction.translate("common:AUTHOR")}: ${res.author}\n${interaction.translate("fun/memes:UPS")}: ${res.ups}`) - .setImage(res.url) - .setTimestamp(); + const tag = i?.values[0]; + const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); - await i.update({ - embeds: [embed] - }); - }); + const embed = new EmbedBuilder() + .setColor(client.config.embed.color) + .setFooter({ + text: client.config.embed.footer + }) + .setTitle(res.title) + .setDescription(`${interaction.translate("fun/memes:SUBREDDIT")}: **${res.subreddit}**\n${interaction.translate("common:AUTHOR")}: **${res.author}**\n${interaction.translate("fun/memes:UPS")}: **${res.ups}**`) + .setImage(res.url) + .setTimestamp(); - collector.on("end", (_, reason) => { - if (reason === "idle") { - if (msg) msg.update({ - components: [] + await interaction.editReply({ + embeds: [embed] }); } }); + + collector.on("end", () => { + return interaction.editReply({ + components: [] + }); + }); } } diff --git a/commands/Owner/servers.js b/commands/Owner/servers.js index 964bd0be..9a05e13c 100644 --- a/commands/Owner/servers.js +++ b/commands/Owner/servers.js @@ -84,7 +84,7 @@ class Servers extends BaseCommand { description = `${interaction.translate("common:SERVERS")}: ${client.guilds.cache.size}\n\n` + client.guilds.cache .sort((a, b) => b.memberCount - a.memberCount) - .map((r) => r) + .map(r => r) .map((r, i) => `**${i + 1}** - ${r.name} | ${r.memberCount} ${client.getNoun(r.memberCount, interaction.translate("misc:NOUNS:MEMBERS:1"), interaction.translate("misc:NOUNS:MEMBERS:2"), interaction.translate("misc:NOUNS:MEMBERS:5"))}`) .slice(i0, i1) .join("\n"); diff --git a/languages/en-US/administration/configuration.json b/languages/en-US/administration/configuration.json index 95ebdd6c..ddcdbcd5 100644 --- a/languages/en-US/administration/configuration.json +++ b/languages/en-US/administration/configuration.json @@ -22,9 +22,6 @@ "AUTOMOD_TITLE": "Auto-moderation:", "AUTOMOD_CONTENT": "Auto-moderation enabled.\n*Ignored channels: {{channels}}*", "AUTOMOD_DISABLED": "Auto-moderation disabled.", - "AUTODELETEMOD": "Auto delete mod commands", - "AUTODELETEMOD_ENABLED": "Automatic moderation commands deletion.", - "AUTODELETEMOD_DISABLED": "Automatic moderation commands deletion disabled.", "DASHBOARD_TITLE": "Edit your configuration:", "DASHBOARD_CONTENT": "Click here to go on the dashboard!", "AUTO_SANCTIONS": "Automatic sanctions", diff --git a/languages/ru-RU/administration/config.json b/languages/ru-RU/administration/config.json index c233fd43..0918eaca 100644 --- a/languages/ru-RU/administration/config.json +++ b/languages/ru-RU/administration/config.json @@ -15,9 +15,6 @@ "REPORTS": "Жалобы: {{channel}}", "AUTOMOD_TITLE": "Автомодерация", "AUTOMOD_CONTENT": "Автомодерация включена.\nИгнорируемые каналы: {{channels}}", - "AUTODELETEMOD": "Автоудаление команд модерации", - "AUTODELETEMOD_ENABLED": "Автоудаление команд модерации включено.", - "AUTODELETEMOD_DISABLED": "Автоудаление команд модерации отключено.", "AUTO_SANCTIONS": "Автоматические наказания", "KICK_CONTENT": "Кик: После **{{count}}** предупреждений.", "KICK_NOT_DEFINED": "Кик: Не назначено.", diff --git a/languages/uk-UA/administration/configuration.json b/languages/uk-UA/administration/configuration.json index 21111f51..958e3083 100644 --- a/languages/uk-UA/administration/configuration.json +++ b/languages/uk-UA/administration/configuration.json @@ -22,9 +22,6 @@ "AUTOMOD_TITLE": "Автомодерація", "AUTOMOD_CONTENT": "Автомодерація увімкнена.\n*Ігноровані канали: {{channels}}*", "AUTOMOD_DISABLED": "Автомодерація вимкнена.", - "AUTODELETEMOD": "Автовидалення команд модерації", - "AUTODELETEMOD_ENABLED": "Автовидалення команд модерації увімкнено.", - "AUTODELETEMOD_DISABLED": "Автовидалення команд модерації вимкнено.", "DASHBOARD_TITLE": "Змінити налаштування", "DASHBOARD_CONTENT": "Натисніть сюди, щоб перейти до панелі керування!", "AUTO_SANCTIONS": "Автоматичні покарання",