diff --git a/src/buttons/music/queueList-next.ts b/src/buttons/music/queueList-next.ts index 7786e51..2b743db 100644 --- a/src/buttons/music/queueList-next.ts +++ b/src/buttons/music/queueList-next.ts @@ -36,7 +36,7 @@ export default { const rows = []; if (queue) { // Create the embed - embedListQueue(client, embed, queue.tracks, page, interaction.locale); + embedListQueue(client, embed, queue, page, interaction.locale); // Create buttons const idPrec = "queueList-prec_" + uuidv4(); diff --git a/src/buttons/music/queueList-prec.ts b/src/buttons/music/queueList-prec.ts index b13c456..5ca54b8 100644 --- a/src/buttons/music/queueList-prec.ts +++ b/src/buttons/music/queueList-prec.ts @@ -36,7 +36,7 @@ export default { const rows = []; if (queue) { // Create the embed - embedListQueue(client, embed, queue.tracks, page, interaction.locale); + embedListQueue(client, embed, queue, page, interaction.locale); // Create buttons const idPrec = "queueList-prec_" + uuidv4(); diff --git a/src/commands/music/lyrics.ts b/src/commands/music/lyrics.ts index 6a82a34..b0f81da 100644 --- a/src/commands/music/lyrics.ts +++ b/src/commands/music/lyrics.ts @@ -48,7 +48,7 @@ export default { try { data = await client.player.lyrics.search(request); } catch { - return await interaction.followUp(loc.get("c_lyrics2") + ` \`${request}\``); + return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${request}\``); } } else { const queue = client.player.queues.get(interaction.guildId ?? ""); @@ -58,7 +58,7 @@ export default { try { data = await client.player.lyrics.search(title); } catch { - return await interaction.followUp(loc.get("c_lyrics2") + ` \`${title}\``); + return await interaction.followUp(`❌ | ${loc.get("c_lyrics2")} \`${title}\``); } } } @@ -114,6 +114,6 @@ export default { return; } - return await interaction.followUp(loc.get("c_lyrics1")); + return await interaction.followUp(`❌ | ${loc.get("c_lyrics1")}`); }, }; diff --git a/src/commands/music/pause.ts b/src/commands/music/pause.ts index 5c286a0..e7733a7 100644 --- a/src/commands/music/pause.ts +++ b/src/commands/music/pause.ts @@ -1,5 +1,5 @@ import { SlashCommandBuilder } from "@discordjs/builders"; -import { ChatInputCommandInteraction, Client } from "discord.js"; +import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js"; import { getLocale, getLocalizations } from "../../utils/locales"; import { getFilename } from "../../utils/misc"; @@ -25,20 +25,20 @@ export default { const queue = client.player.queues.get(interaction.guildId ?? ""); if (queue) { + const embed = new EmbedBuilder(); if (queue.paused) { queue.resume(); - // TODO: Pretty embed - return await interaction.reply(loc.get("c_pause1")); + embed.setDescription(loc.get("c_pause1")); + return await interaction.reply({ embeds: [embed] }); } else { queue.pause(); - // TODO: Pretty embed - return await interaction.reply(loc.get("c_pause2")); + embed.setDescription(loc.get("c_pause2")); + return await interaction.reply({ embeds: [embed] }); } } - // TODO: Pretty embed - return await interaction.reply(loc.get("c_pause3")); + return await interaction.reply(`❌ | ${loc.get("c_pause3")}`); }, }; diff --git a/src/commands/music/play.ts b/src/commands/music/play.ts index f1c17fa..5499761 100644 --- a/src/commands/music/play.ts +++ b/src/commands/music/play.ts @@ -2,6 +2,7 @@ import { SlashCommandBuilder } from "@discordjs/builders"; import { ChatInputCommandInteraction, Client, + EmbedBuilder, GuildResolvable, VoiceBasedChannel, } from "discord.js"; @@ -48,7 +49,7 @@ export default { if (!member?.voice.channelId) { return await interaction.reply({ - content: loc.get("c_play1"), + content: `❌ | ${loc.get("c_play1")}`, ephemeral: true, }); } @@ -58,7 +59,7 @@ export default { member.voice.channelId !== interaction.guild.members.me.voice.channelId ) { return await interaction.reply({ - content: loc.get("c_play2"), + content: `❌ | ${loc.get("c_play2")} ${interaction.guild.members.me.voice.channel}`, ephemeral: true, }); } @@ -75,16 +76,21 @@ export default { if (queue) { const track = queue.nowPlaying(); if (track) { - // TODO: Pretty embed - // Use: createProgressBar - return await interaction.reply( - `${loc.get("c_play7")} \`${track.title}\` - *${track.author}*` - ); + const embed = new EmbedBuilder() + .setDescription( + `${queue.createProgressBar()}\n\n${loc.get("c_play8")} ${track.requestedBy}` + ) + .setTitle(track.title) + .setURL(track.url) + .setThumbnail(track.thumbnail) + .setFooter({ text: loc.get("c_play7") }) + .setTimestamp(); + return await interaction.reply({ embeds: [embed] }); } } - // TODO: Pretty embed - return await interaction.reply(loc.get("c_play6")); + const embed = new EmbedBuilder().setDescription(`❌ | ${loc.get("c_play6")}`); + return await interaction.reply({ embeds: [embed] }); } const queue = client.player.createQueue(interaction.guild as GuildResolvable, { @@ -99,7 +105,7 @@ export default { } catch { queue.destroy(); return await interaction.reply({ - content: loc.get("c_play3"), + content: `❌ | ${loc.get("c_play3")}`, ephemeral: true, }); } @@ -112,8 +118,8 @@ export default { .then((x) => x); if (!result.tracks[0]) { - // TODO: Pretty embed - return await interaction.followUp({ content: `❌ | \`${query}\` ${loc.get("c_play4")}.` }); + const embed = new EmbedBuilder().setDescription(`❌ | \`${query}\` ${loc.get("c_play4")}.`); + return await interaction.followUp({ embeds: [embed] }); } let title; @@ -132,7 +138,6 @@ export default { queue.play(); } - // TODO: Pretty embed return await interaction.followUp({ content: `⏱️ | \`${title}\` ${loc.get("c_play5")}.`, }); diff --git a/src/commands/music/queue.ts b/src/commands/music/queue.ts index e5c8a86..22db84e 100644 --- a/src/commands/music/queue.ts +++ b/src/commands/music/queue.ts @@ -107,7 +107,7 @@ export default { loc_default?.get(`c_${filename}_sub1_opt1_name`) as string ) ?? 1; - embedListQueue(client, embed, queue.tracks, page, interaction.locale); + embedListQueue(client, embed, queue, page, interaction.locale); const idPrec = "queueList-prec_" + uuidv4(); const idNext = "queueList-next_" + uuidv4(); diff --git a/src/commands/music/repeat.ts b/src/commands/music/repeat.ts index 9c811f7..b330d99 100644 --- a/src/commands/music/repeat.ts +++ b/src/commands/music/repeat.ts @@ -72,31 +72,31 @@ export default { // Disable case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": { queue.setRepeatMode(QueueRepeatMode.OFF); - return interaction.reply(loc.get("c_repeat2")); + return interaction.reply(loc.get("c_repeat2") + "."); } // Queue Repeat case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "": { queue.setRepeatMode(QueueRepeatMode.QUEUE); - return interaction.reply(loc.get("c_repeat3") + " " + loc.get("c_repeat6")); + return interaction.reply(`${loc.get("c_repeat3")} ${loc.get("c_repeat6")}.`); } // Autoplay case loc_default?.get(`c_${filename}_sub4_name`)?.toLowerCase() ?? "": { queue.setRepeatMode(QueueRepeatMode.AUTOPLAY); - return interaction.reply(loc.get("c_repeat4") + " " + loc.get("c_repeat6")); + return interaction.reply(`${loc.get("c_repeat4")} ${loc.get("c_repeat6")}.`); } // Track repeat case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": { queue.setRepeatMode(QueueRepeatMode.TRACK); return interaction.reply( - loc.get("c_repeat5") + ` ${queue.nowPlaying()?.title} ` + loc.get("c_repeat6") + `${loc.get("c_repeat5")} ${queue.nowPlaying()?.title} ${loc.get("c_repeat6")}.` ); } } } - return await interaction.reply(loc.get("c_repeat1")); + return await interaction.reply(`❌ | ${loc.get("c_repeat1")}`); }, }; diff --git a/src/commands/music/skip.ts b/src/commands/music/skip.ts index 66838a6..261799b 100644 --- a/src/commands/music/skip.ts +++ b/src/commands/music/skip.ts @@ -53,6 +53,6 @@ export default { return await interaction.reply(msg); } - return await interaction.reply(loc.get("c_skip2")); + return await interaction.reply(`❌ | ${loc.get("c_skip2")}`); }, }; diff --git a/src/commands/music/stop.ts b/src/commands/music/stop.ts index 3379335..cd96d1a 100644 --- a/src/commands/music/stop.ts +++ b/src/commands/music/stop.ts @@ -31,7 +31,7 @@ export default { }); if (!(queue.connection || queue.playing)) { - return interaction.reply(loc.get("c_stop1")); + return interaction.reply(`❌ | ${loc.get("c_stop1")}`); } queue.destroy(); diff --git a/src/events/player/trackStart.ts b/src/events/player/trackStart.ts index d8d4f29..d733690 100644 --- a/src/events/player/trackStart.ts +++ b/src/events/player/trackStart.ts @@ -1,7 +1,23 @@ +import { EmbedBuilder } from "@discordjs/builders"; import { Queue, Track } from "discord-player"; +import { Client } from "discord.js"; import { Metadata } from "../../utils/metadata"; +import { emojiPng } from "../../utils/misc"; /** https://discord-player.js.org/docs/main/master/typedef/PlayerEvents */ -export default (queue: Queue, track: Track) => { - queue.metadata?.channel?.send(`🎶 | Joue \`${track.title}\` demandé par ${track.requestedBy}.`); +export default (queue: Queue, track: Track, client: Client) => { + const loc_default = client.locales.get(client.config.default_lang); + + const embed = new EmbedBuilder() + .setDescription(`${loc_default?.get("e_trackstart1")} ${track.requestedBy}`) + .setTitle(track.title) + .setURL(track.url) + .setThumbnail(track.thumbnail) + .setFooter({ + text: `${loc_default?.get("e_trackstart2")} ${ + track.duration + } via ${track.source.capitalize()}`, + iconURL: emojiPng("🎶"), + }); + queue.metadata?.channel?.send({ embeds: [embed] }); }; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index bf0b227..1a1a03c 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -82,7 +82,7 @@ "c_play_opt1_name": "query", "c_play_opt1_desc": "What you want to listen to", "c_play1": "You're not in any vocal channel.", - "c_play2": "I am already in a voice channel.", + "c_play2": "You are in the wrong voice channel, I am in", "c_play3": "Unable to join the voice channel.", "c_play4": "not found", "c_play5": "added to the queue", @@ -121,7 +121,8 @@ "c_queue7": "Page", "c_queue8": "Previous", "c_queue9": "Next", - "c_queue10": "Sorry, an error occurred.", + "c_queue10": "Currently", + "c_queue11": "Coming up", "c_skip_name": "skip", "c_skip_desc": "Play the current song", @@ -149,9 +150,9 @@ "c_repeat_sub4_name": "autoplay", "c_repeat_sub4_desc": "Activates automatic playback", "c_repeat1": "The bot is not playing anything right now.", - "c_repeat2": "Repeat disabled.", + "c_repeat2": "Repeat disabled", "c_repeat3": "Repeating the queue", "c_repeat4": "Automatic playback", "c_repeat5": "Repeating the song", - "c_repeat6": "activated." + "c_repeat6": "enabled" } diff --git a/src/locales/fr.json b/src/locales/fr.json index c662026..da817db 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -82,12 +82,13 @@ "c_play_opt1_name": "requête", "c_play_opt1_desc": "Ce que vous voulez écouter", "c_play1": "Tu n'es dans aucun salon vocal.", - "c_play2": "Je suis déjà en vocal.", + "c_play2": "Tu es dans le mauvais salon vocal, je suis dans", "c_play3": "Impossible de rejoindre le salon vocal.", "c_play4": "introuvable", "c_play5": "ajouté à la file d'attente", "c_play6": "Le bot ne joue rien en ce moment.", "c_play7": "Joue actuellement", + "c_play8": "Demandé par", "c_stop_name": "stop", "c_stop_desc": "Stop la musique", @@ -121,7 +122,8 @@ "c_queue7": "Page", "c_queue8": "Précédent", "c_queue9": "Suivant", - "c_queue10": "Désolé, une erreur est survenue.", + "c_queue10": "Actuellement", + "c_queue11": "À suivre", "c_skip_name": "skip", "c_skip_desc": "Passe la chanson en cours", @@ -149,9 +151,12 @@ "c_repeat_sub4_name": "autoplay", "c_repeat_sub4_desc": "Active la lecture automatique", "c_repeat1": "Le bot ne joue rien en ce moment.", - "c_repeat2": "Répétition désactivé.", + "c_repeat2": "Répétition désactivé", "c_repeat3": "Répétition de la file d'attente", "c_repeat4": "Lecture automatique", "c_repeat5": "Répétition de la chanson", - "c_repeat6": "activé." + "c_repeat6": "activé", + + "e_trackstart1": "Demandé par", + "e_trackstart2": "Durée :" } diff --git a/src/utils/misc.ts b/src/utils/misc.ts index beac077..8a24cbc 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -102,3 +102,13 @@ export const cleanCodeBlock = (text: string) => { return text; }; + +/** + * Returns the emoji URL as png, only works with one-composed emoji code + * @param emoji Emoji + * @returns URL of emoji as png + */ +export const emojiPng = (emoji: string) => + `https://cdn.jsdelivr.net/gh/twitter/twemoji/assets/72x72/${emoji + .codePointAt(0) + ?.toString(16)}.png`; diff --git a/src/utils/music.ts b/src/utils/music.ts index 1d5426d..21bf43d 100644 --- a/src/utils/music.ts +++ b/src/utils/music.ts @@ -1,16 +1,20 @@ import { EmbedBuilder } from "@discordjs/builders"; -import { Track } from "discord-player"; +import { Queue, QueueRepeatMode, Track } from "discord-player"; import { Client } from "discord.js"; import { getLocale } from "./locales"; export const embedListQueue = ( client: Client, embed: EmbedBuilder, - tracks: Track[], + queue: Queue, page: number, local: string ) => { const loc = getLocale(client, local); + const tracks = queue.tracks.slice(); + + // Add the current song at the top of the list + tracks.unshift(queue.current as Track); // Limit of discord is 25 const limit_fields = 25; @@ -18,11 +22,33 @@ export const embedListQueue = ( const pageMax = Math.ceil(tracks.length / limit_fields); embed.setAuthor({ name: `${loc.get("c_queue1")} • ${loc.get("c_queue7")} ${page}/${pageMax}` }); + embed.setFooter({ text: `${printRepeatMode(queue.repeatMode, loc)}` }); - tracks.slice((page - 1) * limit_fields, page * limit_fields).forEach((t, idx) => + tracks.slice((page - 1) * limit_fields, page * limit_fields).forEach((t, idx) => { + const name = idx == 0 ? loc.get("c_queue10") : idx == 1 ? loc.get("c_queue11") : "\u200b"; + const idx_track = idx == 0 ? "" : `${idx * page}. `; embed.addFields({ - name: "\u200b", - value: `${(idx + 1) * page}. [${t.title}](${t.url}) (${t.duration})`, - }) - ); + name, + value: `${idx_track}[${t.title}](${t.url}) (${t.duration})`, + }); + }); +}; + +const printRepeatMode = (mode: QueueRepeatMode, loc: Map) => { + switch (mode) { + case QueueRepeatMode.OFF: + return loc.get("c_repeat2"); + + case QueueRepeatMode.QUEUE: + return loc.get("c_repeat3") + " " + loc.get("c_repeat6"); + + case QueueRepeatMode.AUTOPLAY: + return loc.get("c_repeat4") + " " + loc.get("c_repeat6"); + + case QueueRepeatMode.TRACK: + return loc.get("c_repeat5") + " " + loc.get("c_repeat6"); + + default: + break; + } };