Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Commit

Permalink
feat: Added /back command to go back in history
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusbegby committed Dec 11, 2023
1 parent a3107a6 commit e11df37
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 7 deletions.
123 changes: 123 additions & 0 deletions src/interactions/commands/player/back.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { GuildQueue, GuildQueueHistory, Track, useHistory, useQueue } from 'discord-player';
import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import { BaseSlashCommandInteraction } from '../../../classes/interactions';
import { BaseSlashCommandParams, BaseSlashCommandReturnType } from '../../../types/interactionTypes';
import { checkHistoryExists, checkQueueCurrentTrack } from '../../../utils/validation/queueValidator';
import { checkInVoiceChannel, checkSameVoiceChannel } from '../../../utils/validation/voiceChannelValidator';
import { Logger } from 'pino';

class BackCommand extends BaseSlashCommandInteraction {
constructor() {
const data = new SlashCommandBuilder()
.setName('back')
.setDescription('Go back to previous track or specified position in history.')
.addNumberOption((option) =>
option.setName('tracknumber').setDescription('The position in history to go back to.').setMinValue(1)
);
super(data);
}

async execute(params: BaseSlashCommandParams): BaseSlashCommandReturnType {
const { executionId, interaction } = params;
const logger = this.getLogger(this.name, executionId, interaction);

const history: GuildQueueHistory = useHistory(interaction.guild!.id)!;

await this.runValidators({ interaction, history, executionId }, [
checkInVoiceChannel,
checkSameVoiceChannel,
checkHistoryExists,
checkQueueCurrentTrack
]);

const backToTrackInput: number = interaction.options.getNumber('tracknumber')!;

if (backToTrackInput) {
return await this.handleBackToTrackPosition(logger, interaction, history, backToTrackInput);
} else {
return await this.handleBackToPreviousTrack(logger, interaction, history);
}
}

private async handleBackToTrackPosition(
logger: Logger,
interaction: ChatInputCommandInteraction,
history: GuildQueueHistory,
backtoTrackPosition: number
) {
if (backtoTrackPosition > history.tracks.data.length) {
return await this.handleTrackNumberHigherThanTotalTracks(backtoTrackPosition, history, logger, interaction);
} else {
await history.back();
const recoveredTrack: Track = history.currentTrack! ?? history.tracks.data[backtoTrackPosition - 1];
logger.debug('Went back to specified track number in history.');
return await this.respondWithSuccessEmbed(recoveredTrack, interaction);
}
}

private async handleTrackNumberHigherThanTotalTracks(
backToTrackPosition: number,
history: GuildQueueHistory,
logger: Logger,
interaction: ChatInputCommandInteraction
) {
logger.debug('Specified track number was higher than total tracks.');
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
`There are only **\`${history.tracks.data.length}\`** tracks in the history. You cannot go back to track **\`${backToTrackPosition}\`**.\n\n` +
'View tracks added in the history with **`/history`**.'
)
.setColor(this.embedOptions.colors.warning)
]
});
}

private async handleBackToPreviousTrack(
logger: Logger,
interaction: ChatInputCommandInteraction,
history: GuildQueueHistory
) {
if (history.tracks.data.length === 0) {
return await this.handleNoTracksInHistory(logger, interaction);
}

await history.back();
const queue: GuildQueue = useQueue(interaction.guild!.id)!;
const currentTrack: Track = queue.currentTrack!;
logger.debug('Recovered track from history.');
return await this.respondWithSuccessEmbed(currentTrack, interaction);
}
private async handleNoTracksInHistory(logger: Logger, interaction: ChatInputCommandInteraction) {
logger.debug('No tracks in history.');
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
'The history is empty, add some tracks with **`/play`**!'
)
.setColor(this.embedOptions.colors.warning)
]
});
}

private async respondWithSuccessEmbed(recoveredTrack: Track, interaction: ChatInputCommandInteraction) {
return await interaction.editReply({
embeds: [
new EmbedBuilder()
.setAuthor(this.getEmbedUserAuthor(interaction))
.setDescription(
`**${this.embedOptions.icons.back} Recovered track**\n` +
`${this.getDisplayTrackDurationAndUrl(recoveredTrack)}`
)
.setThumbnail(this.getTrackThumbnailUrl(recoveredTrack))
.setColor(this.embedOptions.colors.success)
]
});
}
}

export default new BackCommand();
14 changes: 7 additions & 7 deletions src/interactions/commands/player/skip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ class SkipCommand extends BaseSlashCommandInteraction {
const skipToTrackInput: number = interaction.options.getNumber('tracknumber')!;

if (skipToTrackInput) {
return await this.handleSkipToTrack(logger, interaction, queue, skipToTrackInput);
return await this.handleSkipToTrackPosition(logger, interaction, queue, skipToTrackInput);
} else {
return await this.handleSkipToNextTrack(logger, interaction, queue);
}
}

private async handleSkipToTrack(
private async handleSkipToTrackPosition(
logger: Logger,
interaction: ChatInputCommandInteraction,
queue: GuildQueue,
skipToTrack: number
skipToTrackPosition: number
) {
if (skipToTrack > queue.tracks.data.length) {
return await this.handleTrackNumberHigherThanTotalTracks(skipToTrack, queue, logger, interaction);
if (skipToTrackPosition > queue.tracks.data.length) {
return await this.handleTrackNumberHigherThanTotalTracks(skipToTrackPosition, queue, logger, interaction);
} else {
const skippedTrack: Track = queue.currentTrack!;
queue.node.skipTo(skipToTrack - 1);
queue.node.skipTo(skipToTrackPosition - 1);
logger.debug('Skipped to specified track number.');
return await this.respondWithSuccessEmbed(skippedTrack, interaction);
}
Expand Down Expand Up @@ -93,7 +93,7 @@ class SkipCommand extends BaseSlashCommandInteraction {
new EmbedBuilder()
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
'There is nothing currently playing. First add some tracks with **`/play`**!'
'The queue is empty, add some tracks with **`/play`**!'
)
.setColor(this.embedOptions.colors.warning)
]
Expand Down

0 comments on commit e11df37

Please sign in to comment.