Repository: Cog-Creators/Red-DiscordBot

Issue:
[Audio] search only picks the 1st option when you have buttons enabled
### What Red version are you using?

3.5.1

### Cog name

Audio

### Command name

search

### What did you expect to happen?

It's supposed to pick the `subsequent` song from the search results **according to** your interaction with buttons. 
I.e.
If you choose to pick 5 (let's say) and press on the following no. 5 button, it should pick the 5th number song, from the search results and not the 1st one.

### What actually happened?

So it only picks the 1st option i.e. 1st song from the search results **even if** you selected the 5th one, no matter which page you're on. Same result.

### How can we reproduce this error?

1. `<p>set usebuttons` (make the buttons on)
2. Join VC & `<p>search <queries>` (any queries)
3. Try to select the results __other than__ the 1st option.
4. You will see it only picks the 1st option even tho you've selected something else other than the 1st option.

Now, if you use the reactions instead, 
> `<p>set usebuttons` (make the buttons off)
> Then run the cmds in the same sequence, it work as how you expect it to be.


### Anything else?

Nope


Discussion:

Resolving patch:
diff --git a/redbot/core/utils/menus.py b/redbot/core/utils/menus.py
--- a/redbot/core/utils/menus.py
+++ b/redbot/core/utils/menus.py
@@ -32,10 +32,8 @@
 
 
 class _GenericButton(discord.ui.Button):
-    def __init__(self, emoji: Union[str, discord.PartialEmoji], func):
-        super().__init__(
-            emoji=discord.PartialEmoji.from_str(emoji), style=discord.ButtonStyle.grey
-        )
+    def __init__(self, emoji: discord.PartialEmoji, func: _ControlCallable):
+        super().__init__(emoji=emoji, style=discord.ButtonStyle.grey)
         self.func = func
 
     async def callback(self, interaction: discord.Interaction):
@@ -45,7 +43,11 @@ async def callback(self, interaction: discord.Interaction):
         message = self.view.message
         page = self.view.current_page
         timeout = self.view.timeout
-        emoji = self.emoji
+        emoji = (
+            str(self.emoji)
+            if self.emoji.is_unicode_emoji()
+            else (ctx.bot.get_emoji(self.emoji.id) or self.emoji)
+        )
         try:
             await self.func(ctx, pages, controls, message, page, timeout, emoji)
         except Exception:
@@ -148,18 +150,19 @@ async def menu(
             has_close = False
             to_add = {}
             for emoji, func in controls.items():
+                part_emoji = discord.PartialEmoji.from_str(str(emoji))
                 if func == next_page:
                     has_next = True
-                    if emoji != view.forward_button.emoji:
-                        view.forward_button.emoji = discord.PartialEmoji.from_str(emoji)
+                    if part_emoji != view.forward_button.emoji:
+                        view.forward_button.emoji = part_emoji
                 elif func == prev_page:
                     has_prev = True
-                    if emoji != view.backward_button.emoji:
-                        view.backward_button.emoji = discord.PartialEmoji.from_str(emoji)
+                    if part_emoji != view.backward_button.emoji:
+                        view.backward_button.emoji = part_emoji
                 elif func == close_menu:
                     has_close = True
                 else:
-                    to_add[emoji] = func
+                    to_add[part_emoji] = func
             if not has_next:
                 view.remove_item(view.forward_button)
             if not has_prev:


Test patch: