mirror of
https://github.com/deadcxap/YandexMusicDiscordBot.git
synced 2026-01-11 13:51:40 +03:00
feat: Add find autocomplete.
This commit is contained in:
@@ -18,9 +18,55 @@ from MusicBot.cogs.utils.embeds import generate_item_embed
|
|||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(General(bot))
|
bot.add_cog(General(bot))
|
||||||
|
|
||||||
|
async def get_search_suggestions(ctx: discord.AutocompleteContext) -> list[str]:
|
||||||
|
if not ctx.interaction.user or not ctx.value:
|
||||||
|
return []
|
||||||
|
|
||||||
|
users_db = BaseUsersDatabase()
|
||||||
|
token = users_db.get_ym_token(ctx.interaction.user.id)
|
||||||
|
if not token:
|
||||||
|
return ['❌ Укажите токен через /account login.']
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = await YMClient(token).init()
|
||||||
|
except yandex_music.exceptions.UnauthorizedError:
|
||||||
|
logging.info(f"User {ctx.interaction.user.id} provided invalid token")
|
||||||
|
return ['❌ Недействительный токен.']
|
||||||
|
|
||||||
|
content_type = ctx.options['тип']
|
||||||
|
search = await client.search(ctx.value)
|
||||||
|
if not search:
|
||||||
|
logging.warning(f"Failed to search for '{ctx.value}' for user {ctx.interaction.user.id}")
|
||||||
|
return ["❌ Что-то пошло не так. Повторите попытку позже"]
|
||||||
|
|
||||||
|
res = []
|
||||||
|
logging.debug(f"Searching for '{ctx.value}' for user {ctx.interaction.user.id}")
|
||||||
|
|
||||||
|
if content_type == 'Трек' and search.tracks:
|
||||||
|
for item in search.tracks.results:
|
||||||
|
res.append(f"{item.title} {f"({item.version})" if item.version else ''} - {", ".join(item.artists_name())}")
|
||||||
|
elif content_type == 'Альбом' and search.albums:
|
||||||
|
for item in search.albums.results:
|
||||||
|
res.append(f"{item.title} - {", ".join(item.artists_name())}")
|
||||||
|
elif content_type == 'Артист' and search.artists:
|
||||||
|
for item in search.artists.results:
|
||||||
|
res.append(f"{item.name}")
|
||||||
|
elif content_type == 'Плейлист' and search.playlists:
|
||||||
|
for item in search.playlists.results:
|
||||||
|
res.append(f"{item.title}")
|
||||||
|
elif content_type == "Свой плейлист":
|
||||||
|
if not client.me or not client.me.account or not client.me.account.uid:
|
||||||
|
logging.warning(f"Failed to get playlists for user {ctx.interaction.user.id}")
|
||||||
|
return ["❌ Что-то пошло не так. Повторите попытку позже"]
|
||||||
|
|
||||||
|
playlists_list = await client.users_playlists_list(client.me.account.uid)
|
||||||
|
res = [playlist.title if playlist.title else 'Без названия' for playlist in playlists_list]
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
class General(Cog):
|
class General(Cog):
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot: discord.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.db = BaseGuildsDatabase()
|
self.db = BaseGuildsDatabase()
|
||||||
self.users_db = BaseUsersDatabase()
|
self.users_db = BaseUsersDatabase()
|
||||||
@@ -36,6 +82,7 @@ class General(Cog):
|
|||||||
)
|
)
|
||||||
async def help(self, ctx: discord.ApplicationContext, command: str) -> None:
|
async def help(self, ctx: discord.ApplicationContext, command: str) -> None:
|
||||||
logging.info(f"Help command invoked by {ctx.user.id} for command '{command}'")
|
logging.info(f"Help command invoked by {ctx.user.id} for command '{command}'")
|
||||||
|
|
||||||
response_message = None
|
response_message = None
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title='Помощь',
|
title='Помощь',
|
||||||
@@ -45,60 +92,76 @@ class General(Cog):
|
|||||||
embed.description = '__Использование__\n'
|
embed.description = '__Использование__\n'
|
||||||
|
|
||||||
if command == 'all':
|
if command == 'all':
|
||||||
embed.description = ("Данный бот позволяет вам слушать музыку из вашего аккаунта Yandex Music.\n"
|
embed.description = (
|
||||||
|
"Этот бот позволяет слушать музыку из вашего аккаунта Yandex Music.\n"
|
||||||
"Зарегистрируйте свой токен с помощью /login. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n"
|
"Зарегистрируйте свой токен с помощью /login. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n"
|
||||||
"Для получения помощи для конкретной команды, введите /help <команда>.\n\n"
|
"Для получения помощи по конкретной команде, введите /help <команда>.\n\n"
|
||||||
"**Для доп. помощи, зайдите на [сервер любителей Яндекс Музыки](https://discord.gg/gkmFDaPMeC).**")
|
"**Для дополнительной помощи, присоединяйтесь к [серверу любителей Яндекс Музыки](https://discord.gg/gkmFDaPMeC).**"
|
||||||
|
)
|
||||||
|
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name='__Основные команды__',
|
name='__Основные команды__',
|
||||||
value="""
|
value="""`account`
|
||||||
`account`
|
|
||||||
`find`
|
`find`
|
||||||
`help`
|
`help`
|
||||||
`like`
|
`like`
|
||||||
`queue`
|
`queue`
|
||||||
`settings`
|
`settings`
|
||||||
`track`
|
`track`
|
||||||
`voice`
|
`voice`"""
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
embed.set_footer(text='©️ Bananchiki')
|
embed.set_footer(text='©️ Bananchiki')
|
||||||
elif command == 'account':
|
elif command == 'account':
|
||||||
embed.description += ("Ввести токен от Яндекс Музыки. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n"
|
embed.description += (
|
||||||
|
"Ввести токен от Яндекс Музыки. Его можно получить [здесь](https://github.com/MarshalX/yandex-music-api/discussions/513).\n"
|
||||||
"```/account login <token>```\n"
|
"```/account login <token>```\n"
|
||||||
"Удалить токен из датабазы бота.\n```/account remove```\n"
|
"Удалить токен из базы данных бота.\n```/account remove```\n"
|
||||||
"Получить ваши плейлисты. Чтобы добавить плейлист в очередь, используйте команду /find.\n```/account playlists```\n"
|
"Получить ваши плейлисты. Чтобы добавить плейлист в очередь, используйте команду /find.\n```/account playlists```\n"
|
||||||
"Получить плейлист «Мне нравится». \n```/account likes```\n")
|
"Получить плейлист «Мне нравится».\n```/account likes```\n"
|
||||||
|
)
|
||||||
elif command == 'find':
|
elif command == 'find':
|
||||||
embed.description += ("Вывести информацию о треке (по умолчанию), альбоме, авторе или плейлисте. Позволяет добавить музыку в очередь. "
|
embed.description += (
|
||||||
"В названии можно уточнить автора или версию. Возвращается лучшее совпадение.\n```/find <название> <тип>```")
|
"Вывести информацию о треке (по умолчанию), альбоме, авторе или плейлисте. Позволяет добавить музыку в очередь. "
|
||||||
|
"В названии можно уточнить автора или версию. Возвращается лучшее совпадение.\n```/find <название> <тип>```"
|
||||||
|
)
|
||||||
elif command == 'help':
|
elif command == 'help':
|
||||||
embed.description += ("Вывести список всех команд.\n```/help```\n"
|
embed.description += (
|
||||||
"Получить информацию о конкретной команде.\n```/help <команда>```")
|
"Вывести список всех команд.\n```/help```\n"
|
||||||
|
"Получить информацию о конкретной команде.\n```/help <команда>```"
|
||||||
|
)
|
||||||
elif command == 'like':
|
elif command == 'like':
|
||||||
embed.description += "Добавить трек в плейлист «Мне нравится». Пользовательские треки из этого плейлиста игнорируются.\n```/like```"
|
embed.description += (
|
||||||
|
"Добавить трек в плейлист «Мне нравится». Пользовательские треки из этого плейлиста игнорируются.\n```/like```"
|
||||||
|
)
|
||||||
elif command == 'queue':
|
elif command == 'queue':
|
||||||
embed.description += ("Получить очередь треков. По 15 элементов на страницу.\n```/queue get```\n"
|
embed.description += (
|
||||||
"Очистить очередь треков и историю прослушивания. Доступно только если вы единственный в голосовом канале"
|
"Получить очередь треков. По 15 элементов на страницу.\n```/queue get```\n"
|
||||||
"или имеете разрешение управления каналом.\n```/queue clear```\n")
|
"Очистить очередь треков и историю прослушивания. Доступно только если вы единственный в голосовом канале "
|
||||||
|
"или имеете разрешение управления каналом.\n```/queue clear```\n"
|
||||||
|
)
|
||||||
elif command == 'settings':
|
elif command == 'settings':
|
||||||
embed.description += ("Получить текущие настройки.\n```/settings show```\n"
|
embed.description += (
|
||||||
|
"Получить текущие настройки.\n```/settings show```\n"
|
||||||
"Разрешить или запретить воспроизведение Explicit треков и альбомов. Если автор или плейлист содержат Explicit треки, убираются кнопки для доступа к ним.\n```/settings explicit```\n"
|
"Разрешить или запретить воспроизведение Explicit треков и альбомов. Если автор или плейлист содержат Explicit треки, убираются кнопки для доступа к ним.\n```/settings explicit```\n"
|
||||||
"Разрешить или запретить создание меню проигрывателя, когда в канале больше одного человека.\n```/settings menu```\n"
|
"Разрешить или запретить создание меню проигрывателя, когда в канале больше одного человека.\n```/settings menu```\n"
|
||||||
"Разрешить или запретить голосование.\n```/settings vote <тип голосования>```\n"
|
"Разрешить или запретить голосование.\n```/settings vote <тип голосования>```\n"
|
||||||
"`Примечание`: Только пользователи с разрешением управления каналом могут менять настройки.")
|
"`Примечание`: Только пользователи с разрешением управления каналом могут менять настройки."
|
||||||
|
)
|
||||||
elif command == 'track':
|
elif command == 'track':
|
||||||
embed.description += ("`Примечание`: Если вы один в голосовом канале или имеете разрешение управления каналом, голосование не начинается.\n\n"
|
embed.description += (
|
||||||
|
"`Примечание`: Если вы один в голосовом канале или имеете разрешение управления каналом, голосование не начинается.\n\n"
|
||||||
"Переключиться на следующий трек в очереди. \n```/track next```\n"
|
"Переключиться на следующий трек в очереди. \n```/track next```\n"
|
||||||
"Приостановить текущий трек.\n ```/track pause```\n"
|
"Приостановить текущий трек.\n ```/track pause```\n"
|
||||||
"Возобновить текущий трек.\n ```/track resume```\n"
|
"Возобновить текущий трек.\n ```/track resume```\n"
|
||||||
"Прервать проигрывание, удалить историю, очередь и текущий плеер.\n ```/track stop```")
|
"Прервать проигрывание, удалить историю, очередь и текущий плеер.\n ```/track stop```"
|
||||||
|
)
|
||||||
elif command == 'voice':
|
elif command == 'voice':
|
||||||
embed.description += ("Присоединить бота в голосовой канал. Требует разрешения управления каналом.\n ```/voice join```\n"
|
embed.description += (
|
||||||
|
"Присоединить бота в голосовой канал. Требует разрешения управления каналом.\n ```/voice join```\n"
|
||||||
"Заставить бота покинуть голосовой канал. Требует разрешения управления каналом.\n ```/voice leave```\n"
|
"Заставить бота покинуть голосовой канал. Требует разрешения управления каналом.\n ```/voice leave```\n"
|
||||||
"Создать меню проигрывателя. Доступность зависит от настроек сервера. По умолчанию работает только когда в канале один человек.\n```/voice menu```")
|
"Создать меню проигрывателя. Доступность зависит от настроек сервера. По умолчанию работает только когда в канале один человек.\n```/voice menu```"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
response_message = '❌ Неизвестная команда.'
|
response_message = '❌ Неизвестная команда.'
|
||||||
embed = None
|
embed = None
|
||||||
@@ -160,43 +223,52 @@ class General(Cog):
|
|||||||
@account.command(description="Получить ваши плейлисты.")
|
@account.command(description="Получить ваши плейлисты.")
|
||||||
async def playlists(self, ctx: discord.ApplicationContext) -> None:
|
async def playlists(self, ctx: discord.ApplicationContext) -> None:
|
||||||
logging.info(f"Playlists command invoked by user {ctx.user.id} in guild {ctx.guild_id}")
|
logging.info(f"Playlists command invoked by user {ctx.user.id} in guild {ctx.guild_id}")
|
||||||
|
|
||||||
token = self.users_db.get_ym_token(ctx.user.id)
|
token = self.users_db.get_ym_token(ctx.user.id)
|
||||||
if not token:
|
if not token:
|
||||||
await ctx.respond('❌ Необходимо указать свой токен доступа с помощью команды /login.', delete_after=15, ephemeral=True)
|
await ctx.respond('❌ Необходимо указать свой токен доступа с помощью команды /login.', delete_after=15, ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
client = await YMClient(token).init()
|
client = await YMClient(token).init()
|
||||||
if not client.me or not client.me.account or not client.me.account.uid:
|
if not client.me or not client.me.account or not client.me.account.uid:
|
||||||
await ctx.respond('❌ Что-то пошло не так. Повторите попытку позже.', delete_after=15, ephemeral=True)
|
await ctx.respond('❌ Что-то пошло не так. Повторите попытку позже.', delete_after=15, ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
playlists_list = await client.users_playlists_list(client.me.account.uid)
|
playlists_list = await client.users_playlists_list(client.me.account.uid)
|
||||||
playlists: list[tuple[str, int]] = [
|
playlists: list[tuple[str, int]] = [
|
||||||
(playlist.title if playlist.title else 'Без названия', playlist.track_count if playlist.track_count else 0) for playlist in playlists_list
|
(playlist.title if playlist.title else 'Без названия', playlist.track_count if playlist.track_count else 0) for playlist in playlists_list
|
||||||
]
|
]
|
||||||
|
|
||||||
self.users_db.update(ctx.user.id, {'playlists': playlists, 'playlists_page': 0})
|
self.users_db.update(ctx.user.id, {'playlists': playlists, 'playlists_page': 0})
|
||||||
embed = generate_playlists_embed(0, playlists)
|
embed = generate_playlists_embed(0, playlists)
|
||||||
|
|
||||||
logging.info(f"Successfully fetched playlists for user {ctx.user.id}")
|
logging.info(f"Successfully fetched playlists for user {ctx.user.id}")
|
||||||
await ctx.respond(embed=embed, view=MyPlaylists(ctx), ephemeral=True)
|
await ctx.respond(embed=embed, view=MyPlaylists(ctx), ephemeral=True)
|
||||||
|
|
||||||
|
discord.Option
|
||||||
@discord.slash_command(description="Найти контент и отправить информацию о нём. Возвращается лучшее совпадение.")
|
@discord.slash_command(description="Найти контент и отправить информацию о нём. Возвращается лучшее совпадение.")
|
||||||
@discord.option(
|
@discord.option(
|
||||||
"name",
|
"тип",
|
||||||
description="Название контента для поиска (По умолчанию трек).",
|
parameter_name='content_type',
|
||||||
type=discord.SlashCommandOptionType.string
|
description="Тип контента для поиска.",
|
||||||
)
|
|
||||||
@discord.option(
|
|
||||||
"content_type",
|
|
||||||
description="Тип искомого контента.",
|
|
||||||
type=discord.SlashCommandOptionType.string,
|
type=discord.SlashCommandOptionType.string,
|
||||||
choices=['Трек', 'Альбом', 'Артист', 'Плейлист', 'Свой плейлист'],
|
choices=['Трек', 'Альбом', 'Артист', 'Плейлист', 'Свой плейлист'],
|
||||||
default='Трек'
|
)
|
||||||
|
@discord.option(
|
||||||
|
"запрос",
|
||||||
|
parameter_name='name',
|
||||||
|
description="Название контента для поиска (По умолчанию трек).",
|
||||||
|
type=discord.SlashCommandOptionType.string,
|
||||||
|
autocomplete=discord.utils.basic_autocomplete(get_search_suggestions)
|
||||||
)
|
)
|
||||||
async def find(
|
async def find(
|
||||||
self,
|
self,
|
||||||
ctx: discord.ApplicationContext,
|
ctx: discord.ApplicationContext,
|
||||||
name: str,
|
content_type: Literal['Трек', 'Альбом', 'Артист', 'Плейлист', 'Свой плейлист'],
|
||||||
content_type: Literal['Трек', 'Альбом', 'Артист', 'Плейлист', 'Свой плейлист'] = 'Трек'
|
name: str
|
||||||
) -> None:
|
) -> None:
|
||||||
logging.info(f"Find command invoked by user {ctx.user.id} in guild {ctx.guild_id} for '{content_type}' with name '{name}'")
|
logging.info(f"Find command invoked by user {ctx.user.id} in guild {ctx.guild_id} for '{content_type}' with name '{name}'")
|
||||||
|
|
||||||
guild = self.db.get_guild(ctx.guild_id)
|
guild = self.db.get_guild(ctx.guild_id)
|
||||||
token = self.users_db.get_ym_token(ctx.user.id)
|
token = self.users_db.get_ym_token(ctx.user.id)
|
||||||
if not token:
|
if not token:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class VoiceExtension:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if updated, False if not.
|
bool: True if updated, False if not.
|
||||||
"""
|
"""
|
||||||
|
from MusicBot.ui import MenuView
|
||||||
logging.debug(
|
logging.debug(
|
||||||
f"Updating player embed using " +
|
f"Updating player embed using " +
|
||||||
"interaction context" if isinstance(ctx, Interaction) else
|
"interaction context" if isinstance(ctx, Interaction) else
|
||||||
@@ -41,7 +42,7 @@ class VoiceExtension:
|
|||||||
logging.warning("Guild ID or User ID not found in context inside 'update_player_embed'")
|
logging.warning("Guild ID or User ID not found in context inside 'update_player_embed'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
player = await self.get_player_message(ctx, player_mid)
|
player = await self.get_menu_message(ctx, player_mid)
|
||||||
if not player:
|
if not player:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -63,14 +64,14 @@ class VoiceExtension:
|
|||||||
|
|
||||||
if isinstance(ctx, Interaction) and ctx.message and ctx.message.id == player_mid:
|
if isinstance(ctx, Interaction) and ctx.message and ctx.message.id == player_mid:
|
||||||
# If interaction from player buttons
|
# If interaction from player buttons
|
||||||
await ctx.edit(embed=embed)
|
await ctx.edit(embed=embed, view=await MenuView(ctx).init())
|
||||||
else:
|
else:
|
||||||
# If interaction from other buttons or commands. They should have their own response.
|
# If interaction from other buttons or commands. They should have their own response.
|
||||||
await player.edit(embed=embed)
|
await player.edit(embed=embed, view=await MenuView(ctx).init())
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def get_player_message(self, ctx: ApplicationContext | Interaction | RawReactionActionEvent, player_mid: int) -> discord.Message | None:
|
async def get_menu_message(self, ctx: ApplicationContext | Interaction | RawReactionActionEvent, player_mid: int) -> discord.Message | None:
|
||||||
"""Fetch the player message by its id. Return the message if found, None if not.
|
"""Fetch the player message by its id. Return the message if found, None if not.
|
||||||
Reset `current_player` field in the database if not found.
|
Reset `current_player` field in the database if not found.
|
||||||
|
|
||||||
@@ -369,7 +370,7 @@ class VoiceExtension:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get_likes(self, ctx: ApplicationContext | Interaction) -> list[TrackShort] | None:
|
async def get_likes(self, ctx: ApplicationContext | Interaction | RawReactionActionEvent) -> list[TrackShort] | None:
|
||||||
"""Get liked tracks. Return list of tracks on success.
|
"""Get liked tracks. Return list of tracks on success.
|
||||||
Return None if no token found.
|
Return None if no token found.
|
||||||
|
|
||||||
@@ -380,12 +381,14 @@ class VoiceExtension:
|
|||||||
list[Track] | None: List of tracks or None.
|
list[Track] | None: List of tracks or None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not ctx.guild or not ctx.user:
|
gid = ctx.guild_id if isinstance(ctx, discord.RawReactionActionEvent) else ctx.guild.id if ctx.guild else None
|
||||||
logging.warning("Guild or User not found in context inside 'like_track'")
|
uid = ctx.user_id if isinstance(ctx, discord.RawReactionActionEvent) else ctx.user.id if ctx.user else None
|
||||||
|
if not gid or not uid:
|
||||||
|
logging.warning("Guild ID or User ID not found in context inside 'play_track'")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
current_track = self.db.get_track(ctx.guild.id, 'current')
|
current_track = self.db.get_track(gid, 'current')
|
||||||
token = self.users_db.get_ym_token(ctx.user.id)
|
token = self.users_db.get_ym_token(uid)
|
||||||
if not current_track or not token:
|
if not current_track or not token:
|
||||||
logging.debug("Current track or token not found")
|
logging.debug("Current track or token not found")
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ class Voice(Cog, VoiceExtension):
|
|||||||
guild = self.db.get_guild(guild_id)
|
guild = self.db.get_guild(guild_id)
|
||||||
votes = guild['votes']
|
votes = guild['votes']
|
||||||
|
|
||||||
|
if payload.message_id not in votes:
|
||||||
|
logging.info(f"Message {payload.message_id} not found in votes")
|
||||||
|
return
|
||||||
|
|
||||||
vote_data = votes[str(payload.message_id)]
|
vote_data = votes[str(payload.message_id)]
|
||||||
if payload.emoji.name == '✅':
|
if payload.emoji.name == '✅':
|
||||||
logging.info(f"User {payload.user_id} voted positively for message {payload.message_id}")
|
logging.info(f"User {payload.user_id} voted positively for message {payload.message_id}")
|
||||||
@@ -214,7 +218,7 @@ class Voice(Cog, VoiceExtension):
|
|||||||
|
|
||||||
if guild['current_player']:
|
if guild['current_player']:
|
||||||
logging.info(f"Deleteing old player menu {guild['current_player']} in guild {ctx.guild.id}")
|
logging.info(f"Deleteing old player menu {guild['current_player']} in guild {ctx.guild.id}")
|
||||||
message = await self.get_player_message(ctx, guild['current_player'])
|
message = await self.get_menu_message(ctx, guild['current_player'])
|
||||||
if message:
|
if message:
|
||||||
await message.delete()
|
await message.delete()
|
||||||
|
|
||||||
@@ -354,7 +358,7 @@ class Voice(Cog, VoiceExtension):
|
|||||||
|
|
||||||
current_player = self.db.get_current_player(ctx.guild.id)
|
current_player = self.db.get_current_player(ctx.guild.id)
|
||||||
if current_player:
|
if current_player:
|
||||||
player = await self.get_player_message(ctx, current_player)
|
player = await self.get_menu_message(ctx, current_player)
|
||||||
if player:
|
if player:
|
||||||
await player.delete()
|
await player.delete()
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class PlayButton(Button, VoiceExtension):
|
|||||||
|
|
||||||
current_player = None
|
current_player = None
|
||||||
if guild['current_player']:
|
if guild['current_player']:
|
||||||
current_player = await self.get_player_message(interaction, guild['current_player'])
|
current_player = await self.get_menu_message(interaction, guild['current_player'])
|
||||||
|
|
||||||
if current_player and interaction.message:
|
if current_player and interaction.message:
|
||||||
logging.debug(f"Deleting interaction message {interaction.message.id}: current player {current_player.id} found")
|
logging.debug(f"Deleting interaction message {interaction.message.id}: current player {current_player.id} found")
|
||||||
@@ -130,7 +130,7 @@ class PlayButton(Button, VoiceExtension):
|
|||||||
await interaction.respond(response_message, delete_after=15)
|
await interaction.respond(response_message, delete_after=15)
|
||||||
|
|
||||||
class ListenView(View):
|
class ListenView(View):
|
||||||
def __init__(self, item: Track | Album | Artist | Playlist | list[Track], *items: Item, timeout: float | None = None, disable_on_timeout: bool = False):
|
def __init__(self, item: Track | Album | Artist | Playlist | list[Track], *items: Item, timeout: float | None = 3600, disable_on_timeout: bool = False):
|
||||||
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
super().__init__(*items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||||
logging.debug(f"Creating view for type: '{type(item).__name__}'")
|
logging.debug(f"Creating view for type: '{type(item).__name__}'")
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ class LyricsButton(Button, VoiceExtension):
|
|||||||
|
|
||||||
class MenuView(View, VoiceExtension):
|
class MenuView(View, VoiceExtension):
|
||||||
|
|
||||||
def __init__(self, ctx: ApplicationContext | Interaction, *items: Item, timeout: float | None = 3600, disable_on_timeout: bool = True):
|
def __init__(self, ctx: ApplicationContext | Interaction | RawReactionActionEvent, *items: Item, timeout: float | None = 3600, disable_on_timeout: bool = False):
|
||||||
View.__init__(self, *items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
View.__init__(self, *items, timeout=timeout, disable_on_timeout=disable_on_timeout)
|
||||||
VoiceExtension.__init__(self, None)
|
VoiceExtension.__init__(self, None)
|
||||||
if not ctx.guild_id:
|
if not ctx.guild_id:
|
||||||
@@ -167,7 +167,7 @@ class MenuView(View, VoiceExtension):
|
|||||||
self.add_item(self.next_button)
|
self.add_item(self.next_button)
|
||||||
self.add_item(self.shuffle_button)
|
self.add_item(self.shuffle_button)
|
||||||
|
|
||||||
if len(cast(VoiceChannel, self.ctx.channel).members) > 2:
|
if isinstance(self.ctx, RawReactionActionEvent) or len(cast(VoiceChannel, self.ctx.channel).members) > 2:
|
||||||
self.like_button.disabled = True
|
self.like_button.disabled = True
|
||||||
elif likes and current_track and str(current_track['id']) in [str(like.id) for like in likes]:
|
elif likes and current_track and str(current_track['id']) in [str(like.id) for like in likes]:
|
||||||
self.like_button.style = ButtonStyle.success
|
self.like_button.style = ButtonStyle.success
|
||||||
@@ -179,3 +179,17 @@ class MenuView(View, VoiceExtension):
|
|||||||
self.add_item(self.lyrics_button)
|
self.add_item(self.lyrics_button)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
async def on_timeout(self) -> None:
|
||||||
|
logging.debug('Menu timed out...')
|
||||||
|
if not self.ctx.guild_id:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.guild['current_player']:
|
||||||
|
self.db.update(self.ctx.guild_id, {'current_player': None, 'previous_tracks': []})
|
||||||
|
message = await self.get_menu_message(self.ctx, self.guild['current_player'])
|
||||||
|
if message:
|
||||||
|
await message.delete()
|
||||||
|
logging.debug('Successfully deleted menu message')
|
||||||
|
else:
|
||||||
|
logging.debug('No menu message found')
|
||||||
Reference in New Issue
Block a user