164 lines
5.4 KiB
TypeScript
164 lines
5.4 KiB
TypeScript
import { CommandMessage } from "../../../core/types/commands";
|
|
import type Amayo from "../../../core/client";
|
|
import { queues } from "./play";
|
|
import { DisplayComponentV2Builder } from "../../../core/lib/displayComponents/builders/v2Builder";
|
|
import { sendComponentsV2Message } from "../../../core/api/discordAPI";
|
|
|
|
// Store pagination state per guild
|
|
const queuePages = new Map<string, number>();
|
|
|
|
export const command: CommandMessage = {
|
|
name: "queue",
|
|
type: "message",
|
|
aliases: ["q", "cola", "list"],
|
|
cooldown: 3,
|
|
description: "Muestra la cola de reproducción actual",
|
|
category: "Música",
|
|
usage: "queue [página]",
|
|
run: async (message, args, client: Amayo) => {
|
|
const guildId = message.guild!.id;
|
|
const player = client.music.players.get(guildId);
|
|
const queue = queues.get(guildId);
|
|
|
|
if (!player && (!queue || queue.length === 0)) {
|
|
await message.reply("❌ No hay nada en la cola de reproducción.");
|
|
return;
|
|
}
|
|
|
|
// Get current page from args or stored state
|
|
let page = 1;
|
|
if (args.length > 0) {
|
|
const pageArg = parseInt(args[0]);
|
|
if (!isNaN(pageArg) && pageArg > 0) {
|
|
page = pageArg;
|
|
}
|
|
} else {
|
|
page = queuePages.get(guildId) || 1;
|
|
}
|
|
|
|
// Get currently playing track
|
|
const currentTrack = player?.track as any;
|
|
|
|
// Build queue list
|
|
const queueList = queue || [];
|
|
const itemsPerPage = 10;
|
|
const totalPages = Math.ceil(queueList.length / itemsPerPage);
|
|
|
|
// Validate page number
|
|
if (page > totalPages && totalPages > 0) {
|
|
page = totalPages;
|
|
}
|
|
if (page < 1) {
|
|
page = 1;
|
|
}
|
|
|
|
// Store current page
|
|
queuePages.set(guildId, page);
|
|
|
|
const startIdx = (page - 1) * itemsPerPage;
|
|
const endIdx = Math.min(startIdx + itemsPerPage, queueList.length);
|
|
|
|
// Build display with DisplayComponentV2Builder
|
|
const builder = new DisplayComponentV2Builder()
|
|
.setAccentColor(0x608beb)
|
|
.addText("📋 **En cola**");
|
|
|
|
// Add currently playing track
|
|
if (currentTrack) {
|
|
const duration = formatDuration(currentTrack.info?.length || 0);
|
|
const nowPlayingText = `▶️ **Ahora**: ${currentTrack.info?.title || 'Desconocido'} - ${currentTrack.info?.author || 'Desconocido'} (${duration})`;
|
|
builder.addText(nowPlayingText);
|
|
builder.addSeparator(1, true);
|
|
}
|
|
|
|
// Add queue items
|
|
if (queueList.length === 0) {
|
|
builder.addText("*La cola está vacía*");
|
|
} else {
|
|
builder.addText(`**${queueList.length} ${queueList.length === 1 ? 'canción' : 'canciones'} en cola**`);
|
|
|
|
for (let i = startIdx; i < endIdx; i++) {
|
|
const track = queueList[i] as any;
|
|
const duration = formatDuration(track.info?.length || track.info?.duration || 0);
|
|
const title = track.info?.title || "Desconocido";
|
|
const author = track.info?.author || "Desconocido";
|
|
|
|
builder.addText(`\`${i + 1}.\` ${title} - ${author} (${duration})`);
|
|
}
|
|
}
|
|
|
|
// Calculate total duration
|
|
let totalDuration = 0;
|
|
if (currentTrack) {
|
|
totalDuration += currentTrack.info?.length || 0;
|
|
}
|
|
queueList.forEach((track: any) => {
|
|
totalDuration += track.info?.length || track.info?.duration || 0;
|
|
});
|
|
|
|
const totalDurationText = formatDuration(totalDuration);
|
|
|
|
builder.addSeparator(1, true);
|
|
builder.addText(`⏱️ **Duración total**: ${totalDurationText}`);
|
|
|
|
if (totalPages > 0) {
|
|
builder.addText(`📄 Página ${page}/${totalPages}`);
|
|
}
|
|
|
|
// Create navigation and clear buttons
|
|
const buttons: any[] = [];
|
|
|
|
if (totalPages > 1) {
|
|
buttons.push(
|
|
DisplayComponentV2Builder.createButton(
|
|
"music_queue_prev",
|
|
"◀️",
|
|
2, // secondary
|
|
page === 1 // disabled if first page
|
|
),
|
|
DisplayComponentV2Builder.createButton(
|
|
"music_queue_next",
|
|
"▶️",
|
|
2, // secondary
|
|
page === totalPages // disabled if last page
|
|
)
|
|
);
|
|
}
|
|
|
|
if (queueList.length > 0) {
|
|
buttons.push(
|
|
DisplayComponentV2Builder.createButton(
|
|
"music_queue_clear",
|
|
"🗑️ Limpiar",
|
|
4 // danger
|
|
)
|
|
);
|
|
}
|
|
|
|
if (buttons.length > 0) {
|
|
builder.addActionRow(buttons);
|
|
}
|
|
|
|
await sendComponentsV2Message(message.channel.id, {
|
|
components: [builder.toJSON()],
|
|
});
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Format duration in milliseconds to MM:SS or HH:MM:SS
|
|
*/
|
|
function formatDuration(ms: number): string {
|
|
const seconds = Math.floor(ms / 1000);
|
|
const minutes = Math.floor(seconds / 60);
|
|
const hours = Math.floor(minutes / 60);
|
|
|
|
if (hours > 0) {
|
|
return `${hours}:${String(minutes % 60).padStart(2, "0")}:${String(seconds % 60).padStart(2, "0")}`;
|
|
}
|
|
return `${minutes}:${String(seconds % 60).padStart(2, "0")}`;
|
|
}
|
|
|
|
// Export pagination state for button handlers
|
|
export { queuePages };
|