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

Commit

Permalink
feat: Updated /remove command with options for range, queue, user and…
Browse files Browse the repository at this point in the history
… duplicates!
  • Loading branch information
mariusbegby committed Dec 13, 2023
1 parent e7f7b7a commit 27d4c6c
Showing 1 changed file with 169 additions and 24 deletions.
193 changes: 169 additions & 24 deletions src/interactions/commands/player/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class RemoveCommand extends BaseSlashCommandInteraction {
.addSubcommand((subcommand) =>
subcommand
.setName('track')
.setDescription('Remove a track from the queue')
.setDescription('Remove a track from the queue by position')
.addIntegerOption((option) =>
option
.setName('position')
Expand Down Expand Up @@ -43,6 +43,14 @@ class RemoveCommand extends BaseSlashCommandInteraction {
.addSubcommand((subcommand) =>
subcommand.setName('queue').setDescription('Remove all tracks from the queue')
)
.addSubcommand((subcommand) =>
subcommand
.setName('user')
.setDescription('Remove all tracks from a specific user')
.addUserOption((option) =>
option.setName('target').setDescription('User to remove tracks for').setRequired(true)
)
)
.addSubcommand((subcommand) =>
subcommand.setName('duplicates').setDescription('Remove all duplicate tracks from the queue')
);
Expand All @@ -64,67 +72,204 @@ class RemoveCommand extends BaseSlashCommandInteraction {
const subcommand = interaction.options.getSubcommand();

switch (subcommand) {
case 'track':
return await this.handleRemovedTrack(logger, interaction, queue);
case 'range':
return await this.handleRemoveRange(logger, interaction, queue);
case 'queue':
return await this.handleRemoveQueue(logger, interaction, queue);
case 'user':
return await this.handleRemoveUserTracks(logger, interaction, queue);
case 'duplicates':
return await this.handleRemoveDuplicates(logger, interaction, queue);
default:
return Promise.resolve();
}
}

private async handleRemoveUserTracks(logger: Logger, interaction: ChatInputCommandInteraction, queue: GuildQueue) {
const targetUser = interaction.options.getUser('target')!;
const removedTracks: Track[] = [];
queue.tracks.data.forEach((track) => {
if (track.requestedBy?.id === targetUser.id) {
const removedTrack = queue.node.remove(track);
if (removedTrack) {
removedTracks.push(removedTrack);
}
}
});

if (removedTracks.length === 0) {
return await this.handleNoTracksRemoved(logger, interaction);
}

logger.debug(`Removed ${removedTracks.length} tracks from queue added by a user.`);

return await this.handleResponseRemovedTracks(logger, interaction, removedTracks.length);
}

private async handleRemoveDuplicates(logger: Logger, interaction: ChatInputCommandInteraction, queue: GuildQueue) {
const removedTracks: Track[] = [];
const uniqueTrackUrls = new Set<string>();
queue.tracks.data.forEach((track) => {
if (uniqueTrackUrls.has(track.url)) {
const removedTrack = queue.node.remove(track);
if (removedTrack) {
removedTracks.push(removedTrack);
}
} else {
uniqueTrackUrls.add(track.url);
}
});

if (removedTracks.length === 0) {
return await this.handleNoTracksRemoved(logger, interaction);
}

logger.debug(`Removed ${removedTracks.length} duplicate tracks from queue.`);

return await this.handleResponseRemovedTracks(logger, interaction, removedTracks.length);
}

private async handleRemoveRange(logger: Logger, interaction: ChatInputCommandInteraction, queue: GuildQueue) {
const start: number = interaction.options.getInteger('start')!;
const end: number = interaction.options.getInteger('end')!;

if (start > queue.tracks.data.length || end > queue.tracks.data.length) {
return await this.handleTrackPositionHigherThanQueueLength(logger, interaction, start, queue);
} else if (start > end) {
logger.debug('Start position is higher than end position.');

logger.debug('Responding with warning embed.');
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
`Start position **\`${start}\`** is higher than end position **\`${end}\`**. Please specify a valid range.` +
'\n\nView tracks added to the queue with **`/queue`**.'
)
.setColor(this.embedOptions.colors.warning)
]
});
return Promise.resolve();
}

const trackPositionInput: number = interaction.options.getNumber('position')!;
const removedTracks: Track[] = [];
for (let i = start; i <= end; i++) {
const track = queue.node.remove(start - 1);
if (track) {
removedTracks.push(track);
}
}

if (removedTracks.length === 0) {
return await this.handleNoTracksRemoved(logger, interaction);
}

logger.debug(`Removed ${removedTracks.length} tracks from queue.`);

return await this.handleResponseRemovedTracks(logger, interaction, removedTracks.length);
}

