From 850ea31a6dc8daa288fdb6f85c6a973ca3915dab Mon Sep 17 00:00:00 2001 From: RainyXeon Date: Sat, 7 Sep 2024 17:42:35 +0700 Subject: [PATCH] add: new interface for setup (check log below) add: filter select menu (#100) add: some extra button in the bottom (#148) --- src/@types/Button.ts | 2 +- src/buttons/Clear.ts | 4 +- src/buttons/Loop.ts | 4 +- src/buttons/Pause.ts | 18 +- src/buttons/Previous.ts | 4 +- src/buttons/Queue.ts | 4 +- src/buttons/Shuffle.ts | 4 +- src/buttons/Skip.ts | 4 +- src/buttons/Stop.ts | 4 +- src/buttons/VolumeDown.ts | 4 +- src/buttons/VolumeUp.ts | 4 +- src/commands/Utils/Setup.ts | 7 +- src/database/setup/setup.ts | 7 +- src/events/player/playerPause.ts | 25 +- src/events/player/playerResume.ts | 20 +- src/events/track/trackStart.ts | 6 +- src/handlers/Player/ButtonCommands/Loop.ts | 101 -------- src/handlers/Player/ButtonCommands/Pause.ts | 96 -------- .../Player/ButtonCommands/Previous.ts | 71 ------ src/handlers/Player/ButtonCommands/Skip.ts | 76 ------ src/handlers/Player/ButtonCommands/Stop.ts | 70 ------ src/handlers/Player/loadContent.ts | 227 ++++++++++++------ src/handlers/Player/loadSetup.ts | 99 -------- src/handlers/Player/loadUpdate.ts | 13 +- src/handlers/loadPlayer.ts | 2 - src/manager.ts | 3 - src/services/ReplyInteractionService.ts | 12 +- src/utilities/PlayerControlButton.ts | 54 +++-- 28 files changed, 293 insertions(+), 652 deletions(-) delete mode 100644 src/handlers/Player/ButtonCommands/Loop.ts delete mode 100644 src/handlers/Player/ButtonCommands/Pause.ts delete mode 100644 src/handlers/Player/ButtonCommands/Previous.ts delete mode 100644 src/handlers/Player/ButtonCommands/Skip.ts delete mode 100644 src/handlers/Player/ButtonCommands/Stop.ts delete mode 100644 src/handlers/Player/loadSetup.ts diff --git a/src/@types/Button.ts b/src/@types/Button.ts index 763b6a9d..edded538 100644 --- a/src/@types/Button.ts +++ b/src/@types/Button.ts @@ -10,6 +10,6 @@ export class PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise {} } diff --git a/src/buttons/Clear.ts b/src/buttons/Clear.ts index 6dbc889f..ba0831f8 100644 --- a/src/buttons/Clear.ts +++ b/src/buttons/Clear.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } player.queue.clear() diff --git a/src/buttons/Loop.ts b/src/buttons/Loop.ts index c1d7ad46..7d70a1ba 100644 --- a/src/buttons/Loop.ts +++ b/src/buttons/Loop.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } diff --git a/src/buttons/Pause.ts b/src/buttons/Pause.ts index fa2bb57d..c3bd2b40 100644 --- a/src/buttons/Pause.ts +++ b/src/buttons/Pause.ts @@ -18,23 +18,33 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } + player.data.set('pause-from-button', true) + const newPlayer = await player.setPause(!player.paused) newPlayer.paused ? nplaying .edit({ - components: [playerRowOneEdited(client), playerRowTwo(client), filterSelect(client)], + components: [ + filterSelect(client, false), + playerRowOneEdited(client, false), + playerRowTwo(client, false), + ], }) .catch(() => null) : nplaying .edit({ - components: [playerRowOne(client), playerRowTwo(client), filterSelect(client)], + components: [ + filterSelect(client, false), + playerRowOne(client, false), + playerRowTwo(client, false), + ], }) .catch(() => null) diff --git a/src/buttons/Previous.ts b/src/buttons/Previous.ts index 826e5b65..f3b656ab 100644 --- a/src/buttons/Previous.ts +++ b/src/buttons/Previous.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } const previousIndex = player.queue.previous.length - 1 diff --git a/src/buttons/Queue.ts b/src/buttons/Queue.ts index 82a4d2ca..a59cae5b 100644 --- a/src/buttons/Queue.ts +++ b/src/buttons/Queue.ts @@ -19,9 +19,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } const song = player.queue.current diff --git a/src/buttons/Shuffle.ts b/src/buttons/Shuffle.ts index da2c610b..2a28d745 100644 --- a/src/buttons/Shuffle.ts +++ b/src/buttons/Shuffle.ts @@ -21,9 +21,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } diff --git a/src/buttons/Skip.ts b/src/buttons/Skip.ts index cf1e9463..bccb7863 100644 --- a/src/buttons/Skip.ts +++ b/src/buttons/Skip.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } diff --git a/src/buttons/Stop.ts b/src/buttons/Stop.ts index aec26013..6b95bc7f 100644 --- a/src/buttons/Stop.ts +++ b/src/buttons/Stop.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - collector.stop() + if (collector) collector.stop() player.data.set('sudo-destroy', true) const is247 = await client.db.autoreconnect.get(`${message.guildId}`) diff --git a/src/buttons/VolumeDown.ts b/src/buttons/VolumeDown.ts index 5c9bbca7..ac9abb7e 100644 --- a/src/buttons/VolumeDown.ts +++ b/src/buttons/VolumeDown.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } diff --git a/src/buttons/VolumeUp.ts b/src/buttons/VolumeUp.ts index 061c8960..65fd95e6 100644 --- a/src/buttons/VolumeUp.ts +++ b/src/buttons/VolumeUp.ts @@ -12,9 +12,9 @@ export default class implements PlayerButton { language: string, player: RainlinkPlayer, nplaying: Message, - collector: InteractionCollector> + collector?: InteractionCollector> ): Promise { - if (!player) { + if (!player && collector) { collector.stop() } diff --git a/src/commands/Utils/Setup.ts b/src/commands/Utils/Setup.ts index 3f0cfd38..785a1c06 100644 --- a/src/commands/Utils/Setup.ts +++ b/src/commands/Utils/Setup.ts @@ -2,6 +2,7 @@ import { EmbedBuilder, ApplicationCommandOptionType, ChannelType } from 'discord import { Manager } from '../../manager.js' import { Accessableby, Command } from '../../structures/Command.js' import { CommandHandler } from '../../structures/CommandHandler.js' +import { filterSelect, playerRowOne, playerRowTwo } from '../../utilities/PlayerControlButton.js' export default class implements Command { public name = ['setup'] @@ -92,7 +93,11 @@ export default class implements Command { const channel_msg = await textChannel.send({ content: `${queueMsg}`, embeds: [playEmbed], - components: [client.diSwitch], + components: [ + filterSelect(client, true), + playerRowOne(client, true), + playerRowTwo(client, true), + ], }) const voiceChannel = await handler.guild!.channels.create({ diff --git a/src/database/setup/setup.ts b/src/database/setup/setup.ts index 707d2657..70a4851c 100644 --- a/src/database/setup/setup.ts +++ b/src/database/setup/setup.ts @@ -1,4 +1,5 @@ import { Manager } from '../../manager.js' +import { filterSelect, playerRowOne, playerRowTwo } from '../../utilities/PlayerControlButton.js' import { Setup } from '../schema/Setup.js' import { EmbedBuilder, TextChannel } from 'discord.js' @@ -55,7 +56,11 @@ export class SongRequesterCleanSetup { .edit({ content: `${queueMsg}`, embeds: [playEmbed], - components: [this.client.diSwitch], + components: [ + filterSelect(this.client, true), + playerRowOne(this.client, true), + playerRowTwo(this.client, true), + ], }) .catch((e) => {}) } diff --git a/src/events/player/playerPause.ts b/src/events/player/playerPause.ts index b3bcc59b..cfd60c0a 100644 --- a/src/events/player/playerPause.ts +++ b/src/events/player/playerPause.ts @@ -1,4 +1,8 @@ -import { playerRowOneEdited, playerRowTwo } from '../../utilities/PlayerControlButton.js' +import { + filterSelect, + playerRowOneEdited, + playerRowTwo, +} from '../../utilities/PlayerControlButton.js' import { Manager } from '../../manager.js' import { TextChannel } from 'discord.js' import { RainlinkPlayer } from 'rainlink' @@ -10,7 +14,13 @@ export default class { const nowPlaying = client.nplayingMsg.get(`${player.guildId}`) if (nowPlaying) { nowPlaying.msg - .edit({ components: [playerRowOneEdited(client), playerRowTwo(client)] }) + .edit({ + components: [ + filterSelect(client, false), + playerRowOneEdited(client, false), + playerRowTwo(client, false), + ], + }) .catch(() => null) } @@ -22,11 +32,20 @@ export default class { const channel = await client.channels.fetch(setup.channel).catch(() => undefined) if (!channel) return if (!channel.isTextBased) return + if (player.data.get('pause-from-button')) return player.data.delete('pause-from-button') const msg = await (channel as TextChannel).messages .fetch(setup.playmsg) .catch(() => undefined) if (!msg) return - msg.edit({ components: [client.enSwitch] }).catch(() => null) + msg + .edit({ + components: [ + filterSelect(client, false), + playerRowOneEdited(client, false), + playerRowTwo(client, false), + ], + }) + .catch(() => null) } } } diff --git a/src/events/player/playerResume.ts b/src/events/player/playerResume.ts index b201be95..5d1fd775 100644 --- a/src/events/player/playerResume.ts +++ b/src/events/player/playerResume.ts @@ -1,4 +1,4 @@ -import { playerRowOne, playerRowTwo } from '../../utilities/PlayerControlButton.js' +import { filterSelect, playerRowOne, playerRowTwo } from '../../utilities/PlayerControlButton.js' import { Manager } from '../../manager.js' import { TextChannel } from 'discord.js' import { RainlinkPlayer } from 'rainlink' @@ -10,7 +10,13 @@ export default class { const nowPlaying = client.nplayingMsg.get(`${player.guildId}`) if (nowPlaying) { nowPlaying.msg - .edit({ components: [playerRowOne(client), playerRowTwo(client)] }) + .edit({ + components: [ + filterSelect(client, false), + playerRowOne(client, false), + playerRowTwo(client, false), + ], + }) .catch(() => null) } @@ -26,7 +32,15 @@ export default class { .fetch(setup.playmsg) .catch(() => undefined) if (!msg) return - msg.edit({ components: [client.enSwitchMod] }).catch(() => null) + msg + .edit({ + components: [ + filterSelect(client, false), + playerRowOne(client, false), + playerRowTwo(client, false), + ], + }) + .catch(() => null) } } } diff --git a/src/events/track/trackStart.ts b/src/events/track/trackStart.ts index bc8652bf..975d88ad 100644 --- a/src/events/track/trackStart.ts +++ b/src/events/track/trackStart.ts @@ -120,7 +120,11 @@ export default class { const nplaying = playing_channel ? await playing_channel.send({ embeds: [embeded], - components: [filterSelect(client), playerRowOne(client), playerRowTwo(client)], + components: [ + filterSelect(client, false), + playerRowOne(client, false), + playerRowTwo(client, false), + ], // files: client.config.bot.SAFE_PLAYER_MODE ? [] : [attachment], }) : undefined diff --git a/src/handlers/Player/ButtonCommands/Loop.ts b/src/handlers/Player/ButtonCommands/Loop.ts deleted file mode 100644 index 36215e81..00000000 --- a/src/handlers/Player/ButtonCommands/Loop.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { ButtonInteraction, EmbedBuilder } from 'discord.js' -import { Manager } from '../../../manager.js' -import { AutoReconnectBuilderService } from '../../../services/AutoReconnectBuilderService.js' -import { RainlinkLoopMode, RainlinkPlayer } from 'rainlink' - -export class ButtonLoop { - client: Manager - interaction: ButtonInteraction - language: string - player: RainlinkPlayer - constructor( - client: Manager, - interaction: ButtonInteraction, - language: string, - player: RainlinkPlayer - ) { - this.client = client - this.language = language - this.player = player - this.interaction = interaction - this.execute() - } - - async execute() { - if (!this.player) { - return - } - - switch (this.player.loop) { - case 'none': - this.player.setLoop(RainlinkLoopMode.SONG) - - if (this.client.config.utilities.AUTO_RESUME) this.setLoop247(String(RainlinkLoopMode.SONG)) - - const looptrack = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'loop_current')}`) - .setColor(this.client.color) - await this.interaction.reply({ - content: ' ', - embeds: [looptrack], - }) - - this.client.wsl.get(this.interaction.guild!.id)?.send({ - op: 'playerLoop', - guild: this.interaction.guild!.id, - mode: 'song', - }) - break - - case 'song': - this.player.setLoop(RainlinkLoopMode.QUEUE) - - if (this.client.config.utilities.AUTO_RESUME) - this.setLoop247(String(RainlinkLoopMode.QUEUE)) - - const loopall = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'loop_all')}`) - .setColor(this.client.color) - await this.interaction.reply({ - content: ' ', - embeds: [loopall], - }) - - this.client.wsl.get(this.interaction.guild!.id)?.send({ - op: 'playerLoop', - guild: this.interaction.guild!.id, - mode: 'queue', - }) - break - - case 'queue': - this.player.setLoop(RainlinkLoopMode.NONE) - - if (this.client.config.utilities.AUTO_RESUME) this.setLoop247(String(RainlinkLoopMode.NONE)) - - const unloopall = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'unloop_all')}`) - .setColor(this.client.color) - await this.interaction.reply({ - content: ' ', - embeds: [unloopall], - }) - - this.client.wsl.get(this.interaction.guild!.id)?.send({ - op: 'playerLoop', - guild: this.interaction.guild!.id, - mode: 'none', - }) - break - } - } - - async setLoop247(loop: string) { - const check = await new AutoReconnectBuilderService(this.client, this.player).execute( - this.player.guildId - ) - if (check) { - await this.client.db.autoreconnect.set(`${this.player.guildId}.config.loop`, loop) - } - } -} diff --git a/src/handlers/Player/ButtonCommands/Pause.ts b/src/handlers/Player/ButtonCommands/Pause.ts deleted file mode 100644 index d24d3f08..00000000 --- a/src/handlers/Player/ButtonCommands/Pause.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { ButtonInteraction, EmbedBuilder, TextChannel, VoiceBasedChannel } from 'discord.js' -import { Manager } from '../../../manager.js' -import { RainlinkPlayer } from 'rainlink' - -export class ButtonPause { - client: Manager - interaction: ButtonInteraction - channel: VoiceBasedChannel | null - language: string - player: RainlinkPlayer - constructor( - client: Manager, - interaction: ButtonInteraction, - channel: VoiceBasedChannel | null, - language: string, - player: RainlinkPlayer - ) { - this.channel = channel - this.client = client - this.language = language - this.player = player - this.interaction = interaction - this.execute() - } - - async execute() { - let data = await this.client.db.setup.get(`${this.player.guildId}`) - if (!data) return - if (data.enable === false) return - - if (!this.channel) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_in_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if ( - this.interaction.guild!.members.me!.voice.channel && - !this.interaction.guild!.members.me!.voice.channel.equals(this.channel) - ) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_same_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if (!this.player) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_player')}`) - .setColor(this.client.color), - ], - }) - return - } else { - const getChannel = await this.client.channels.fetch(data.channel).catch(() => undefined) - if (!getChannel) return - let playMsg = await (getChannel as TextChannel)!.messages - .fetch(data.playmsg) - .catch(() => undefined) - if (!playMsg) return - - const newPlayer = await this.player.setPause(!this.player.paused) - - newPlayer.paused - ? playMsg - .edit({ - // content: playMsg.content, - // embeds: new EmbedBuilder(playMsg.embeds), - components: [this.client.enSwitch], - }) - .catch(() => null) - : playMsg - .edit({ - // content: playMsg.content, - // embeds: playMsg.embeds, - components: [this.client.enSwitchMod], - }) - .catch(() => null) - - const embed = new EmbedBuilder() - .setDescription( - `${this.client.i18n.get(this.language, 'button.music', newPlayer.paused ? 'pause_msg' : 'resume_msg')}` - ) - .setColor(this.client.color) - - this.interaction.reply({ embeds: [embed] }) - } - } -} diff --git a/src/handlers/Player/ButtonCommands/Previous.ts b/src/handlers/Player/ButtonCommands/Previous.ts deleted file mode 100644 index 1cfb29c0..00000000 --- a/src/handlers/Player/ButtonCommands/Previous.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ButtonInteraction, EmbedBuilder, VoiceBasedChannel } from 'discord.js' -import { Manager } from '../../../manager.js' -import { RainlinkPlayer } from 'rainlink' - -export class ButtonPrevious { - client: Manager - interaction: ButtonInteraction - channel: VoiceBasedChannel | null - language: string - player: RainlinkPlayer - constructor( - client: Manager, - interaction: ButtonInteraction, - channel: VoiceBasedChannel | null, - language: string, - player: RainlinkPlayer - ) { - this.channel = channel - this.client = client - this.language = language - this.player = player - this.interaction = interaction - this.execute() - } - - async execute() { - if (!this.channel) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_in_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if ( - this.interaction.guild!.members.me!.voice.channel && - !this.interaction.guild!.members.me!.voice.channel.equals(this.channel) - ) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_same_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if (!this.player || this.player.queue.previous.length == 0) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription( - `${this.client.i18n.get(this.language, 'button.music', 'previous_notfound')}` - ) - .setColor(this.client.color), - ], - }) - return - } else { - this.player.previous() - - this.player.data.set('endMode', 'previous') - - const embed = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'previous_msg')}`) - .setColor(this.client.color) - - this.interaction.reply({ embeds: [embed] }) - } - } -} diff --git a/src/handlers/Player/ButtonCommands/Skip.ts b/src/handlers/Player/ButtonCommands/Skip.ts deleted file mode 100644 index fa7be6ea..00000000 --- a/src/handlers/Player/ButtonCommands/Skip.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { ButtonInteraction, EmbedBuilder, VoiceBasedChannel } from 'discord.js' -import { Manager } from '../../../manager.js' -import { RainlinkPlayer } from 'rainlink' - -export class ButtonSkip { - client: Manager - interaction: ButtonInteraction - channel: VoiceBasedChannel | null - language: string - player: RainlinkPlayer - constructor( - client: Manager, - interaction: ButtonInteraction, - channel: VoiceBasedChannel | null, - language: string, - player: RainlinkPlayer - ) { - this.channel = channel - this.client = client - this.language = language - this.player = player - this.interaction = interaction - this.execute() - } - - async execute() { - if (!this.channel) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_in_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if ( - this.interaction.guild!.members.me!.voice.channel && - !this.interaction.guild!.members.me!.voice.channel.equals(this.channel) - ) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_same_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if (!this.player) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_player')}`) - .setColor(this.client.color), - ], - }) - return - } else { - } - - if (this.player.queue.size == 0 && this.player.data.get('autoplay') !== true) { - const embed = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'skip_notfound')}`) - .setColor(this.client.color) - - this.interaction.reply({ embeds: [embed] }) - } else { - await this.player.skip() - - const embed = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'skip_msg')}`) - .setColor(this.client.color) - - this.interaction.reply({ embeds: [embed] }) - } - } -} diff --git a/src/handlers/Player/ButtonCommands/Stop.ts b/src/handlers/Player/ButtonCommands/Stop.ts deleted file mode 100644 index db96fae7..00000000 --- a/src/handlers/Player/ButtonCommands/Stop.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ButtonInteraction, EmbedBuilder, VoiceBasedChannel } from 'discord.js' -import { Manager } from '../../../manager.js' -import { RainlinkPlayer } from 'rainlink' - -export class ButtonStop { - client: Manager - interaction: ButtonInteraction - channel: VoiceBasedChannel | null - language: string - player: RainlinkPlayer - constructor( - client: Manager, - interaction: ButtonInteraction, - channel: VoiceBasedChannel | null, - language: string, - player: RainlinkPlayer - ) { - this.channel = channel - this.client = client - this.language = language - this.player = player - this.interaction = interaction - this.execute() - } - - async execute() { - if (!this.channel) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_in_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if ( - this.interaction.guild!.members.me!.voice.channel && - !this.interaction.guild!.members.me!.voice.channel.equals(this.channel) - ) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_same_voice')}`) - .setColor(this.client.color), - ], - }) - return - } else if (!this.player) { - this.interaction.reply({ - embeds: [ - new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'error', 'no_player')}`) - .setColor(this.client.color), - ], - }) - return - } else { - this.player.data.set('sudo-destroy', true) - const is247 = await this.client.db.autoreconnect.get(`${this.player.guildId}`) - await this.player.stop(is247 && is247.twentyfourseven ? false : true) - await this.client.UpdateMusic(this.player) - - const embed = new EmbedBuilder() - .setDescription(`${this.client.i18n.get(this.language, 'button.music', 'stop_msg')}`) - .setColor(this.client.color) - - this.interaction.reply({ embeds: [embed] }) - } - } -} diff --git a/src/handlers/Player/loadContent.ts b/src/handlers/Player/loadContent.ts index 1e4b0dd8..96f02960 100644 --- a/src/handlers/Player/loadContent.ts +++ b/src/handlers/Player/loadContent.ts @@ -1,16 +1,17 @@ import { Manager } from '../../manager.js' -import { EmbedBuilder, Message, GuildMember, TextChannel } from 'discord.js' +import { + EmbedBuilder, + Message, + GuildMember, + TextChannel, + StringSelectMenuInteraction, +} from 'discord.js' import { GlobalInteraction } from '../../@types/Interaction.js' -// Button Commands -import { ButtonPrevious } from './ButtonCommands/Previous.js' -import { ButtonSkip } from './ButtonCommands/Skip.js' -import { ButtonStop } from './ButtonCommands/Stop.js' -import { ButtonLoop } from './ButtonCommands/Loop.js' -import { ButtonPause } from './ButtonCommands/Pause.js' import { RateLimitManager } from '@sapphire/ratelimits' import { convertTime } from '../../utilities/ConvertTime.js' import { getTitle } from '../../utilities/GetTitle.js' import { BlacklistService } from '../../services/BlacklistService.js' +import { RainlinkFilterMode } from 'rainlink' const rateLimitManager = new RateLimitManager(2000) /** @@ -26,42 +27,46 @@ export class PlayerContentLoader { register() { try { - this.client.on('interactionCreate', this.interaction.bind(null, this.client)) - this.client.on('messageCreate', this.message.bind(null, this.client)) + this.client.on('interactionCreate', (interaction) => this.interaction(interaction)) + this.client.on('messageCreate', (message) => this.message(message)) } catch (err) { this.client.logger.error(PlayerContentLoader.name, err) } } - async interaction(client: Manager, interaction: GlobalInteraction): Promise { + async interaction(interaction: GlobalInteraction): Promise { if (!interaction.guild || interaction.user.bot) return + if (interaction.isStringSelectMenu()) { + return this.filterSelect(interaction) + } if (!interaction.isButton()) return - const { customId, member } = interaction - let voiceMember = await interaction.guild.members - .fetch((member as GuildMember)!.id) - .catch(() => undefined) - let channel = voiceMember!.voice.channel + const { customId } = interaction - let player = client.rainlink.players.get(interaction.guild.id) + let player = this.client.rainlink.players.get(interaction.guild.id) if (!player) return - const playChannel = await client.channels.fetch(player.textId).catch(() => undefined) + const playChannel = await this.client.channels.fetch(player.textId).catch(() => undefined) if (!playChannel) return - let guildModel = await client.db.language.get(`${player.guildId}`) + let guildModel = await this.client.db.language.get(`${player.guildId}`) if (!guildModel) { - guildModel = await client.db.language.set(`${player.guildId}`, client.config.bot.LANGUAGE) + guildModel = await this.client.db.language.set( + `${player.guildId}`, + this.client.config.bot.LANGUAGE + ) } const language = guildModel //////////////////////////////// Blacklist check start //////////////////////////////// - const blacklistService = new BlacklistService(client) + const blacklistService = new BlacklistService(this.client) const checkResult = await blacklistService.fullCheck(interaction.user.id, interaction.guildId) if (checkResult[0] && checkResult[1] == 'user') { const blocked = new EmbedBuilder() - .setDescription(client.i18n.get(guildModel, 'error', 'bl_user', { bot: client.user.id })) - .setColor(client.color) + .setDescription( + this.client.i18n.get(guildModel, 'error', 'bl_user', { bot: this.client.user.id }) + ) + .setColor(this.client.color) await interaction.reply({ embeds: [blocked], }) @@ -69,8 +74,10 @@ export class PlayerContentLoader { } if (checkResult[0] && checkResult[1] == 'guild') { const blocked = new EmbedBuilder() - .setDescription(client.i18n.get(guildModel, 'error', 'bl_guild', { bot: client.user.id })) - .setColor(client.color) + .setDescription( + this.client.i18n.get(guildModel, 'error', 'bl_guild', { bot: this.client.user.id }) + ) + .setColor(this.client.color) await interaction.reply({ embeds: [blocked], @@ -78,32 +85,101 @@ export class PlayerContentLoader { return } //////////////////////////////// Blacklist check end //////////////////////////////// + const button = this.client.plButton.get(customId) + + let data = await this.client.db.setup.get(`${player.guildId}`) + if (!data) return + if (data.enable === false) return + + const getChannel = await this.client.channels.fetch(data.channel).catch(() => undefined) + if (!getChannel) return + + let playMsg = await (getChannel as TextChannel)!.messages + .fetch(data.playmsg) + .catch(() => undefined) + + if (!playMsg) return - switch (customId) { - case 'sprevious': - new ButtonPrevious(client, interaction, channel, language, player) - break - case 'sskip': - new ButtonSkip(client, interaction, channel, language, player) - break - case 'sstop': - new ButtonStop(client, interaction, channel, language, player) - break - case 'sloop': - new ButtonLoop(client, interaction, language, player) - break - case 'spause': - new ButtonPause(client, interaction, channel, language, player) - break - default: - break + if (button) { + try { + await button.run(this.client, interaction, String(language), player, playMsg) + } catch (err) { + this.client.logger.error('ButtonError', err) + } } } - async message(client: Manager, message: Message): Promise { + async filterSelect(interaction: StringSelectMenuInteraction): Promise { + if (!interaction.guild || interaction.user.bot) return + + let player = this.client.rainlink.players.get(interaction.guild.id) + if (!player) return + + const playChannel = await this.client.channels.fetch(player.textId).catch(() => undefined) + if (!playChannel) return + + let guildModel = await this.client.db.language.get(`${player.guildId}`) + if (!guildModel) { + guildModel = await this.client.db.language.set( + `${player.guildId}`, + this.client.config.bot.LANGUAGE + ) + } + + const language = guildModel + + const filterMode = interaction.values[0] as RainlinkFilterMode + + if (player.data.get('filter-mode') == filterMode) { + const embed = new EmbedBuilder() + .setDescription( + `${this.client.i18n.get(language, 'button.music', 'filter_already', { name: filterMode })}` + ) + .setColor(this.client.color) + await interaction + .reply({ + embeds: [embed], + }) + .catch(() => {}) + return + } + + if (filterMode == 'clear' && !player.data.get('filter-mode')) { + const embed = new EmbedBuilder() + .setDescription(`${this.client.i18n.get(language, 'button.music', 'reset_already')}`) + .setColor(this.client.color) + await interaction + .reply({ + embeds: [embed], + }) + .catch(() => {}) + return + } + + filterMode == 'clear' + ? player.data.delete('filter-mode') + : player.data.set('filter-mode', filterMode) + filterMode == 'clear' ? await player.filter.clear() : await player.filter.set(filterMode) + + const embed = new EmbedBuilder() + .setDescription( + filterMode == 'clear' + ? `${this.client.i18n.get(language, 'button.music', 'reset_on')}` + : `${this.client.i18n.get(language, 'button.music', 'filter_on', { name: filterMode })}` + ) + .setColor(this.client.color) + + await interaction + .reply({ + embeds: [embed], + }) + .catch(() => {}) + } + + async message(message: Message): Promise { if (!message.guild || !message.guild.available || !message.channel.isTextBased()) return - let database = await client.db.setup.get(`${message.guild.id}`) - let player = client.rainlink.players.get(`${message.guild.id}`) + let database = await this.client.db.setup.get(`${message.guild.id}`) + let player = this.client.rainlink.players.get(`${message.guild.id}`) if (!database) return @@ -116,9 +192,12 @@ export class PlayerContentLoader { if (database!.channel != message.channel.id) return - let guildModel = await client.db.language.get(`${message.guild.id}`) + let guildModel = await this.client.db.language.get(`${message.guild.id}`) if (!guildModel) { - guildModel = await client.db.language.set(`${message.guild.id}`, client.config.bot.LANGUAGE) + guildModel = await this.client.db.language.set( + `${message.guild.id}`, + this.client.config.bot.LANGUAGE + ) } const language = guildModel @@ -135,7 +214,7 @@ export class PlayerContentLoader { const final = fetchedMessage.filter((msg) => msg.id !== database?.playmsg) if (final.size > 0) (message.channel as TextChannel).bulkDelete(final).catch(() => {}) else clearInterval(preInterval) - }, client.config.utilities.DELETE_MSG_TIMEOUT) + }, this.client.config.utilities.DELETE_MSG_TIMEOUT) } if (message.author.bot) return @@ -149,16 +228,16 @@ export class PlayerContentLoader { ratelimit.consume() - const blacklistService = new BlacklistService(client) + const blacklistService = new BlacklistService(this.client) const checkResult = await blacklistService.fullCheck(message.author.id, message.guildId) if (checkResult[0] && checkResult[1] == 'user') { await message.reply({ embeds: [ new EmbedBuilder() .setDescription( - `You have been blocked from using Dreamvast, please contact the owner to resolve` + this.client.i18n.get(guildModel, 'error', 'bl_user', { bot: this.client.user.id }) ) - .setColor(client.color), + .setColor(this.client.color), ], }) return false @@ -168,21 +247,21 @@ export class PlayerContentLoader { embeds: [ new EmbedBuilder() .setDescription( - `This server has been blocked from using Dreamvast, please contact the owner to resolve or use another server` + this.client.i18n.get(guildModel, 'error', 'bl_guild', { bot: this.client.user.id }) ) - .setColor(client.color), + .setColor(this.client.color), ], }) return false } - let voiceChannel = await message.member!.voice.channel + let voiceChannel = message.member!.voice.channel if (!voiceChannel) return (message.channel as TextChannel).send({ embeds: [ new EmbedBuilder() - .setDescription(`${client.i18n.get(language, 'error', 'no_in_voice')}`) - .setColor(client.color), + .setDescription(`${this.client.i18n.get(language, 'error', 'no_in_voice')}`) + .setColor(this.client.color), ], }) @@ -194,36 +273,36 @@ export class PlayerContentLoader { msg?.reply({ embeds: [ new EmbedBuilder() - .setDescription(`${client.i18n.get(language, 'event.setup', 'play_emoji')}`) - .setColor(client.color), + .setDescription(`${this.client.i18n.get(language, 'event.setup', 'play_emoji')}`) + .setColor(this.client.color), ], }) return } if (!player) - player = await client.rainlink.create({ + player = await this.client.rainlink.create({ guildId: message.guild.id, voiceId: message.member!.voice.channel!.id, textId: message.channel.id, shardId: message.guild.shardId, deaf: true, - volume: client.config.player.DEFAULT_VOLUME, + volume: this.client.config.player.DEFAULT_VOLUME, }) else { if (message.member!.voice.channel !== message.guild!.members.me!.voice.channel) { msg?.reply({ embeds: [ new EmbedBuilder() - .setDescription(`${client.i18n.get(language, 'error', 'no_same_voice')}`) - .setColor(client.color), + .setDescription(`${this.client.i18n.get(language, 'error', 'no_same_voice')}`) + .setColor(this.client.color), ], }) return } } - const maxLength = await client.db.maxlength.get(message.author.id) + const maxLength = await this.client.db.maxlength.get(message.author.id) const result = await player.search(song, { requester: message.author }) const tracks = result.tracks.filter((e) => (maxLength ? e.duration > maxLength : e)) @@ -231,7 +310,7 @@ export class PlayerContentLoader { if (!result.tracks.length) { msg ?.edit({ - content: `${client.i18n.get(language, 'event.setup', 'setup_content')}\n${`${client.i18n.get( + content: `${this.client.i18n.get(language, 'event.setup', 'setup_content')}\n${`${this.client.i18n.get( language, 'event.setup', 'setup_content_empty' @@ -253,30 +332,30 @@ export class PlayerContentLoader { if (result.type === 'PLAYLIST') { const embed = new EmbedBuilder() .setDescription( - `${client.i18n.get(language, 'event.setup', 'play_playlist', { - title: getTitle(client, result.tracks[0]), + `${this.client.i18n.get(language, 'event.setup', 'play_playlist', { + title: getTitle(this.client, result.tracks[0]), duration: convertTime(TotalDuration), songs: `${result.tracks.length}`, request: `${result.tracks[0].requester}`, })}` ) - .setColor(client.color) + .setColor(this.client.color) msg?.reply({ content: ' ', embeds: [embed] }) } else if (result.type === 'TRACK') { const embed = new EmbedBuilder() .setDescription( - `${client.i18n.get(language, 'event.setup', 'play_track', { - title: getTitle(client, result.tracks[0]), + `${this.client.i18n.get(language, 'event.setup', 'play_track', { + title: getTitle(this.client, result.tracks[0]), duration: convertTime(result.tracks[0].duration as number), request: `${result.tracks[0].requester}`, })}` ) - .setColor(client.color) + .setColor(this.client.color) msg?.reply({ content: ' ', embeds: [embed] }) } else if (result.type === 'SEARCH') { - const embed = new EmbedBuilder().setColor(client.color).setDescription( - `${client.i18n.get(language, 'event.setup', 'play_result', { - title: getTitle(client, result.tracks[0]), + const embed = new EmbedBuilder().setColor(this.client.color).setDescription( + `${this.client.i18n.get(language, 'event.setup', 'play_result', { + title: getTitle(this.client, result.tracks[0]), duration: convertTime(result.tracks[0].duration as number), request: `${result.tracks[0].requester}`, })}` @@ -284,6 +363,6 @@ export class PlayerContentLoader { msg?.reply({ content: ' ', embeds: [embed] }) } - await client.UpdateQueueMsg(player) + await this.client.UpdateQueueMsg(player) } } diff --git a/src/handlers/Player/loadSetup.ts b/src/handlers/Player/loadSetup.ts deleted file mode 100644 index 58cb4b4e..00000000 --- a/src/handlers/Player/loadSetup.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { PlayerEmojis } from './../../@types/Config.js' -import { Manager } from '../../manager.js' -import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js' - -/** - * - * @param {Client} client - */ - -export class PlayerSetupLoader { - client: Manager - icons: PlayerEmojis - constructor(client: Manager) { - this.client = client - this.icons = this.client.config.emojis.PLAYER - this.registerDisableSwitch() - this.registerEnableSwitch() - this.registerEnableSwitchMod() - } - registerEnableSwitch() { - this.client.enSwitch = new ActionRowBuilder().addComponents([ - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sstop') - .setEmoji(this.icons.stop), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sprevious') - .setEmoji(this.icons.previous), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('spause') - .setEmoji(this.icons.play), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sskip') - .setEmoji(this.icons.skip), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sloop') - .setEmoji(this.icons.loop), - ]) - } - - registerEnableSwitchMod() { - this.client.enSwitchMod = new ActionRowBuilder().addComponents([ - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sstop') - .setEmoji(this.icons.stop), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sprevious') - .setEmoji(this.icons.previous), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('spause') - .setEmoji(this.icons.pause), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sskip') - .setEmoji(this.icons.skip), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sloop') - .setEmoji(this.icons.loop), - ]) - } - - registerDisableSwitch() { - this.client.diSwitch = new ActionRowBuilder().addComponents([ - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sstop') - .setEmoji(this.icons.stop) - .setDisabled(true), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sprevious') - .setEmoji(this.icons.previous) - .setDisabled(true), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('spause') - .setEmoji(this.icons.play) - .setDisabled(true), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sskip') - .setEmoji(this.icons.skip) - .setDisabled(true), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setCustomId('sloop') - .setEmoji(this.icons.loop) - .setDisabled(true), - ]) - } -} diff --git a/src/handlers/Player/loadUpdate.ts b/src/handlers/Player/loadUpdate.ts index de80a341..86fe2e77 100644 --- a/src/handlers/Player/loadUpdate.ts +++ b/src/handlers/Player/loadUpdate.ts @@ -3,6 +3,7 @@ import { EmbedBuilder, TextChannel } from 'discord.js' import { formatDuration } from '../../utilities/FormatDuration.js' import { RainlinkPlayer } from 'rainlink' import { getTitle } from '../../utilities/GetTitle.js' +import { filterSelect, playerRowOne, playerRowTwo } from '../../utilities/PlayerControlButton.js' export class PlayerUpdateLoader { client: Manager @@ -87,7 +88,11 @@ export class PlayerUpdateLoader { .edit({ content: player.queue.current && player.queue.size == 0 ? ' ' : queueString, embeds: [embed], - components: [client.enSwitchMod], + components: [ + filterSelect(client, false), + playerRowOne(client, false), + playerRowTwo(client, false), + ], }) .catch(() => {}) } @@ -131,7 +136,11 @@ export class PlayerUpdateLoader { .edit({ content: `${queueMsg}`, embeds: [playEmbed], - components: [client.diSwitch], + components: [ + filterSelect(client, true), + playerRowOne(client, true), + playerRowTwo(client, true), + ], }) .catch(() => {}) } diff --git a/src/handlers/loadPlayer.ts b/src/handlers/loadPlayer.ts index ec8260c4..12b0cdaa 100644 --- a/src/handlers/loadPlayer.ts +++ b/src/handlers/loadPlayer.ts @@ -1,7 +1,6 @@ import { Manager } from '../manager.js' import { PlayerContentLoader } from './Player/loadContent.js' import { PlayerEventLoader } from './Player/loadEvent.js' -import { PlayerSetupLoader } from './Player/loadSetup.js' import { PlayerUpdateLoader } from './Player/loadUpdate.js' export class PlayerLoader { @@ -9,6 +8,5 @@ export class PlayerLoader { new PlayerEventLoader(client) new PlayerContentLoader(client) new PlayerUpdateLoader(client) - new PlayerSetupLoader(client) } } diff --git a/src/manager.ts b/src/manager.ts index 91cef0e7..39d41e57 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -75,9 +75,6 @@ export class Manager extends Client { public wsl: Collection<{ send: (data: Record) => void }> public UpdateMusic!: (player: RainlinkPlayer) => Promise> public UpdateQueueMsg!: (player: RainlinkPlayer) => Promise> - public enSwitch!: ActionRowBuilder - public diSwitch!: ActionRowBuilder - public enSwitchMod!: ActionRowBuilder public topgg?: TopggService public icons: Emojis public REGEX: RegExp[] diff --git a/src/services/ReplyInteractionService.ts b/src/services/ReplyInteractionService.ts index 5642fdb9..c357c136 100644 --- a/src/services/ReplyInteractionService.ts +++ b/src/services/ReplyInteractionService.ts @@ -2,13 +2,11 @@ import { EmbedBuilder, ButtonInteraction } from 'discord.js' import { Manager } from '../manager.js' export class ReplyInteractionService { - client: Manager - message: ButtonInteraction - content: string - constructor(client: Manager, message: ButtonInteraction, content: string) { - this.client = client - this.content = content - this.message = message + constructor( + protected client: Manager, + protected message: ButtonInteraction, + protected content: string + ) { this.execute() } diff --git a/src/utilities/PlayerControlButton.ts b/src/utilities/PlayerControlButton.ts index 62943ab3..d5d16eb7 100644 --- a/src/utilities/PlayerControlButton.ts +++ b/src/utilities/PlayerControlButton.ts @@ -1,96 +1,112 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder } from 'discord.js' import { Manager } from '../manager.js' -const playerRowOne = (client: Manager) => +const playerRowOne = (client: Manager, disable?: boolean) => new ActionRowBuilder().addComponents([ new ButtonBuilder() .setCustomId('stop') .setEmoji(client.config.emojis.PLAYER.stop) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('replay') .setEmoji(client.config.emojis.PLAYER.previous) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('pause') .setEmoji(client.config.emojis.PLAYER.pause) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('skip') .setEmoji(client.config.emojis.PLAYER.skip) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('loop') .setEmoji(client.config.emojis.PLAYER.loop) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), ]) -const playerRowTwo = (client: Manager) => +const playerRowTwo = (client: Manager, disable?: boolean) => new ActionRowBuilder().addComponents([ new ButtonBuilder() .setCustomId('shuffle') .setEmoji(client.config.emojis.PLAYER.shuffle) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('voldown') .setEmoji(client.config.emojis.PLAYER.voldown) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('clear') .setEmoji(client.config.emojis.PLAYER.delete) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('volup') .setEmoji(client.config.emojis.PLAYER.volup) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('queue') .setEmoji(client.config.emojis.PLAYER.queue) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), ]) -const playerRowOneEdited = (client: Manager) => +const playerRowOneEdited = (client: Manager, disable?: boolean) => new ActionRowBuilder().addComponents([ new ButtonBuilder() .setCustomId('stop') .setEmoji(client.config.emojis.PLAYER.stop) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('replay') .setEmoji(client.config.emojis.PLAYER.previous) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('pause') .setEmoji(client.config.emojis.PLAYER.play) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('skip') .setEmoji(client.config.emojis.PLAYER.skip) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), new ButtonBuilder() .setCustomId('loop') .setEmoji(client.config.emojis.PLAYER.loop) - .setStyle(ButtonStyle.Secondary), + .setStyle(ButtonStyle.Secondary) + .setDisabled(disable), ]) -const filterSelect = (client: Manager) => +const filterSelect = (client: Manager, disable?: boolean) => new ActionRowBuilder().addComponents( new StringSelectMenuBuilder() .setCustomId('filter') .setPlaceholder('Choose a filter for better audio experience') .addOptions(client.selectMenuOptions) + .setDisabled(disable) ) export { playerRowOne, playerRowOneEdited, playerRowTwo, filterSelect }