aboutsummaryrefslogtreecommitdiff
path: root/src/commands/queue.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/queue.ts')
-rw-r--r--src/commands/queue.ts106
1 files changed, 52 insertions, 54 deletions
diff --git a/src/commands/queue.ts b/src/commands/queue.ts
index 1c0735c..479bc33 100644
--- a/src/commands/queue.ts
+++ b/src/commands/queue.ts
@@ -1,82 +1,80 @@
-import {Message, MessageEmbed} from 'discord.js';
-import getYouTubeID from 'get-youtube-id';
+import {ButtonInteraction, CommandInteraction} from 'discord.js';
+import {SlashCommandBuilder} from '@discordjs/builders';
import {inject, injectable} from 'inversify';
import {TYPES} from '../types.js';
import PlayerManager from '../managers/player.js';
-import {STATUS} from '../services/player.js';
+import UpdatingQueueEmbedManager from '../managers/updating-queue-embed.js';
+import {BUTTON_IDS} from '../services/updating-queue-embed.js';
import Command from '.';
-import getProgressBar from '../utils/get-progress-bar.js';
-import errorMsg from '../utils/error-msg.js';
-import {prettyTime} from '../utils/time.js';
-
-const PAGE_SIZE = 10;
@injectable()
export default class implements Command {
- public name = 'queue';
- public aliases = ['q'];
- public examples = [
- ['queue', 'shows current queue'],
- ['queue 2', 'shows second page of queue'],
- ];
+ public readonly slashCommand = new SlashCommandBuilder()
+ .setName('queue')
+ .setDescription('show the current queue');
+
+ public readonly handledButtonIds = Object.values(BUTTON_IDS);
private readonly playerManager: PlayerManager;
+ private readonly updatingQueueEmbedManager: UpdatingQueueEmbedManager;
- constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager) {
+ constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager, @inject(TYPES.Managers.UpdatingQueueEmbed) updatingQueueEmbedManager: UpdatingQueueEmbedManager) {
this.playerManager = playerManager;
+ this.updatingQueueEmbedManager = updatingQueueEmbedManager;
}
- public async execute(msg: Message, args: string []): Promise<void> {
- const player = this.playerManager.get(msg.guild!.id);
-
- const currentlyPlaying = player.getCurrent();
-
- if (currentlyPlaying) {
- const queueSize = player.queueSize();
- const queuePage = args[0] ? parseInt(args[0], 10) : 1;
-
- const maxQueuePage = Math.ceil((queueSize + 1) / PAGE_SIZE);
+ public async executeFromInteraction(interaction: CommandInteraction) {
+ const embed = this.updatingQueueEmbedManager.get(interaction.guild!.id);
- if (queuePage > maxQueuePage) {
- await msg.channel.send(errorMsg('the queue isn\'t that big'));
- return;
- }
+ await embed.createFromInteraction(interaction);
+ }
- const embed = new MessageEmbed();
+ public async handleButtonInteraction(interaction: ButtonInteraction) {
+ const player = this.playerManager.get(interaction.guild!.id);
+ const embed = this.updatingQueueEmbedManager.get(interaction.guild!.id);
- embed.setTitle(currentlyPlaying.title);
- embed.setURL(`https://www.youtube.com/watch?v=${currentlyPlaying.url.length === 11 ? currentlyPlaying.url : getYouTubeID(currentlyPlaying.url) ?? ''}`);
+ const buttonId = interaction.customId as keyof typeof this.handledButtonIds;
- let description = player.status === STATUS.PLAYING ? 'âšī¸' : 'â–ļī¸';
- description += ' ';
- description += getProgressBar(20, player.getPosition() / currentlyPlaying.length);
- description += ' ';
- description += `\`[${prettyTime(player.getPosition())}/${currentlyPlaying.isLive ? 'live' : prettyTime(currentlyPlaying.length)}]\``;
- description += ' 🔉';
- description += player.isQueueEmpty() ? '' : '\n\n**Next up:**';
+ // Not entirely sure why this is necessary.
+ // We don't wait for the Promise to resolve here to avoid blocking the
+ // main logic. However, we need to wait for the Promise to be resolved before
+ // throwing as otherwise a race condition pops up when bot.ts tries updating
+ // the interaction.
+ const deferedUpdatePromise = interaction.deferUpdate();
- embed.setDescription(description);
+ try {
+ switch (buttonId) {
+ case BUTTON_IDS.TRACK_BACK:
+ await player.back();
+ break;
- let footer = `Source: ${currentlyPlaying.artist}`;
+ case BUTTON_IDS.TRACK_FORWARD:
+ await player.forward(1);
+ break;
- if (currentlyPlaying.playlist) {
- footer += ` (${currentlyPlaying.playlist.title})`;
- }
+ case BUTTON_IDS.PAUSE:
+ player.pause();
+ break;
- embed.setFooter(footer);
+ case BUTTON_IDS.PLAY:
+ await player.play();
+ break;
- const queuePageBegin = (queuePage - 1) * PAGE_SIZE;
- const queuePageEnd = queuePageBegin + PAGE_SIZE;
+ case BUTTON_IDS.PAGE_BACK:
+ await embed.pageBack();
+ break;
- player.getQueue().slice(queuePageBegin, queuePageEnd).forEach((song, i) => {
- embed.addField(`${(i + 1 + queuePageBegin).toString()}/${queueSize.toString()}`, song.title, false);
- });
+ case BUTTON_IDS.PAGE_FORWARD:
+ await embed.pageForward();
+ break;
- embed.addField('Page', `${queuePage} out of ${maxQueuePage}`, false);
+ default:
+ throw new Error('unknown customId');
+ }
+ } catch (error: unknown) {
+ await deferedUpdatePromise;
- await msg.channel.send({embeds: [embed]});
- } else {
- await msg.channel.send('queue empty');
+ throw error;
}
}
}