private async handleRemoveQueue(logger: Logger, interaction: ChatInputCommandInteraction, queue: GuildQueue) {
const queueLength = queue.tracks.data.length;
queue.clear();

if (queueLength === 0) {
return await this.handleNoTracksRemoved(logger, interaction);
}

logger.debug('Cleared the queue and removed all tracks.');

return await this.handleResponseRemovedTracks(logger, interaction, queueLength);
}

private async handleRemovedTrack(logger: Logger, interaction: ChatInputCommandInteraction, queue: GuildQueue) {
const trackPositionInput: number = interaction.options.getInteger('position')!;

if (trackPositionInput > queue.tracks.data.length) {
return await this.handleTrackPositionHigherThanQueueLength(logger, interaction, trackPositionInput, queue);
}

return await this.removeTrackFromQueue(logger, interaction, queue, trackPositionInput);
}
const removedTrack: Track = queue.node.remove(trackPositionInput - 1)!;
logger.debug(`Removed track '${removedTrack.url}' from queue.`);

private async handleTrackPositionHigherThanQueueLength(
logger: Logger,
interaction: ChatInputCommandInteraction,
trackPositionInput: number,
queue: GuildQueue
) {
logger.debug('Specified track position is higher than total tracks.');
logger.debug('Responding with success embed.');
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setAuthor(this.getEmbedUserAuthor(interaction))
.setDescription(
`**${this.embedOptions.icons.success} Removed track**\n${this.getDisplayTrackDurationAndUrl(
removedTrack
)}`
)
.setThumbnail(this.getTrackThumbnailUrl(removedTrack))
.setColor(this.embedOptions.colors.success)
]
});
return Promise.resolve();
}

private async handleNoTracksRemoved(logger: Logger, interaction: ChatInputCommandInteraction) {
logger.debug('Responding with warning embed.');
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setAuthor(this.getEmbedUserAuthor(interaction))
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
`Track **\`${trackPositionInput}\`** is not a valid track position. There are a total of **\`${queue.tracks.data.length}\`** tracks in the queue.` +
'\n\nView tracks added to the queue with **`/queue`**.'
`**${this.embedOptions.icons.warning} No tracks removed**\n` +
'There were no tracks removed from the queue. Please check if the option you selected has tracks to remove.'
)
.setColor(this.embedOptions.colors.warning)
]
});
return Promise.resolve();
}

private async removeTrackFromQueue(
private async handleResponseRemovedTracks(
logger: Logger,
interaction: ChatInputCommandInteraction,
queue: GuildQueue,
trackPositionInput: number
removedAmount: number
) {
const removedTrack: Track = queue.node.remove(trackPositionInput - 1)!;
logger.debug(`Removed track '${removedTrack.url}' from queue.`);

logger.debug('Responding with success embed.');
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setAuthor(this.getEmbedUserAuthor(interaction))
.setDescription(
`**${this.embedOptions.icons.success} Removed track**\n${this.getDisplayTrackDurationAndUrl(
removedTrack
)}`
`**${this.embedOptions.icons.success} Removed tracks**\n` +
`**\`${removedAmount}\`** tracks were removed from the queue.`
)
.setThumbnail(this.getTrackThumbnailUrl(removedTrack))
.setColor(this.embedOptions.colors.success)
]
});
return Promise.resolve();
}

private async handleTrackPositionHigherThanQueueLength(
logger: Logger,
interaction: ChatInputCommandInteraction,
trackPositionInput: number,
queue: GuildQueue
) {
logger.debug('Specified track position is higher than total tracks.');

logger.debug('Responding with warning embed.');
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setDescription(
`**${this.embedOptions.icons.warning} Oops!**\n` +
`Position **\`${trackPositionInput}\`** is not a valid track position. There are only a total of **\`${queue.tracks.data.length}\`** tracks in the queue.` +
'\n\nView tracks added to the queue with **`/queue`**.'
)
.setColor(this.embedOptions.colors.warning)
]
});
return Promise.resolve();
}
}

export default new RemoveCommand();

0 comments on commit 27d4c6c

Please sign in to comment.