initial
This commit is contained in:
163
src/commands/messages/music/queue.ts
Normal file
163
src/commands/messages/music/queue.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
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 };
|
||||
Reference in New Issue
Block a user