Refactor message dispatch and playlist view error handling

Updated dispatch_message to use discord.utils.MISSING and improved content formatting. Added error handling in PlaylistView for VoicelinkException and refactored on_timeout logic in PlaylistViewManager to avoid duplication. Minor improvements to playlist track rendering.
This commit is contained in:
Choco
2025-11-20 23:34:34 +08:00
parent e99aefefcf
commit e2ba8b472a
2 changed files with 25 additions and 21 deletions

View File

@@ -30,7 +30,6 @@ from itertools import zip_longest
from typing import Dict, Optional, Union
from timeit import default_timer as timer
from discord.ext import commands
from discord.utils import MISSING
from .mongodb import MongoDBHandler
from .language import LangHandler
@@ -303,7 +302,7 @@ async def dispatch_message(
*params,
view: Optional[discord.ui.View] = None,
file: Optional[discord.File] = None,
delete_after: Optional[float] = MISSING,
delete_after: Optional[float] = discord.utils.MISSING,
ephemeral: bool = False,
requires_fetch: bool = False
) -> Optional[discord.Message]:
@@ -323,12 +322,12 @@ async def dispatch_message(
Returns:
The sent message object, or None.
"""
if content is None:
if not content:
content = "No content provided."
# Determine the text to send
embed = content if isinstance(content, discord.Embed) else None
text = None if embed else content.format(*params)
text = None if embed else str(content).format(*params) if params else str(content)
# Determine the sending function
send_func = (
@@ -354,13 +353,13 @@ async def dispatch_message(
send_kwargs["view"] = view
if "delete_after" in send_func.__code__.co_varnames:
if delete_after is MISSING and settings and ctx.channel.id == settings.get("music_request_channel", {}).get("text_channel_id"):
if delete_after is discord.utils.MISSING and settings and ctx.channel.id == settings.get("music_request_channel", {}).get("text_channel_id"):
delete_after = 10
send_kwargs["delete_after"] = delete_after if delete_after != MISSING else None
send_kwargs["delete_after"] = delete_after if delete_after is not discord.utils.MISSING else None
if "ephemeral" in send_func.__code__.co_varnames:
send_kwargs["ephemeral"] = ephemeral
# Send the message or embed
message = await send_func(**send_kwargs)

View File

@@ -31,9 +31,10 @@ from typing import Any
from .utils import DynamicViewManager, Pagination
from .pagination import PaginationView
from ..config import Config
from ..utils import format_ms, truncate_string
from ..utils import format_ms, truncate_string, dispatch_message
from ..mongodb import MongoDBHandler
from ..language import LangHandler
from ..exceptions import VoicelinkException
class PlaylistDropdown(discord.ui.Select):
def __init__(self, results: list[dict[str, Any]], lang: str) -> None:
@@ -108,7 +109,7 @@ class PlaylistView(PaginationView):
embed.description += f"\n\n**{texts[5]}:**\n"
if tracks:
for index, track in enumerate(tracks, start=self.pagination.start_index + 1):
if self.type == "playlist":
if isinstance(track, dict):
source_emoji = Config().get_source_config(track['sourceName'], 'emoji')
track_info = f"{source_emoji} `{index:>2}.` `[{format_ms(track['length'])}]` [{truncate_string(track['title'])}]({track['uri']})"
else:
@@ -140,6 +141,10 @@ class PlaylistView(PaginationView):
}
return super().update_view(extra_states)
async def on_error(self, interaction: discord.Interaction, error: Exception, item: discord.ui.Item) -> None:
if isinstance(error, VoicelinkException):
return await dispatch_message(interaction, content=getattr(error, 'original', error), ephemeral=True)
async def update_message(self, interaction: discord.Interaction) -> None:
"""Update the view and edit the message with the new embed."""
self.update_view()
@@ -199,6 +204,18 @@ class PlaylistViewManager(DynamicViewManager):
self.response: discord.Message = None
self.add_item(PlaylistDropdown(results, self.lang))
async def on_timeout(self) -> None:
for view in self._views.values():
view.stop()
for child in self.current_view.children:
child.disabled = True
try:
await self.response.edit(view=self)
except:
pass
def get_width(self, s):
width = 0
for char in str(s):
@@ -214,18 +231,6 @@ class PlaylistViewManager(DynamicViewManager):
padding = width - current_width
return s + " " * padding
async def on_timeout(self) -> None:
for view in self._views.values():
view.stop()
for child in self.current_view.children:
child.disabled = True
try:
await self.response.edit(view=self)
except:
pass
def build_embed(self) -> discord.Embed:
"""
Build the embed for the playlist overview.