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

Commit

Permalink
feat(commands/music): create remove command
Browse files Browse the repository at this point in the history
  • Loading branch information
Mednoob committed Dec 14, 2021
1 parent e9f878a commit ac20a7a
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@
"queue": {
"description": "Show the queue list"
},
"remove": {
"description": "Remove song(s) from the queue",
"slashPositionDescription": "Position of the songs to remove separated by comma or space",
"usage": "{prefix}remove <positions>",
"noPermission": "You don't have permission to use this command",
"noPositions": "Please, specify the song positions to remove.",
"songsRemoved": "Removed {removed} songs from the queue.",
"songSkip": "One of the removed song is the now-playing song. Song skipped."
},
"repeat": {
"description": "Repeat current music or the queue",
"slashQueue": "Set repeat mode to **`QUEUE`**",
Expand Down
79 changes: 79 additions & 0 deletions src/commands/music/RemoveCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { haveQueue, inVC, sameVC } from "../../utils/decorators/MusicUtil";
import { parseHTMLElements } from "../../utils/parseHTMLElements";
import { CommandContext } from "../../structures/CommandContext";
import { ButtonPagination } from "../../utils/ButtonPagination";
import { BaseCommand } from "../../structures/BaseCommand";
import { createEmbed } from "../../utils/createEmbed";
import { IQueueSong } from "../../typings";
import { chunk } from "../../utils/chunk";
import { AudioPlayerState, AudioResource } from "@discordjs/voice";
import { Util } from "discord.js";

export class RemoveCommand extends BaseCommand {
public constructor(client: BaseCommand["client"]) {
super(client, {
description: i18n.__("commands.music.remove.description"),
name: "remove",
slash: {
options: [
{
description: i18n.__("commands.music.remove.slashPositionsDescription"),
name: "positions",
required: true,
type: "STRING"
}
]
},
usage: i18n.__("commands.music.remove.usage")
});
}

public async execute(ctx: CommandContext): Promise<void> {
if (!inVC(ctx)) return;
if (!haveQueue(ctx)) return;
if (!sameVC(ctx)) return;

const djRole = await this.client.utils.fetchDJRole(ctx.guild!);
if (!ctx.member?.roles.cache.has(djRole.id) && !ctx.member?.permissions.has("MANAGE_GUILD")) {
void ctx.reply({ embeds: [createEmbed("error", i18n.__("commands.music.remove.noPermission"), true)] });
return;
}

const positions = (ctx.options?.getString("positions") ?? ctx.args.join(" ")).split(/[, ]/).filter(Boolean);
if (!positions.length) {
void ctx.reply({ embeds: [createEmbed("error", i18n.__("commands.music.remove.noPositions"), true)] });
return;
}

const cloned = [...ctx.guild!.queue!.songs.sortByIndex().values()];
const songs = positions.map(x => cloned[parseInt(x) - 1]).filter(Boolean);
for (const song of songs) {
ctx.guild!.queue!.songs.delete(song.key);
}

const np = (ctx.guild?.queue?.player?.state as (AudioPlayerState & { resource: AudioResource|undefined })|undefined)?.resource?.metadata as IQueueSong|undefined;
if (songs.map(x => x.key).includes(np?.key as string)) {
this.client.commands.get("skip")?.execute(ctx);
}

const opening = i18n.__mf("commands.music.remove.songsRemoved", { removed: songs.length, additional: i18n.__("commands.music.remove.songSkip") });
const pages = await Promise.all(chunk(songs, 10).map(async (v, i) => {
const texts = await Promise.all(v.map((song, index) => `${(i * 10) + (index + 1)}.) ${Util.escapeMarkdown(parseHTMLElements(song.song.title))}`));

return texts.join("\n");
}));
const getText = (page: string): string => `\`\`\`\n${opening}${page}\`\`\``;
const embed = createEmbed("info", getText(pages[0])).setFooter(`• ${i18n.__mf("reusable.pageFooter", { actual: 1, total: pages.length })}`);
const msg = await ctx.reply({ embeds: [embed] }).catch(() => undefined);

if (!msg) return;
void new ButtonPagination(msg, {
author: ctx.author.id,
edit: (i, e, p) => {
e.setDescription(getText(p)).setFooter(`• ${i18n.__mf("reusable.pageFooter", { actual: i + 1, total: pages.length })}`);
},
embed,
pages
}).start();
}
}

0 comments on commit ac20a7a

Please sign in to comment.