Используем createMessageComponentCollector вместо InteractionCollector

This commit is contained in:
JonnyBro 2022-08-28 21:53:54 +05:00
parent a4082163c8
commit 91096cd678
19 changed files with 231 additions and 287 deletions

3
.gitignore vendored
View file

@ -7,6 +7,9 @@
# commands.md # commands.md
**/commands.md **/commands.md
# Data
/.data
# Clips # Clips
/clips /clips

View file

@ -41,5 +41,4 @@ module.exports = mongoose.model("Guild", new Schema({
reports: false reports: false
}}, }},
casesCount: { type: Number, default: 0 }, casesCount: { type: Number, default: 0 },
autoDeleteModCommands: { type: Boolean, default: false },
})); }));

View file

@ -78,10 +78,6 @@ class Config extends BaseCommand {
channels: guildData.plugins.automod.ignored.map(ch => ` ${ch}`) channels: guildData.plugins.automod.ignored.map(ch => ` ${ch}`)
}) : interaction.translate("common:DISABLED") }) : 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"), name: interaction.translate("administration/config:SPECIAL_CHANNELS"),
value: interaction.translate("administration/config:NEWS", { value: interaction.translate("administration/config:NEWS", {

View file

@ -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;

View file

@ -95,7 +95,7 @@ class Marry extends BaseCommand {
}); });
const filter = i => i.user.id === member.id; 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 => { collector.on("collect", async i => {
if (i.isButton()) { if (i.isButton()) {
@ -107,19 +107,10 @@ class Marry extends BaseCommand {
collector.on("end", async (_, reason) => { collector.on("end", async (_, reason) => {
delete pendings[interaction.member.id]; delete pendings[interaction.member.id];
if (reason === "time") { if (reason === "time") {
const row = new ActionRowBuilder() row.components.forEach(component => {
.addComponents( component.setDisabled(true);
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),
);
return interaction.editReply({ return interaction.editReply({
components: [row] components: [row]
}); });

View file

@ -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"), const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch"); fetch = require("node-fetch");
@ -32,6 +32,8 @@ class Memes extends BaseCommand {
* @param {Object} data * @param {Object} data
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply();
const tags = ["memes", "dankmemes", "me_irl", "wholesomememes"].map(tag => const tags = ["memes", "dankmemes", "me_irl", "wholesomememes"].map(tag =>
JSON.parse(JSON.stringify({ JSON.parse(JSON.stringify({
label: tag, label: tag,
@ -47,45 +49,42 @@ class Memes extends BaseCommand {
.addOptions(tags) .addOptions(tags)
); );
const msg = await interaction.reply({ await interaction.editReply({
content: interaction.translate("common:AVAILABLE_OPTIONS"), content: interaction.translate("common:AVAILABLE_OPTIONS"),
components: [row], components: [row]
fetchReply: true
}); });
const filter = i => i.customId === "memes_select" && i.user.id === interaction.user.id; const filter = i => i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, { const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (2 * 60 * 1000) });
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: (60 * 1000)
});
collector.on("collect", async i => { collector.on("collect", async i => {
const tag = i?.values[0]; if (i.isSelectMenu() && i.customId === "memes_select") {
const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); i.deferUpdate();
const embed = new EmbedBuilder() const tag = i.values[0];
.setColor(client.config.embed.color) const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json());
.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();
await i.update({ const embed = new EmbedBuilder()
embeds: [embed] .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) => { await interaction.editReply({
if (reason === "idle") { embeds: [embed]
if (msg) msg.update({
components: []
}); });
} }
}); });
collector.on("end", () => {
return interaction.editReply({
components: []
});
});
} }
} }

View file

@ -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"); { defaultApplications } = require("../../helpers/discordTogether");
const BaseCommand = require("../../base/BaseCommand"); const BaseCommand = require("../../base/BaseCommand");
@ -32,6 +32,8 @@ class Activity extends BaseCommand {
* @param {Object} data * @param {Object} data
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply();
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL");
@ -53,46 +55,43 @@ class Activity extends BaseCommand {
.addOptions(activities) .addOptions(activities)
); );
const msg = await interaction.reply({ await interaction.reply({
content: interaction.translate("general/activity:AVAILABLE_ACTIVITIES"), content: interaction.translate("general/activity:AVAILABLE_ACTIVITIES"),
components: [row], components: [row]
fetchReply: true
}); });
const filter = i => i.customId === "activity_select" && i.user.id === interaction.user.id; const filter = i => i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, { const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) });
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: (2 * 1000)
});
collector.on("collect", async i => { 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 invite = await client.discordTogether.createTogetherCode(voice.id, activity);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(activity) .setTitle(defaultApplications.find(a => a.id === activity).name)
.setColor(client.config.embed.color) .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})**`) .setDescription(`**[${interaction.translate("general/activity:CLICK_HERE", {
.setFooter({ activity: defaultApplications.find(a => a.id === activity).name,
text: client.config.embed.footer channel: voice.name
}) })}](${invite.code})**`)
.setTimestamp(); .setFooter({
text: client.config.embed.footer
})
.setTimestamp();
await i.update({ await interaction.editReply({
embeds: [embed], embeds: [embed],
components: []
});
});
collector.on("end", (_, reason) => {
if (reason === "idle") {
if (msg) msg.update({
components: [] components: []
}); });
} }
}); });
collector.on("end", () => {
return interaction.editReply({
components: []
});
});
} }
} }

View file

@ -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"); const BaseCommand = require("../../base/BaseCommand");
class Help extends BaseCommand { class Help extends BaseCommand {
@ -34,14 +34,16 @@ class Help extends BaseCommand {
* @param {Object} data * @param {Object} data
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply();
const commands = [...new Map(client.commands.map(v => [v.constructor.name, v])).values()]; const commands = [...new Map(client.commands.map(v => [v.constructor.name, v])).values()];
const categories = []; const categories = [];
const command = interaction.options.getString("command"); const command = interaction.options.getString("command");
if (command) { if (command) {
const embed = generateCommandHelp(client, interaction, command); const embed = generateCommandHelp(interaction, command);
return interaction.reply({ return interaction.editReply({
embeds: [embed] embeds: [embed]
}); });
} }
@ -68,60 +70,57 @@ class Help extends BaseCommand {
.addOptions(categoriesRows) .addOptions(categoriesRows)
); );
const msg = await interaction.reply({ await interaction.editReply({
content: interaction.translate("common:AVAILABLE_OPTIONS"), content: interaction.translate("common:AVAILABLE_OPTIONS"),
components: [row], components: [row]
fetchReply: true
}); });
const collector = new InteractionCollector(client, { const filter = i => i.user.id === interaction.user.id;
componentType: ComponentType.SelectMenu, const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) });
message: msg,
idle: (2 * 1000)
});
collector.on("collect", async msg => { collector.on("collect", async i => {
const arg = msg?.values[0]; if (i.isSelectMenu() && (i.customId === "help_category_select" || i.customId === "help_commands_select")) {
i.deferUpdate();
if (categories.find(c => c === arg)) { const arg = i?.values[0];
const categoryCommands = commands.filter(cmd => cmd.category === arg).map(c => {
return {
label: c.command.name,
value: c.command.name
};
});
const commandsRow = new ActionRowBuilder() if (categories.includes(arg)) {
.addComponents( const categoryCommands = commands.filter(cmd => cmd.category === arg).map(c => {
new SelectMenuBuilder() return {
.setCustomId("help_commands_select") label: c.command.name,
.setPlaceholder(client.translate("common:NOTHING_SELECTED")) value: c.command.name
.addOptions(categoryCommands) };
); });
await msg.update({ const commandsRow = new ActionRowBuilder()
content: interaction.translate("general/help:COMMANDS_IN", { .addComponents(
category: arg new SelectMenuBuilder()
}), .setCustomId("help_commands_select")
components: [commandsRow], .setPlaceholder(client.translate("common:NOTHING_SELECTED"))
fetchReply: true .addOptions(categoryCommands)
}); );
} else {
const embed = generateCommandHelp(client, interaction, arg); return await interaction.editReply({
await msg.update({ content: interaction.translate("general/help:COMMANDS_IN", {
content: null, category: arg
components: [], }),
embeds: [embed] components: [commandsRow]
}); });
} else {
const embed = generateCommandHelp(interaction, arg);
return interaction.editReply({
content: null,
components: [],
embeds: [embed]
});
}
} }
}); });
collector.on("end", (_, reason) => { collector.on("end", () => {
if (reason === "idle") { return interaction.editReply({
if (msg) msg.update({ components: []
components: [] });
});
}
}); });
} }
} }
@ -132,9 +131,9 @@ function getPermName(bitfield = 0) {
return null; return null;
} }
function generateCommandHelp(client, interaction, command) { function generateCommandHelp(interaction, command) {
const cmd = client.commands.get(command); const cmd = interaction.client.commands.get(command);
if (!cmd) return interaction.error("general/help:NOT_FOUND", { search: command }); if (!cmd) return interaction.error("general/help:NOT_FOUND", { search: command }, { edit: true });
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setAuthor({ .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") 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({ .setFooter({
text: client.config.embed.footer text: interaction.client.config.embed.footer
}); });
return embed; return embed;

View file

@ -36,6 +36,8 @@ class Clear extends BaseCommand {
* @param {Object} data * @param {Object} data
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
const option = interaction.options.getString("option"); const option = interaction.options.getString("option");
const member = interaction.options.getMember("user"); const member = interaction.options.getMember("user");
@ -52,37 +54,54 @@ class Clear extends BaseCommand {
.setStyle(ButtonStyle.Secondary), .setStyle(ButtonStyle.Secondary),
); );
await interaction.editReply({
await interaction.reply({
content: interaction.translate("moderation/clear:ALL_CONFIRM"), content: interaction.translate("moderation/clear:ALL_CONFIRM"),
ephemeral: true,
components: [row] components: [row]
}); });
const filter = i => i.user.id === interaction.user.id; 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 => { collector.on("collect", async i => {
if (i.isButton()) { if (i.isButton()) {
if (i.customId === "clear_confirm_yes") { if (i.customId === "clear_confirm_yes") {
i.deferUpdate();
const position = interaction.channel.position; const position = interaction.channel.position;
const newChannel = await interaction.channel.clone(); const newChannel = await interaction.channel.clone();
await interaction.channel.delete(); await interaction.channel.delete();
newChannel.setPosition(position); newChannel.setPosition(position);
await newChannel.send({ return newChannel.send({
content: interaction.translate("moderation/clear:CHANNEL_CLEARED") content: interaction.translate("moderation/clear:CHANNEL_CLEARED")
}); });
} else if (i.customId === "clear_confirm_no") { } else if (i.customId === "clear_confirm_no") {
row.components[0].setDisabled(true); i.deferUpdate();
row.components[1].setDisabled(true); collector.stop("cancel");
i.update({
content: interaction.translate("misc:SELECT_CANCELED")
});
} }
} }
}); });
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 { } else {
if (isNaN(option) || parseInt(option) < 1) return interaction.error("misc:OPTION_NAN_ALL", null, { ephemeral: true }); if (isNaN(option) || parseInt(option) < 1) return interaction.error("misc:OPTION_NAN_ALL", null, { ephemeral: true });
let messages = await interaction.channel.messages.fetch({ let messages = await interaction.channel.messages.fetch({

View file

@ -69,7 +69,7 @@ class Giveaway extends BaseCommand {
filter, filter,
componentType: ComponentType.SelectMenu, componentType: ComponentType.SelectMenu,
message: msg, message: msg,
idle: 30 * 1000 idle: (30 * 1000)
}); });
collector.on("collect", async i => { collector.on("collect", async i => {

View file

@ -65,7 +65,7 @@ class Poll extends BaseCommand {
let mention = null; let mention = null;
const filter = i => i.user.id === interaction.user.id; 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 => { collector.on("collect", async i => {
if (i.isButton()) { if (i.isButton()) {

View file

@ -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"); { joinVoiceChannel, createAudioResource, createAudioPlayer, getVoiceConnection, AudioPlayerStatus } = require("@discordjs/voice");
const BaseCommand = require("../../base/BaseCommand"), const BaseCommand = require("../../base/BaseCommand"),
fs = require("fs"); fs = require("fs");
@ -34,6 +34,8 @@ class Clips extends BaseCommand {
*/ */
async execute(client, interaction) { async execute(client, interaction) {
fs.readdir("./clips", async function (err, files) { fs.readdir("./clips", async function (err, files) {
await interaction.deferReply();
if (err) return console.log("Unable to read directory: " + err); if (err) return console.log("Unable to read directory: " + err);
const clips = files.map(file => { const clips = files.map(file => {
@ -52,68 +54,62 @@ class Clips extends BaseCommand {
.addOptions(clips) .addOptions(clips)
); );
const msg = await interaction.reply({ await interaction.editReply({
content: interaction.translate("music/clips:AVAILABLE_CLIPS"), content: interaction.translate("music/clips:AVAILABLE_CLIPS"),
components: [row], components: [row]
fetchReply: true
}); });
const filter = i => i.customId === "clips_select" && i.user.id === interaction.user.id; const filter = i => i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, { const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) });
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: (2 * 1000)
});
collector.on("collect", async i => { collector.on("collect", async i => {
const clip = i?.values[0]; if (i.isSelectMenu() && i.customId === "clips_select") {
const voice = i.member.voice.channel; const clip = i?.values[0];
if (!voice) return i.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] }); const voice = i.member.voice.channel;
const queue = client.player.getQueue(i.guild.id); if (!voice) return i.update({ content: interaction.translate("music/play:NO_VOICE_CHANNEL"), components: [] });
if (queue) return i.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] }); const queue = client.player.getQueue(i.guild.id);
if (getVoiceConnection(i.guild.id)) return i.update({ content: interaction.translate("music/clips:ACTIVE_CLIP"), components: [] }); if (queue) return i.update({ content: interaction.translate("music/clips:ACTIVE_QUEUE"), components: [] });
if (!fs.existsSync(`./clips/${clip}.mp3`)) return i.update({ content: interaction.translate("music/clips:NO_FILE", { file: clip }), 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 { try {
const connection = joinVoiceChannel({ const connection = joinVoiceChannel({
channelId: voice.id, channelId: voice.id,
guildId: i.guild.id, guildId: interaction.guild.id,
adapterCreator: i.guild.voiceAdapterCreator adapterCreator: interaction.guild.voiceAdapterCreator
});
const resource = createAudioResource(fs.createReadStream(`./clips/${clip}.mp3`));
const player = createAudioPlayer()
.on("error", err => {
connection.destroy();
console.error(err.message);
}); });
player.play(resource); const resource = createAudioResource(fs.createReadStream(`./clips/${clip}.mp3`));
connection.subscribe(player); const player = createAudioPlayer()
.on("error", err => {
connection.destroy();
console.error(err.message);
});
player.on(AudioPlayerStatus.Idle, () => { player.play(resource);
connection.destroy(); connection.subscribe(player);
});
} catch (error) {
console.error(error);
}
await i.update({ player.on(AudioPlayerStatus.Idle, () => {
content: interaction.translate("music/clips:PLAYING", { connection.destroy();
clip });
}), } catch (error) {
components: [] console.error(error);
}); }
});
collector.on("end", (_, reason) => { await interaction.editReply({
if (reason === "idle") { content: interaction.translate("music/clips:PLAYING", {
if (msg) msg.update({ clip
}),
components: [] components: []
}); });
} }
}); });
collector.on("end", () => {
return interaction.editReply({
components: []
});
});
}); });
} }
} }

View file

@ -73,7 +73,7 @@ class Loop extends BaseCommand {
const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) }); const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (15 * 1000) });
collector.on("collect", async i => { collector.on("collect", async i => {
if (i.isSelectMenu()) { if (i.isSelectMenu() && i.customId === "loop_select") {
const type = i?.values[0]; const type = i?.values[0];
const mode = type === "3" ? QueueRepeatMode.AUTOPLAY : const mode = type === "3" ? QueueRepeatMode.AUTOPLAY :
type === "2" ? QueueRepeatMode.QUEUE : type === "2" ? QueueRepeatMode.QUEUE :

View file

@ -72,7 +72,7 @@ class Queue extends BaseCommand {
}); });
const filter = i => i.user.id === interaction.user.id; 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 => { collector.on("collect", async i => {
if (i.isButton()) { if (i.isButton()) {
@ -143,21 +143,19 @@ class Queue extends BaseCommand {
}); });
} else if (i.customId === "queue_stop") { } else if (i.customId === "queue_stop") {
i.deferUpdate(); i.deferUpdate();
collector.stop(true); collector.stop();
} }
} }
}); });
collector.on("end", async (_, reason) => { collector.on("end", () => {
if (reason) { row.components.forEach(component => {
row.components.forEach(component => { component.setDisabled(true);
component.setDisabled(true); });
});
return interaction.editReply({ return interaction.editReply({
components: [row] components: [row]
}); });
}
}); });
} }
} }

View file

@ -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"), const BaseCommand = require("../../base/BaseCommand"),
fetch = require("node-fetch"); fetch = require("node-fetch");
@ -32,6 +32,8 @@ class NSFW extends BaseCommand {
* @param {Object} data * @param {Object} data
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply({ ephemeral: true });
if (!interaction.channel.nsfw) return interaction.replyT("misc:NSFW_COMMAND", null, { 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 => const tags = ["hentai", "ecchi", "lewdanimegirls", "hentaifemdom", "animefeets", "animebooty", "biganimetiddies", "sideoppai", "ahegao"].map(tag =>
@ -49,46 +51,43 @@ class NSFW extends BaseCommand {
.addOptions(tags) .addOptions(tags)
); );
const msg = await interaction.reply({ await interaction.editReply({
content: interaction.translate("common:AVAILABLE_OPTIONS"), content: interaction.translate("common:AVAILABLE_OPTIONS"),
ephemeral: true, ephemeral: true,
components: [row], components: [row]
fetchReply: true
}); });
const filter = i => i.customId === "nsfw_select" && i.user.id === interaction.user.id; const filter = i => i.user.id === interaction.user.id;
const collector = new InteractionCollector(client, { const collector = interaction.channel.createMessageComponentCollector({ filter, idle: (2 * 60 * 1000) });
filter,
componentType: ComponentType.SelectMenu,
message: msg,
idle: (60 * 1000)
});
collector.on("collect", async i => { collector.on("collect", async i => {
const tag = i?.values[0]; if (i.isSelectMenu() && i.customId === "nsfw_select") {
const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json()); i.deferUpdate();
const embed = new EmbedBuilder() const tag = i?.values[0];
.setColor(client.config.embed.color) const res = await fetch(`https://meme-api.herokuapp.com/gimme/${tag}`).then(response => response.json());
.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();
await i.update({ const embed = new EmbedBuilder()
embeds: [embed] .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) => { await interaction.editReply({
if (reason === "idle") { embeds: [embed]
if (msg) msg.update({
components: []
}); });
} }
}); });
collector.on("end", () => {
return interaction.editReply({
components: []
});
});
} }
} }

View file

@ -84,7 +84,7 @@ class Servers extends BaseCommand {
description = `${interaction.translate("common:SERVERS")}: ${client.guilds.cache.size}\n\n` + description = `${interaction.translate("common:SERVERS")}: ${client.guilds.cache.size}\n\n` +
client.guilds.cache client.guilds.cache
.sort((a, b) => b.memberCount - a.memberCount) .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"))}`) .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) .slice(i0, i1)
.join("\n"); .join("\n");

View file

@ -22,9 +22,6 @@
"AUTOMOD_TITLE": "Auto-moderation:", "AUTOMOD_TITLE": "Auto-moderation:",
"AUTOMOD_CONTENT": "Auto-moderation enabled.\n*Ignored channels: {{channels}}*", "AUTOMOD_CONTENT": "Auto-moderation enabled.\n*Ignored channels: {{channels}}*",
"AUTOMOD_DISABLED": "Auto-moderation disabled.", "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_TITLE": "Edit your configuration:",
"DASHBOARD_CONTENT": "Click here to go on the dashboard!", "DASHBOARD_CONTENT": "Click here to go on the dashboard!",
"AUTO_SANCTIONS": "Automatic sanctions", "AUTO_SANCTIONS": "Automatic sanctions",

View file

@ -15,9 +15,6 @@
"REPORTS": "Жалобы: {{channel}}", "REPORTS": "Жалобы: {{channel}}",
"AUTOMOD_TITLE": "Автомодерация", "AUTOMOD_TITLE": "Автомодерация",
"AUTOMOD_CONTENT": "Автомодерация включена.\nИгнорируемые каналы: {{channels}}", "AUTOMOD_CONTENT": "Автомодерация включена.\nИгнорируемые каналы: {{channels}}",
"AUTODELETEMOD": "Автоудаление команд модерации",
"AUTODELETEMOD_ENABLED": "Автоудаление команд модерации включено.",
"AUTODELETEMOD_DISABLED": "Автоудаление команд модерации отключено.",
"AUTO_SANCTIONS": "Автоматические наказания", "AUTO_SANCTIONS": "Автоматические наказания",
"KICK_CONTENT": "Кик: После **{{count}}** предупреждений.", "KICK_CONTENT": "Кик: После **{{count}}** предупреждений.",
"KICK_NOT_DEFINED": "Кик: Не назначено.", "KICK_NOT_DEFINED": "Кик: Не назначено.",

View file

@ -22,9 +22,6 @@
"AUTOMOD_TITLE": "Автомодерація", "AUTOMOD_TITLE": "Автомодерація",
"AUTOMOD_CONTENT": "Автомодерація увімкнена.\n*Ігноровані канали: {{channels}}*", "AUTOMOD_CONTENT": "Автомодерація увімкнена.\n*Ігноровані канали: {{channels}}*",
"AUTOMOD_DISABLED": "Автомодерація вимкнена.", "AUTOMOD_DISABLED": "Автомодерація вимкнена.",
"AUTODELETEMOD": "Автовидалення команд модерації",
"AUTODELETEMOD_ENABLED": "Автовидалення команд модерації увімкнено.",
"AUTODELETEMOD_DISABLED": "Автовидалення команд модерації вимкнено.",
"DASHBOARD_TITLE": "Змінити налаштування", "DASHBOARD_TITLE": "Змінити налаштування",
"DASHBOARD_CONTENT": "Натисніть сюди, щоб перейти до панелі керування!", "DASHBOARD_CONTENT": "Натисніть сюди, щоб перейти до панелі керування!",
"AUTO_SANCTIONS": "Автоматичні покарання", "AUTO_SANCTIONS": "Автоматичні покарання",