feat: Better message in music category (#74)
All checks were successful
ci/woodpecker/push/publish Pipeline was successful

- Show repeat mode
- Show current track
- Add progressbar in nowplaying
- Better error message (text)
- Better error message (style)
- Embed when its better

Co-authored-by: Mylloon <kennel.anri@tutanota.com>
Reviewed-on: #74
This commit is contained in:
Mylloon 2023-02-17 23:06:18 +01:00
parent 7b076377c3
commit db5aff64c8
14 changed files with 113 additions and 50 deletions

View file

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

View file

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

View file

@ -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")}`);
},
};

View file

@ -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")}`);
},
};

View file

@ -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")}.`,
});

View file

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

View file

@ -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")}`);
},
};

View file

@ -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")}`);
},
};

View file

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

View file

@ -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<Metadata>, track: Track) => {
queue.metadata?.channel?.send(`🎶 | Joue \`${track.title}\` demandé par ${track.requestedBy}.`);
export default (queue: Queue<Metadata>, 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] });
};

View file

@ -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"
}

View file

@ -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 :"
}

View file

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

View file

@ -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<string, string>) => {
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;
}
};