Skip to content
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 84 additions & 24 deletions core/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,12 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None):
"author_name": (
getattr(m.embeds[0].author, "name", "").split(" (")[0]
if m.embeds and m.embeds[0].author and m.author == self.bot.user
else getattr(m.author, "name", None)
if m.author != self.bot.user
else None
else getattr(m.author, "name", None) if m.author != self.bot.user else None
),
"author_avatar": (
getattr(m.embeds[0].author, "icon_url", None)
if m.embeds and m.embeds[0].author and m.author == self.bot.user
else m.author.display_avatar.url
if m.author != self.bot.user
else None
else m.author.display_avatar.url if m.author != self.bot.user else None
),
}
async for m in channel.history(limit=None, oldest_first=True)
Expand Down Expand Up @@ -849,11 +845,9 @@ async def send_genesis_message():
if getattr(self, "_selected_thread_creation_menu_option", None) and self.bot.config.get(
"thread_creation_menu_selection_log"
):
opt = self._selected_thread_creation_menu_option
path = self._selected_thread_creation_menu_option
try:
log_txt = f"Selected menu option: {opt.get('label')} ({opt.get('type')})"
if opt.get("type") == "command":
log_txt += f" -> {opt.get('callback')}"
log_txt = f"Selected menu path: {' -> '.join(path)}"
await channel.send(embed=discord.Embed(description=log_txt, color=self.bot.mod_color))
except Exception:
logger.warning(
Expand Down Expand Up @@ -2659,29 +2653,44 @@ async def create(
placeholder = "Select an option to contact the staff team."
timeout = 20

options = self.bot.config.get("thread_creation_menu_options") or {}
submenus = self.bot.config.get("thread_creation_menu_submenus") or {}

# Minimal inline view implementation (avoid importing plugin code)

thread.ready = False # not ready yet

class _ThreadCreationMenuSelect(discord.ui.Select):
def __init__(self, outer_thread: Thread):
def __init__(
self,
bot,
outer_thread: Thread,
option_data: dict,
menu_msg: discord.Message,
path: list,
is_home: bool = True,
):
self.bot = bot
self.outer_thread = outer_thread
opts = [
self.option_data = option_data
self.menu_msg = menu_msg
self.path = path
options = [
discord.SelectOption(
label=o["label"],
description=o["description"],
emoji=o["emoji"],
)
for o in options.values()
for o in option_data.values()
]
if not is_home:
options.append(
discord.SelectOption(
label="main menu", description="Return to the main menu", emoji="🏠"
)
)
super().__init__(
placeholder=placeholder,
min_values=1,
max_values=1,
options=opts,
options=options,
)

async def callback(self, interaction: discord.Interaction):
Expand All @@ -2696,8 +2705,35 @@ async def callback(self, interaction: discord.Interaction):
chosen_label = self.values[0]
# Resolve option key
key = chosen_label.lower().replace(" ", "_")
selected = options.get(key)
self.outer_thread._selected_thread_creation_menu_option = selected
if key == "main_menu":
# From a submenu, go back to main menu. This is achieved by rebuilding the view.
option_data = self.bot.config.get("thread_creation_menu_options") or {}
new_view = _ThreadCreationMenuView(
self.bot,
self.outer_thread,
option_data,
self.menu_msg,
path=[],
is_home=True,
)
return await self.menu_msg.edit(view=new_view)
self.path.append(chosen_label)
selected: dict = self.option_data.get(key, {})
if selected.get("type", "command") == "submenu":
# Build new view for submenu
submenu_data = self.bot.config.get("thread_creation_menu_submenus") or {}
option_data = submenu_data.get(key, {})
new_view = _ThreadCreationMenuView(
self.bot,
self.outer_thread,
option_data,
self.menu_msg,
path=self.path,
is_home=False,
)
return await self.menu_msg.edit(view=new_view)

self.outer_thread._selected_thread_creation_menu_option = self.path
# Reflect the selection in the original DM by editing the embed/body
try:
msg = getattr(interaction, "message", None)
Expand Down Expand Up @@ -2936,10 +2972,30 @@ async def callback(self, interaction: discord.Interaction):
ctx_.command.checks = old_checks

class _ThreadCreationMenuView(discord.ui.View):
def __init__(self, outer_thread: Thread):
def __init__(
self,
bot,
outer_thread: Thread,
option_data: dict,
menu_msg: discord.Message,
path: list,
is_home: bool = True,
):
super().__init__(timeout=timeout)
self.outer_thread = outer_thread
self.add_item(_ThreadCreationMenuSelect(outer_thread))
self.path = path
self.menu_msg = menu_msg
self.option_data = option_data
self.add_item(
_ThreadCreationMenuSelect(
bot,
outer_thread,
option_data=option_data,
menu_msg=menu_msg,
path=self.path,
is_home=is_home,
)
)

async def on_timeout(self):
# Timeout -> abort thread creation
Expand Down Expand Up @@ -3061,8 +3117,12 @@ async def on_timeout(self):
embed.set_thumbnail(url=embed_thumb)
except Exception as e:
logger.debug("Thumbnail set failed (ignored): %s", e)
menu_view = _ThreadCreationMenuView(thread)
menu_msg = await recipient.send(embed=embed, view=menu_view)
menu_msg = await recipient.send(embed=embed)
option_data = self.bot.config.get("thread_creation_menu_options") or {}
menu_view = _ThreadCreationMenuView(
self.bot, thread, option_data, menu_msg, path=[], is_home=True
)
menu_msg = await menu_msg.edit(view=menu_view)
# mark thread as pending menu selection
thread._pending_menu = True
# Explicitly attach the message to the view for safety in callbacks
Expand Down Expand Up @@ -3135,10 +3195,10 @@ async def callback(self, interaction: discord.Interaction):
"Failed unsnoozing thread prior to precreate menu selection; continuing.",
exc_info=True,
)
# Define selection variables
chosen_label = self.values[0]
key = chosen_label.lower().replace(" ", "_")
selected = options.get(key)
self.outer_thread._selected_thread_creation_menu_option = selected
# Remove the view
try:
msg = getattr(interaction, "message", None)
Expand Down
Loading