diff --git a/commands/General/info.js b/commands/General/info.js new file mode 100644 index 00000000..2f94de1a --- /dev/null +++ b/commands/General/info.js @@ -0,0 +1,233 @@ +const { SlashCommandBuilder, ChannelType } = require("discord.js"); +const BaseCommand = require("../../base/BaseCommand"); + +class Info extends BaseCommand { + /** + * + * @param {import("../base/Client")} client + */ + constructor(client) { + super({ + command: new SlashCommandBuilder() + .setName("info") + .setDescription(client.translate("general/info:DESCRIPTION")) + .setDescriptionLocalizations({ + uk: client.translate("general/info:DESCRIPTION", null, "uk-UA"), + ru: client.translate("general/info:DESCRIPTION", null, "ru-RU"), + }) + .setDMPermission(false) + .addSubcommand(subcommand => + subcommand + .setName("user") + .setDescription(client.translate("general/info:USER")) + .setDescriptionLocalizations({ + uk: client.translate("general/info:USER", null, "uk-UA"), + ru: client.translate("general/info:USER", null, "ru-RU"), + }) + .addUserOption(option => + option + .setName("user") + .setDescription(client.translate("common:USER")) + .setDescriptionLocalizations({ + uk: client.translate("common:USER", null, "uk-UA"), + ru: client.translate("common:USER", null, "ru-RU"), + }), + ), + ) + .addSubcommand(subcommand => + subcommand + .setName("server") + .setDescription(client.translate("general/info:SERVER")) + .setDescriptionLocalizations({ + uk: client.translate("general/info:SERVER", null, "uk-UA"), + ru: client.translate("general/info:SERVER", null, "ru-RU"), + }), + ), + dirname: __dirname, + ownerOnly: false, + }); + } + + /** + * + * @param {import("../../base/Client")} client + * @param {import("discord.js").ChatInputCommandInteraction} interaction + */ + async execute(client, interaction) { + await interaction.deferReply(); + + const command = interaction.options.getSubcommand(); + + if (command === "user") { + const member = interaction.options.getMember("user") || interaction.member; + const embed = getUserInfo(interaction, member); + + return interaction.editReply({ + embeds: [embed], + }); + } else { + const embed = await getServerInfo(interaction); + + return interaction.editReply({ + embeds: [embed], + }); + } + } +} + +/** + * + * @param {import("discord.js").ChatInputCommandInteraction} interaction + * @returns {Promise} Embed containing information about the guild + */ +async function getServerInfo(interaction) { + const { guild } = interaction; + + await guild.members.fetch(); + const owner = await guild.fetchOwner(); + + const embed = interaction.client.embed({ + author: guild.name, + thumbnail: guild.iconURL(), + fields: [ + { + name: interaction.client.customEmojis.title + interaction.translate("common:NAME"), + value: guild.name, + inline: true, + }, + { + name: interaction.client.customEmojis.calendar + interaction.translate("common:CREATION"), + value: ``, + inline: true, + }, + { + name: interaction.client.customEmojis.users + interaction.translate("common:MEMBERS"), + value: + `${guild.members.cache.filter(m => !m.user.bot).size} ${interaction.client.functions.getNoun( + guild.members.cache.filter(m => !m.user.bot).size, + interaction.translate("misc:NOUNS:MEMBERS:1"), + interaction.translate("misc:NOUNS:MEMBERS:2"), + interaction.translate("misc:NOUNS:MEMBERS:5"), + )}` + + "\n" + + `${guild.members.cache.filter(m => m.user.bot).size} ${interaction.client.functions.getNoun( + guild.members.cache.filter(m => m.user.bot).size, + interaction.translate("misc:NOUNS:BOTS:1"), + interaction.translate("misc:NOUNS:BOTS:2"), + interaction.translate("misc:NOUNS:BOTS:5"), + )}`, + inline: true, + }, + { + name: interaction.client.customEmojis.afk + interaction.translate("general/serverinfo:AFK_CHANNEL"), + value: guild.afkChannel?.toString() || interaction.translate("common:MISSING"), + inline: true, + }, + { + name: interaction.client.customEmojis.id + interaction.translate("common:SERVER_ID"), + value: guild.id, + inline: true, + }, + { + name: interaction.client.customEmojis.crown + interaction.translate("common:OWNER"), + value: owner.toString(), + inline: true, + }, + { + name: interaction.client.customEmojis.boost + interaction.translate("general/serverinfo:BOOSTS"), + value: guild.premiumSubscriptionCount?.toString() || "0", + inline: true, + }, + { + name: interaction.client.customEmojis.channels + interaction.translate("common:CHANNELS"), + value: + `${guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size} ${interaction.client.functions.getNoun( + guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size, + interaction.translate("misc:NOUNS:TEXT:1"), + interaction.translate("misc:NOUNS:TEXT:2"), + interaction.translate("misc:NOUNS:TEXT:5"), + )}` + + "\n" + + `${guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size} ${interaction.client.functions.getNoun( + guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size, + interaction.translate("misc:NOUNS:VOICE:1"), + interaction.translate("misc:NOUNS:VOICE:2"), + interaction.translate("misc:NOUNS:VOICE:5"), + )}` + + "\n" + + `${guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size} ${interaction.client.functions.getNoun( + guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size, + interaction.translate("misc:NOUNS:CATEGORY:1"), + interaction.translate("misc:NOUNS:CATEGORY:2"), + interaction.translate("misc:NOUNS:CATEGORY:5"), + )}`, + inline: true, + }, + ], + }); + + return embed; +} + +/** + * + * @param {import("discord.js").ChatInputCommandInteraction} interaction + * @param {import("discord.js").Member} member + * @returns {import("discord.js").Embed} Embed containing information about the user + */ +function getUserInfo(interaction, member) { + const embed = interaction.client.embed({ + author: { + name: `${member.user.getUsername()} (${member.id})`, + iconURL: member.displayAvatarURL(), + }, + thumbnail: member.displayAvatarURL(), + fields: [ + { + name: ":man: " + interaction.translate("common:USERNAME"), + value: member.user.getUsername(), + inline: true, + }, + { + name: interaction.client.customEmojis.pencil + " " + interaction.translate("common:NICKNAME"), + value: member.nickname || interaction.translate("general/userinfo:NO_NICKNAME"), + inline: true, + }, + { + name: interaction.client.customEmojis.bot + " " + interaction.translate("common:ROBOT"), + value: member.user.bot ? interaction.translate("common:YES") : interaction.translate("common:NO"), + inline: true, + }, + { + name: interaction.client.customEmojis.calendar + " " + interaction.translate("common:CREATION"), + value: ``, + inline: true, + }, + { + name: interaction.client.customEmojis.calendar2 + " " + interaction.translate("common:JOINED"), + value: ``, + inline: true, + }, + { + name: interaction.client.customEmojis.color + " " + interaction.translate("common:COLOR"), + value: member.displayHexColor, + inline: true, + }, + { + name: interaction.client.customEmojis.roles + " " + interaction.translate("common:ROLES"), + value: + member.roles.size > 10 + ? member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", ") + " " + + interaction.translate("general/userinfo:MORE_ROLES", { + count: member.roles.cache.size - 10, + }) + : member.roles.cache.size < 1 ? interaction.translate("general/userinfo:NO_ROLE") : member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", "), + inline: true, + }, + ], + }); + + return embed; +} + +module.exports = Info; diff --git a/commands/General/reminds.js b/commands/General/reminds.js index 633c231b..bbe5c4fe 100644 --- a/commands/General/reminds.js +++ b/commands/General/reminds.js @@ -130,6 +130,12 @@ class Reminds extends BaseCommand { const embeds = generateRemindsEmbeds(interaction, interaction.data.user.reminds); + if (embeds.length === 0) return interaction.editReply({ + content: interaction.translate("general/reminds:NO_REMINDS"), + embeds: [], + components: [], + }); + embeds.length <= 5 ? currentPage = 0 : currentPage; const row2 = new ActionRowBuilder().addComponents(embeds[currentPage].data._buttons); diff --git a/commands/General/serverinfo.js b/commands/General/serverinfo.js deleted file mode 100644 index 601a8af4..00000000 --- a/commands/General/serverinfo.js +++ /dev/null @@ -1,121 +0,0 @@ -const { SlashCommandBuilder, ChannelType } = require("discord.js"); -const BaseCommand = require("../../base/BaseCommand"); - -class Serverinfo extends BaseCommand { - /** - * - * @param {import("../base/Client")} client - */ - constructor(client) { - super({ - command: new SlashCommandBuilder() - .setName("serverinfo") - .setDescription(client.translate("general/serverinfo:DESCRIPTION")) - .setDescriptionLocalizations({ - uk: client.translate("general/serverinfo:DESCRIPTION", null, "uk-UA"), - ru: client.translate("general/serverinfo:DESCRIPTION", null, "ru-RU"), - }) - .setDMPermission(false), - dirname: __dirname, - ownerOnly: false, - }); - } - - /** - * - * @param {import("../../base/Client")} client - * @param {import("discord.js").ChatInputCommandInteraction} interaction - */ - async execute(client, interaction) { - const { guild } = interaction; - - await guild.members.fetch(); - const owner = await guild.fetchOwner(); - - const embed = client.embed({ - author: guild.name, - thumbnail: guild.iconURL(), - fields: [ - { - name: client.customEmojis.title + interaction.translate("common:NAME"), - value: guild.name, - inline: true, - }, - { - name: client.customEmojis.calendar + interaction.translate("common:CREATION"), - value: ``, - inline: true, - }, - { - name: client.customEmojis.users + interaction.translate("common:MEMBERS"), - value: - `${guild.members.cache.filter(m => !m.user.bot).size} ${client.functions.getNoun( - guild.members.cache.filter(m => !m.user.bot).size, - interaction.translate("misc:NOUNS:MEMBERS:1"), - interaction.translate("misc:NOUNS:MEMBERS:2"), - interaction.translate("misc:NOUNS:MEMBERS:5"), - )}` + - "\n" + - `${guild.members.cache.filter(m => m.user.bot).size} ${client.functions.getNoun( - guild.members.cache.filter(m => m.user.bot).size, - interaction.translate("misc:NOUNS:BOTS:1"), - interaction.translate("misc:NOUNS:BOTS:2"), - interaction.translate("misc:NOUNS:BOTS:5"), - )}`, - inline: true, - }, - { - name: client.customEmojis.afk + interaction.translate("general/serverinfo:AFK_CHANNEL"), - value: guild.afkChannel?.toString() || interaction.translate("common:MISSING"), - inline: true, - }, - { - name: client.customEmojis.id + interaction.translate("common:SERVER_ID"), - value: guild.id, - inline: true, - }, - { - name: client.customEmojis.crown + interaction.translate("common:OWNER"), - value: owner.toString(), - inline: true, - }, - { - name: client.customEmojis.boost + interaction.translate("general/serverinfo:BOOSTS"), - value: guild.premiumSubscriptionCount?.toString() || "0", - inline: true, - }, - { - name: client.customEmojis.channels + interaction.translate("common:CHANNELS"), - value: - `${guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size} ${client.functions.getNoun( - guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size, - interaction.translate("misc:NOUNS:TEXT:1"), - interaction.translate("misc:NOUNS:TEXT:2"), - interaction.translate("misc:NOUNS:TEXT:5"), - )}` + - "\n" + - `${guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size} ${client.functions.getNoun( - guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size, - interaction.translate("misc:NOUNS:VOICE:1"), - interaction.translate("misc:NOUNS:VOICE:2"), - interaction.translate("misc:NOUNS:VOICE:5"), - )}` + - "\n" + - `${guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size} ${client.functions.getNoun( - guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size, - interaction.translate("misc:NOUNS:CATEGORY:1"), - interaction.translate("misc:NOUNS:CATEGORY:2"), - interaction.translate("misc:NOUNS:CATEGORY:5"), - )}`, - inline: true, - }, - ], - }); - - interaction.reply({ - embeds: [embed], - }); - } -} - -module.exports = Serverinfo; diff --git a/commands/General/userinfo.js b/commands/General/userinfo.js deleted file mode 100644 index f467146b..00000000 --- a/commands/General/userinfo.js +++ /dev/null @@ -1,99 +0,0 @@ -const { SlashCommandBuilder } = require("discord.js"); -const BaseCommand = require("../../base/BaseCommand"); - -class Userinfo extends BaseCommand { - /** - * - * @param {import("../base/Client")} client - */ - constructor(client) { - super({ - command: new SlashCommandBuilder() - .setName("userinfo") - .setDescription(client.translate("general/userinfo:DESCRIPTION")) - .setDescriptionLocalizations({ - uk: client.translate("general/userinfo:DESCRIPTION", null, "uk-UA"), - ru: client.translate("general/userinfo:DESCRIPTION", null, "ru-RU"), - }) - .setDMPermission(false) - .addUserOption(option => - option - .setName("user") - .setDescription(client.translate("common:USER")) - .setDescriptionLocalizations({ - uk: client.translate("common:USER", null, "uk-UA"), - ru: client.translate("common:USER", null, "ru-RU"), - }), - ), - dirname: __dirname, - ownerOnly: false, - }); - } - - /** - * - * @param {import("../../base/Client")} client - * @param {import("discord.js").ChatInputCommandInteraction} interaction - * @param {Object} data - */ - async execute(client, interaction) { - const member = interaction.options.getMember("user") || interaction.member; - - const embed = client.embed({ - author: { - name: `${member.user.getUsername()} (${member.id})`, - iconURL: member.displayAvatarURL(), - }, - thumbnail: member.displayAvatarURL(), - fields: [ - { - name: ":man: " + interaction.translate("common:USERNAME"), - value: member.user.getUsername(), - inline: true, - }, - { - name: client.customEmojis.pencil + " " + interaction.translate("common:NICKNAME"), - value: member.nickname || interaction.translate("general/userinfo:NO_NICKNAME"), - inline: true, - }, - { - name: client.customEmojis.bot + " " + interaction.translate("common:ROBOT"), - value: member.user.bot ? interaction.translate("common:YES") : interaction.translate("common:NO"), - inline: true, - }, - { - name: client.customEmojis.calendar + " " + interaction.translate("common:CREATION"), - value: ``, - inline: true, - }, - { - name: client.customEmojis.calendar2 + " " + interaction.translate("common:JOINED"), - value: ``, - inline: true, - }, - { - name: client.customEmojis.color + " " + interaction.translate("common:COLOR"), - value: member.displayHexColor, - inline: true, - }, - { - name: client.customEmojis.roles + " " + interaction.translate("common:ROLES"), - value: - member.roles.size > 10 - ? member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", ") + " " + - interaction.translate("general/userinfo:MORE_ROLES", { - count: member.roles.cache.size - 10, - }) - : member.roles.cache.size < 1 ? interaction.translate("general/userinfo:NO_ROLE") : member.roles.cache.map(r => r).filter(r => r.id !== interaction.guild.roles.everyone.id).slice(0, 10).join(", "), - inline: true, - }, - ], - }); - - interaction.reply({ - embeds: [embed], - }); - } -} - -module.exports = Userinfo; diff --git a/languages/en-US/general/info.json b/languages/en-US/general/info.json new file mode 100644 index 00000000..fc869e69 --- /dev/null +++ b/languages/en-US/general/info.json @@ -0,0 +1,17 @@ +{ + "DESCRIPTION": "Shows user/guild information", + "USAGE": "", + "EXAMPLES": "info server\ninfo user @jonny_bro\ninfo user", + "USER": "User info", + "CUSTOM": "Custom Status", + "NO_ACTIVITY": "Not playing", + "NO_ROLE": "No role", + "ROLE": "Top Role", + "NO_NICKNAME": "No nickname", + "MORE_ROLES": "and {{count}} more role(s)", + "SERVER": "Server info", + "AFK_CHANNEL": "AFK Channel", + "BOOSTS": "Number of Boosts", + "LINK": "Server Statistics", + "LINK_TEXT": "Click here to open the server statistics in the control panel" +} \ No newline at end of file diff --git a/languages/en-US/general/reminds.json b/languages/en-US/general/reminds.json index 02d13a8f..5e745298 100644 --- a/languages/en-US/general/reminds.json +++ b/languages/en-US/general/reminds.json @@ -2,7 +2,7 @@ "DESCRIPTION": "Lists your reminds", "USAGE": "", "EXAMPLES": "reminds", - "NO_REMINDS": "No reminds found", + "NO_REMINDS": "No reminds", "REMINDS_LIST": "Reminds List", "DELETE": "Delete {{pos}}", "DELETED": "Deleted remind №{{pos}}" diff --git a/languages/en-US/general/serverinfo.json b/languages/en-US/general/serverinfo.json deleted file mode 100644 index 7f28b772..00000000 --- a/languages/en-US/general/serverinfo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "DESCRIPTION": "Shows server information", - "USAGE": "", - "EXAMPLES": "serverinfo", - "AFK_CHANNEL": "AFK Channel", - "BOOSTS": "Number of Boosts", - "LINK": "Server Statistics", - "LINK_TEXT": "Click here to open the server statistics in the control panel" -} \ No newline at end of file diff --git a/languages/en-US/general/userinfo.json b/languages/en-US/general/userinfo.json deleted file mode 100644 index 4c1afe88..00000000 --- a/languages/en-US/general/userinfo.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "DESCRIPTION": "Shows user information", - "USAGE": "(@user)", - "EXAMPLES": "userinfo\nuserinfo user:@jonny_bro", - "CUSTOM": "Custom Status", - "NO_ACTIVITY": "Not playing", - "NO_ROLE": "No role", - "ROLE": "Top Role", - "NO_NICKNAME": "No nickname", - "MORE_ROLES": "and {{count}} more role(s)" -} \ No newline at end of file diff --git a/languages/ru-RU/general/info.json b/languages/ru-RU/general/info.json new file mode 100644 index 00000000..e4866397 --- /dev/null +++ b/languages/ru-RU/general/info.json @@ -0,0 +1,17 @@ +{ + "DESCRIPTION": "Показать информацию о пользователе/сервере", + "USAGE": "", + "EXAMPLES": "info server\ninfo user @jonny_bro\ninfo user", + "USER": "Информация о пользователе", + "CUSTOM": "Пользовательский статус", + "NO_ACTIVITY": "Не играет", + "NO_ROLE": "Нет роли", + "ROLE": "Высшая роль", + "NO_NICKNAME": "Нет никнейма", + "MORE_ROLES": "и ещё {{count}} роль(и/ей)", + "SERVER": "Информация о сервере", + "AFK_CHANNEL": "AFK канал", + "BOOSTS": "Кол-во бустов", + "LINK": "Статистика сервера", + "LINK_TEXT": "Нажмите сюда, чтобы открыть статистику сервера в панели управления" +} \ No newline at end of file diff --git a/languages/ru-RU/general/serverinfo.json b/languages/ru-RU/general/serverinfo.json deleted file mode 100644 index 13d95478..00000000 --- a/languages/ru-RU/general/serverinfo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "DESCRIPTION": "Показать информацию о сервере", - "USAGE": "", - "EXAMPLES": "serverinfo", - "AFK_CHANNEL": "AFK канал", - "BOOSTS": "Кол-во бустов", - "LINK": "Статистика сервера", - "LINK_TEXT": "Нажмите сюда, чтобы открыть статистику сервера в панели управления" -} \ No newline at end of file diff --git a/languages/ru-RU/general/userinfo.json b/languages/ru-RU/general/userinfo.json deleted file mode 100644 index 98c3e942..00000000 --- a/languages/ru-RU/general/userinfo.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "DESCRIPTION": "Показать информацию о пользователе", - "USAGE": "(@user)", - "EXAMPLES": "userinfo\nuserinfo user:@jonny_bro", - "CUSTOM": "Пользовательский статус", - "NO_ACTIVITY": "Не играет", - "NO_ROLE": "Нет роли", - "ROLE": "Высшая роль", - "NO_NICKNAME": "Нет никнейма", - "MORE_ROLES": "и ещё {{count}} роль(и/ей)" -} \ No newline at end of file diff --git a/languages/uk-UA/general/info.json b/languages/uk-UA/general/info.json new file mode 100644 index 00000000..8e4e0e61 --- /dev/null +++ b/languages/uk-UA/general/info.json @@ -0,0 +1,17 @@ +{ + "DESCRIPTION": "Показати інформацію про користувача/сервер", + "USAGE": "", + "EXAMPLES": "info server\ninfo user @jonny_bro\ninfo user", + "USER": "Інформація про користувача", + "CUSTOM": "Стан користувача", + "NO_ACTIVITY": "Не грає", + "NO_ROLE": "Немає ролі", + "ROLE": "Вища роль", + "NO_NICKNAME": "Немає нікнейму", + "MORE_ROLES": "і ще {{count}} роль(і/ей)", + "SERVER": "Інформація про сервер", + "AFK_CHANNEL": "AFK канал", + "BOOSTS": "К-сть бустів", + "LINK": "Статистика сервера", + "LINK_TEXT": "Натисніть сюди, щоб відкрити статистику сервера на панелі керування" +} \ No newline at end of file diff --git a/languages/uk-UA/general/serverinfo.json b/languages/uk-UA/general/serverinfo.json deleted file mode 100644 index 9b4daf83..00000000 --- a/languages/uk-UA/general/serverinfo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "DESCRIPTION": "Показати інформацію про сервер", - "USAGE": "", - "EXAMPLES": "serverinfo", - "AFK_CHANNEL": "AFK канал", - "BOOSTS": "К-сть бустів", - "LINK": "Статистика сервера", - "LINK_TEXT": "Натисніть сюди, щоб відкрити статистику сервера на панелі керування" - } \ No newline at end of file diff --git a/languages/uk-UA/general/userinfo.json b/languages/uk-UA/general/userinfo.json deleted file mode 100644 index 735aa26a..00000000 --- a/languages/uk-UA/general/userinfo.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "DESCRIPTION": "Показати інформацію про користувача", - "USAGE": "(@user)", - "EXAMPLES": "userinfo\nuserinfo user:@jonny_bro", - "CUSTOM": "Стан користувача", - "NO_ACTIVITY": "Не грає", - "NO_ROLE": "Немає ролі", - "ROLE": "Вища роль", - "NO_NICKNAME": "Немає нікнейму", - "MORE_ROLES": "і ще {{count}} роль(і/ей)" -} \ No newline at end of file diff --git a/package.json b/package.json index 0276ebb6..b00b34e2 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "jaba", - "version": "4.6.3", + "version": "4.6.4", "description": "My Discord Bot", "main": "index.js", "scripts": { "start": "node ." }, - "author": "@jonny_bro", + "author": "https://github.com/JonnyBro", "dependencies": { "@discord-player/extractor": "^4.5.1", "@discordjs/opus": "^0.9.0",