Files
2024-10-26 20:33:18 +08:00

126 lines
3.6 KiB
TypeScript

import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ChatInputCommandInteraction,
CommandInteraction,
EmbedBuilder,
Interaction,
SlashCommandBuilder
} from "discord.js";
import { bot } from "../index";
import { Song } from "../structs/Song";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("queue").setDescription(i18n.__("queue.description")),
cooldown: 5,
async execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
if (!queue || !queue.songs.length) return interaction.reply({ content: i18n.__("queue.errorNotQueue") });
let currentPage = 0;
const embeds = generateQueueEmbed(interaction, queue.songs);
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("previous").setLabel("⬅️").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("stop").setLabel("⏹").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("next").setLabel("➡️").setStyle(ButtonStyle.Secondary)
);
await interaction.reply("⏳ Loading queue...");
if (interaction.replied)
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage")} ${currentPage + 1}/${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row]
});
const queueEmbed = await interaction.fetchReply();
const filter = (buttonInteraction: Interaction) =>
buttonInteraction.isButton() && buttonInteraction.user.id === interaction.user.id;
const collector = queueEmbed.createMessageComponentCollector({ filter, time: 60000 });
const buttonHandlers = {
next: async () => {
if (currentPage >= embeds.length - 1) return;
currentPage++;
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage", {
page: currentPage + 1,
length: embeds.length
})}**`,
embeds: [embeds[currentPage]],
components: [row]
});
},
previous: async () => {
if (currentPage === 0) return;
currentPage--;
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage", {
page: currentPage + 1,
length: embeds.length
})}**`,
embeds: [embeds[currentPage]],
components: [row]
});
},
stop: async () => {
await interaction.editReply({
components: []
});
collector.stop();
}
};
collector.on("collect", async (buttonInteraction) => {
buttonInteraction.deferUpdate();
const handler = buttonHandlers[buttonInteraction.customId as keyof typeof buttonHandlers];
if (handler) {
await handler();
}
});
collector.on("end", () => {
queueEmbed
.edit({
components: []
})
.catch(console.error);
});
}
};
function generateQueueEmbed(interaction: CommandInteraction, songs: Song[]) {
let embeds = [];
let k = 10;
for (let i = 0; i < songs.length; i += 10) {
const current = songs.slice(i, k);
let j = i;
k += 10;
const info = current.map((track) => `${++j} - [${track.title}](${track.url})`).join("\n");
const embed = new EmbedBuilder()
.setTitle(i18n.__("queue.embedTitle"))
.setThumbnail(interaction.guild?.iconURL()!)
.setColor("#F8AA2A")
.setDescription(i18n.__mf("queue.embedCurrentSong", { title: songs[0].title, url: songs[0].url, info: info }))
.setTimestamp();
embeds.push(embed);
}
return embeds;
}