From a5051e0c9c2cc5ebffa14b947e7d43c21c5768eb Mon Sep 17 00:00:00 2001 From: Choco <94597336+ChocoMeow@users.noreply.github.com> Date: Mon, 20 Feb 2023 11:23:18 +0800 Subject: [PATCH] Support for custom buttons in music controller --- function.py | 5 ++- settings Example.json | 4 +++ view/controller.py | 73 ++++++++++++++++++++++++++++--------------- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/function.py b/function.py index 102e634..6a3aa84 100644 --- a/function.py +++ b/function.py @@ -55,6 +55,8 @@ bot_prefix = "?" #The default bot prefix max_queue = 1000 #The default maximum number of tracks in the queue cooldowns_settings = {} #Stores command cooldown settings aliases_settings = {} #Stores command aliases settings +controller_settings = {} #Stores the layout of music controller + #----------------- Nodes ----------------- nodes = {} @@ -97,7 +99,7 @@ def settings_setup(): with open(os.path.join(root_dir, "settings.json"), encoding="utf8") as json_file: rawSettings = json.load(json_file) - global nodes, embed_color, bot_access_user, emoji_source_raw, bot_prefix, max_queue, cooldowns_settings, aliases_settings + global nodes, max_queue, bot_prefix, embed_color, bot_access_user, emoji_source_raw, cooldowns_settings, aliases_settings, controller_settings nodes = rawSettings.get("nodes", {}) if (new_max_queue := rawSettings.get("default_max_queue", max_queue)): max_queue = new_max_queue @@ -107,6 +109,7 @@ def settings_setup(): emoji_source_raw = rawSettings.get("emoji_source_raw", {}) cooldowns_settings = rawSettings.get("cooldowns", {}) aliases_settings = rawSettings.get("aliases", {}) + controller_settings = rawSettings.get("controller", [["back", "resume", "skip", {"stop": "red"}, "add"], ["tracks"]]) def get_lang(guildid:int, key:str): lang = lang_guilds.get(guildid) diff --git a/settings Example.json b/settings Example.json index 59efe44..0847813 100644 --- a/settings Example.json +++ b/settings Example.json @@ -24,6 +24,10 @@ "reddit": "<:reddit:996007566863773717>", "tiktok": "<:tiktok:996007689798811698>" }, + "controller": [ + ["back", "resume", "skip", {"stop": "red"}, "add"], + ["tracks"] + ], "cooldowns": { "connect": [2, 30], "playlist view": [1, 30] diff --git a/view/controller.py b/view/controller.py index d4df07d..3bfe157 100644 --- a/view/controller.py +++ b/view/controller.py @@ -30,16 +30,17 @@ from function import ( get_playlist, update_playlist, create_account, - checkroles + checkroles, ) +from typing import Dict def key(interaction: discord.Interaction): return interaction.user -class previous_command(discord.ui.Button): - def __init__(self, player): +class Back(discord.ui.Button): + def __init__(self, player, style, row): self.player = player - super().__init__(emoji="⏮️", label=player.get_msg('buttonBack'), style=discord.ButtonStyle.secondary, disabled=False if self.player.queue.history() or not self.player.current else True) + super().__init__(emoji="⏮️", label=player.get_msg('buttonBack'), style=style, disabled=False if self.player.queue.history() or not self.player.current else True, row=row) async def callback(self, interaction: discord.Interaction): if not await self.player.is_privileged(interaction.user): @@ -67,10 +68,10 @@ class previous_command(discord.ui.Button): if self.player.queue._repeat == 1: self.player.queue.set_repeat("off") -class resume_command(discord.ui.Button): - def __init__(self, player): +class Resume(discord.ui.Button): + def __init__(self, player, style, row): self.player = player - super().__init__(emoji="⏸️", label=player.get_msg('buttonPause'), style=discord.ButtonStyle.secondary, disabled=False if self.player.current else True) + super().__init__(emoji="⏸️", label=player.get_msg('buttonPause'), style=style, disabled=False if self.player.current else True, row=row) async def callback(self, interaction: discord.Interaction): if self.player.is_paused: @@ -106,10 +107,10 @@ class resume_command(discord.ui.Button): await self.player.set_pause(True) await interaction.response.edit_message(view=self.view) -class skip_command(discord.ui.Button): - def __init__(self, player): +class Skip(discord.ui.Button): + def __init__(self, player, style, row): self.player = player - super().__init__(emoji="⏭️", label=player.get_msg('buttonSkip'), style=discord.ButtonStyle.secondary) + super().__init__(emoji="⏭️", label=player.get_msg('buttonSkip'), style=style, row=row) async def callback(self, interaction: discord.Interaction): if not self.player.is_playing: @@ -135,10 +136,10 @@ class skip_command(discord.ui.Button): self.player.queue.set_repeat("off") await self.player.stop() -class stop_command(discord.ui.Button): - def __init__(self, player): +class Stop(discord.ui.Button): + def __init__(self, player, style, row): self.player = player - super().__init__(emoji="⏹️", label=player.get_msg('buttonLeave'), style=discord.ButtonStyle.danger) + super().__init__(emoji="⏹️", label=player.get_msg('buttonLeave'), style=style, row=row) async def callback(self, interaction: discord.Interaction): if not await self.player.is_privileged(interaction.user): if interaction.user in self.player.stop_votes: @@ -153,10 +154,10 @@ class stop_command(discord.ui.Button): await interaction.response.send_message(self.player.get_msg("left").format(interaction.user)) await self.player.teardown() -class add_playlist(discord.ui.Button): - def __init__(self, player): +class Add(discord.ui.Button): + def __init__(self, player, style, row): self.player = player - super().__init__(emoji="❤️", style=discord.ButtonStyle.secondary, disabled=False if self.player.current else True) + super().__init__(emoji="❤️", style=style, disabled=False if self.player.current else True, row=row) async def callback(self, interaction: discord.Interaction): track = self.player.current @@ -184,8 +185,8 @@ class add_playlist(discord.ui.Button): else: await interaction.response.send_message(self.player.get_msg("playlistAddError2"), ephemeral=True) -class Dropdown(discord.ui.Select): - def __init__(self, player): +class Tracks(discord.ui.Select): + def __init__(self, player, style, row): self.player = player @@ -199,6 +200,7 @@ class Dropdown(discord.ui.Select): placeholder=player.get_msg("playerDropdown"), min_values=1, max_values=1, options=options, + row=row ) async def callback(self, interaction: discord.Interaction): @@ -209,18 +211,39 @@ class Dropdown(discord.ui.Select): await self.player.stop() await interaction.response.send_message(self.player.get_msg("skipped").format(interaction.user)) +btnType = { + "back": Back, + "resume": Resume, + "skip": Skip, + "stop": Stop, + "add": Add, + "tracks": Tracks +} + +btnColor = { + "blue": discord.ButtonStyle.primary, + "grey": discord.ButtonStyle.secondary, + "red": discord.ButtonStyle.danger, + "green": discord.ButtonStyle.success +} + class InteractiveController(discord.ui.View): def __init__(self, player): super().__init__(timeout=None) self.player = player - self.add_item(previous_command(player)) - self.add_item(resume_command(player)) - self.add_item(skip_command(player)) - self.add_item(stop_command(player)) - self.add_item(add_playlist(player)) - if not self.player.queue.is_empty: - self.add_item(Dropdown(player)) + for row, btnRow in enumerate(func.controller_settings): + for btn in btnRow: + color = "" + if isinstance(btn, Dict): + color = list(btn.values())[0] + btn = list(btn.keys())[0] + btnClass = btnType.get(btn.lower()) + style = btnColor.get(color.lower(), btnColor["grey"]) + if not btnClass or (self.player.queue.is_empty and btn == "tracks"): + continue + self.add_item(btnClass(player, style, row)) + self.cooldown = commands.CooldownMapping.from_cooldown(2.0, 10.0, key) async def interaction_check(self, interaction):