Files
amayo/src/commands/messages/music/queue.ts
2025-12-01 18:59:48 +00:00

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 };