feat: Music support #62
5 changed files with 215 additions and 11 deletions
72
src/buttons/music/queueList-next.ts
Normal file
72
src/buttons/music/queueList-next.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import {
|
||||||
|
ActionRowBuilder,
|
||||||
|
ButtonBuilder,
|
||||||
|
ButtonStyle,
|
||||||
|
Client,
|
||||||
|
EmbedBuilder,
|
||||||
|
MessageComponentInteraction,
|
||||||
|
} from "discord.js";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { getLocale } from "../../utils/locales";
|
||||||
|
import { getFilename } from "../../utils/misc";
|
||||||
|
import { embedListQueue } from "../../utils/music";
|
||||||
|
import { collect } from "../loader";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: {
|
||||||
|
name: getFilename(__filename),
|
||||||
|
},
|
||||||
|
interaction: async (interaction: MessageComponentInteraction, client: Client) => {
|
||||||
|
const loc = getLocale(client, interaction.locale);
|
||||||
|
const embed_desc = interaction.message.embeds.at(0)?.author?.name as string;
|
||||||
|
|
||||||
|
// Retrieve Pages
|
||||||
|
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||||
|
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||||
|
if (page + 1 > pageMax) {
|
||||||
|
page = 1;
|
||||||
|
} else {
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get queue
|
||||||
|
const queue = client.player.queues.get(interaction.guildId ?? "");
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder();
|
||||||
|
const rows = [];
|
||||||
|
if (queue) {
|
||||||
|
// Create the embed
|
||||||
|
embedListQueue(client, embed, queue.tracks, page, interaction.locale);
|
||||||
|
|
||||||
|
// Create buttons
|
||||||
|
const idPrec = "queueList-prec_" + uuidv4();
|
||||||
|
const idNext = "queueList-next_" + uuidv4();
|
||||||
|
rows.push(
|
||||||
|
new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idPrec)
|
||||||
|
.setLabel(loc.get("c_queue8"))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idNext)
|
||||||
|
.setLabel(loc.get("c_queue9"))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buttons interactions
|
||||||
|
collect(client, interaction, idPrec);
|
||||||
|
collect(client, interaction, idNext);
|
||||||
|
} else {
|
||||||
|
// In case queue doesn't exists
|
||||||
|
embed.setDescription(loc.get("c_queue2"));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
embeds: [embed],
|
||||||
|
components: rows,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
72
src/buttons/music/queueList-prec.ts
Normal file
72
src/buttons/music/queueList-prec.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import {
|
||||||
|
ActionRowBuilder,
|
||||||
|
ButtonBuilder,
|
||||||
|
ButtonStyle,
|
||||||
|
Client,
|
||||||
|
EmbedBuilder,
|
||||||
|
MessageComponentInteraction,
|
||||||
|
} from "discord.js";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { getLocale } from "../../utils/locales";
|
||||||
|
import { getFilename } from "../../utils/misc";
|
||||||
|
import { embedListQueue } from "../../utils/music";
|
||||||
|
import { collect } from "../loader";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: {
|
||||||
|
name: getFilename(__filename),
|
||||||
|
},
|
||||||
|
interaction: async (interaction: MessageComponentInteraction, client: Client) => {
|
||||||
|
const loc = getLocale(client, interaction.locale);
|
||||||
|
const embed_desc = interaction.message.embeds.at(0)?.author?.name as string;
|
||||||
|
|
||||||
|
// Retrieve Pages
|
||||||
|
const pageMax = Number(/(\d+)(?!.*\d)/gm.exec(embed_desc)?.[0]);
|
||||||
|
let page = Number(/(?!• \s+)\d(?=\/)/gm.exec(embed_desc)?.[0]);
|
||||||
|
if (page - 1 == 0) {
|
||||||
|
page = pageMax;
|
||||||
|
} else {
|
||||||
|
page--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get queue
|
||||||
|
const queue = client.player.queues.get(interaction.guildId ?? "");
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder();
|
||||||
|
const rows = [];
|
||||||
|
if (queue) {
|
||||||
|
// Create the embed
|
||||||
|
embedListQueue(client, embed, queue.tracks, page, interaction.locale);
|
||||||
|
|
||||||
|
// Create buttons
|
||||||
|
const idPrec = "queueList-prec_" + uuidv4();
|
||||||
|
const idNext = "queueList-next_" + uuidv4();
|
||||||
|
rows.push(
|
||||||
|
new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idPrec)
|
||||||
|
.setLabel(loc.get("c_queue8"))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idNext)
|
||||||
|
.setLabel(loc.get("c_queue9"))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buttons interactions
|
||||||
|
collect(client, interaction, idPrec);
|
||||||
|
collect(client, interaction, idNext);
|
||||||
|
} else {
|
||||||
|
// In case queue doesn't exists
|
||||||
|
embed.setDescription(loc.get("c_queue2"));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
embeds: [embed],
|
||||||
|
components: rows,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,7 +1,17 @@
|
||||||
import { SlashCommandBuilder } from "@discordjs/builders";
|
import { SlashCommandBuilder } from "@discordjs/builders";
|
||||||
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
|
import {
|
||||||
|
ActionRowBuilder,
|
||||||
|
ButtonBuilder,
|
||||||
|
ButtonStyle,
|
||||||
|
ChatInputCommandInteraction,
|
||||||
|
Client,
|
||||||
|
EmbedBuilder,
|
||||||
|
} from "discord.js";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { collect } from "../../buttons/loader";
|
||||||
import { getLocale, getLocalizations } from "../../utils/locales";
|
import { getLocale, getLocalizations } from "../../utils/locales";
|
||||||
import { getFilename } from "../../utils/misc";
|
import { getFilename } from "../../utils/misc";
|
||||||
|
import { embedListQueue } from "../../utils/music";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
scope: () => [],
|
scope: () => [],
|
||||||
|
@ -85,24 +95,42 @@ export default {
|
||||||
const queue = client.player.queues.get(interaction.guildId ?? "");
|
const queue = client.player.queues.get(interaction.guildId ?? "");
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
|
const rows = [];
|
||||||
|
|
||||||
if (queue) {
|
if (queue) {
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const subcommand = interaction.options.getSubcommand();
|
||||||
switch (subcommand) {
|
switch (subcommand) {
|
||||||
// Show the queue
|
// Show the queue
|
||||||
case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": {
|
case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": {
|
||||||
embed.setAuthor({ name: loc.get("c_queue1") });
|
const page =
|
||||||
|
interaction.options.getNumber(
|
||||||
|
loc_default?.get(`c_${filename}_sub1_opt1_name`) as string
|
||||||
|
) ?? 1;
|
||||||
|
|
||||||
const tracks = queue.tracks;
|
embedListQueue(client, embed, queue.tracks, page, interaction.locale);
|
||||||
// TODO: Add pages for +25 tracks on a queue
|
|
||||||
// Limit of discord is 25
|
const idPrec = "queueList-prec_" + uuidv4();
|
||||||
tracks.slice(0, 25).forEach((t, idx) =>
|
const idNext = "queueList-next_" + uuidv4();
|
||||||
embed.addFields({
|
rows.push(
|
||||||
name: "\u200b",
|
new ActionRowBuilder<ButtonBuilder>()
|
||||||
value: `${idx + 1}. [${t.title}](${t.url}) (${t.duration})`,
|
.addComponents(
|
||||||
})
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idPrec)
|
||||||
|
.setLabel(loc.get(`c_${filename}8`))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(idNext)
|
||||||
|
.setLabel(loc.get(`c_${filename}9`))
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Buttons interactions
|
||||||
|
collect(client, interaction, idPrec);
|
||||||
|
collect(client, interaction, idNext);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +165,6 @@ export default {
|
||||||
embed.setDescription(loc.get("c_queue2"));
|
embed.setDescription(loc.get("c_queue2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return await interaction.reply({ embeds: [embed] });
|
return await interaction.reply({ embeds: [embed], components: rows });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,6 +116,10 @@
|
||||||
"c_queue4": "Musique",
|
"c_queue4": "Musique",
|
||||||
"c_queue5": "supprimée",
|
"c_queue5": "supprimée",
|
||||||
"c_queue6": "Cette ID n'existe pas.",
|
"c_queue6": "Cette ID n'existe pas.",
|
||||||
|
"c_queue7": "Page",
|
||||||
|
"c_queue8": "Précédent",
|
||||||
|
"c_queue9": "Suivant",
|
||||||
|
"c_queue10": "Désolé, une erreur est survenue.",
|
||||||
"c_skip_name": "skip",
|
"c_skip_name": "skip",
|
||||||
"c_skip_desc": "Passe la chanson en cours",
|
"c_skip_desc": "Passe la chanson en cours",
|
||||||
"c_skip_opt1_name": "id",
|
"c_skip_opt1_name": "id",
|
||||||
|
|
28
src/utils/music.ts
Normal file
28
src/utils/music.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { EmbedBuilder } from "@discordjs/builders";
|
||||||
|
import { Track } from "discord-player";
|
||||||
|
import { Client } from "discord.js";
|
||||||
|
import { getLocale } from "./locales";
|
||||||
|
|
||||||
|
export const embedListQueue = (
|
||||||
|
client: Client,
|
||||||
|
embed: EmbedBuilder,
|
||||||
|
tracks: Track[],
|
||||||
|
page: number,
|
||||||
|
local: string
|
||||||
|
) => {
|
||||||
|
const loc = getLocale(client, local);
|
||||||
|
|
||||||
|
// Limit of discord is 25
|
||||||
|
const limit_fields = 25;
|
||||||
|
|
||||||
|
const pageMax = Math.ceil(tracks.length / limit_fields);
|
||||||
|
|
||||||
|
embed.setAuthor({ name: `${loc.get("c_queue1")} • ${loc.get("c_queue7")} ${page}/${pageMax}` });
|
||||||
|
|
||||||
|
tracks.slice((page - 1) * limit_fields, page * limit_fields).forEach((t, idx) =>
|
||||||
|
embed.addFields({
|
||||||
|
name: "\u200b",
|
||||||
|
value: `${(idx + 1) * page}. [${t.title}](${t.url}) (${t.duration})`,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in a new issue