fix(modmail): use Button subclasses with callbacks in LayoutView
All checks were successful
deploy / deploy (push) Successful in 21s

Raw discord.ui.Button in LayoutView has no callback -> discord.py
can't dispatch the interaction -> 3s timeout.
Replace with CloseTicketButton/OpenTicketButton subclasses that have
proper callback methods. Remove PersistentCloseButton/PersistentQuickOpen.
This commit is contained in:
Mathis 2026-09-20 19:27:04 +02:00
parent 9312be91fd
commit eec6b2bb9b

View file

@ -149,12 +149,7 @@ async def _send_ticket_panel(channel, user, category_name, initial_message):
container.add_item(discord.ui.TextDisplay(f"**Message initial:**\n{initial_message}")) container.add_item(discord.ui.TextDisplay(f"**Message initial:**\n{initial_message}"))
container.add_item(discord.ui.Separator()) container.add_item(discord.ui.Separator())
close_button = discord.ui.Button( container.add_item(discord.ui.ActionRow(CloseTicketButton()))
label="Fermer le ticket",
style=discord.ButtonStyle.danger,
custom_id="modmail_close_ticket",
)
container.add_item(discord.ui.ActionRow(close_button))
view = discord.ui.LayoutView() view = discord.ui.LayoutView()
view.add_item(container) view.add_item(container)
@ -162,31 +157,29 @@ async def _send_ticket_panel(channel, user, category_name, initial_message):
await channel.send(view=view) await channel.send(view=view)
class PersistentCloseButton(discord.ui.View): class CloseTicketButton(discord.ui.Button):
def __init__(self): def __init__(self):
super().__init__(timeout=None) super().__init__(
@discord.ui.button(
label="Fermer le ticket", label="Fermer le ticket",
style=discord.ButtonStyle.danger, style=discord.ButtonStyle.danger,
custom_id="modmail_close_ticket", custom_id="modmail_close_ticket",
) )
async def close_button(self, interaction: discord.Interaction, button: discord.ui.Button):
async def callback(self, interaction: discord.Interaction):
cog = interaction.client.get_cog("ModMail") cog = interaction.client.get_cog("ModMail")
if cog: if cog:
await cog._close_ticket(interaction.channel, interaction.user) await cog._close_ticket(interaction.channel, interaction.user)
class PersistentQuickOpen(discord.ui.View): class OpenTicketButton(discord.ui.Button):
def __init__(self): def __init__(self):
super().__init__(timeout=None) super().__init__(
@discord.ui.button(
label="Ouvrir le ticket", label="Ouvrir le ticket",
style=discord.ButtonStyle.primary, style=discord.ButtonStyle.primary,
custom_id="modmail_quick_open", custom_id="modmail_quick_open",
) )
async def quick_open(self, interaction: discord.Interaction, button: discord.ui.Button):
async def callback(self, interaction: discord.Interaction):
categories = cfg.get_categories() categories = cfg.get_categories()
if len(categories) == 1: if len(categories) == 1:
key = list(categories.keys())[0] key = list(categories.keys())[0]
@ -400,8 +393,6 @@ class ModMail(commands.Cog):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot self.bot = bot
self._dm_messages: dict[int, list[dict]] = {} self._dm_messages: dict[int, list[dict]] = {}
self.bot.add_view(PersistentCloseButton())
self.bot.add_view(PersistentQuickOpen())
# --- LISTENERS --- # --- LISTENERS ---
@ -447,12 +438,7 @@ class ModMail(commands.Cog):
container.add_item( container.add_item(
discord.ui.TextDisplay(f"## Ouvrir un ticket\nCliquez pour ouvrir un ticket **{cat['name']}**.") discord.ui.TextDisplay(f"## Ouvrir un ticket\nCliquez pour ouvrir un ticket **{cat['name']}**.")
) )
open_button = discord.ui.Button( container.add_item(discord.ui.ActionRow(OpenTicketButton()))
label=f"Ouvrir — {cat['name']}",
style=discord.ButtonStyle.primary,
custom_id="modmail_quick_open",
)
container.add_item(discord.ui.ActionRow(open_button))
view = discord.ui.LayoutView() view = discord.ui.LayoutView()
view.add_item(container) view.add_item(container)