@@ -224,16 +224,12 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None):
224224 "author_name" : (
225225 getattr (m .embeds [0 ].author , "name" , "" ).split (" (" )[0 ]
226226 if m .embeds and m .embeds [0 ].author and m .author == self .bot .user
227- else getattr (m .author , "name" , None )
228- if m .author != self .bot .user
229- else None
227+ else getattr (m .author , "name" , None ) if m .author != self .bot .user else None
230228 ),
231229 "author_avatar" : (
232230 getattr (m .embeds [0 ].author , "icon_url" , None )
233231 if m .embeds and m .embeds [0 ].author and m .author == self .bot .user
234- else m .author .display_avatar .url
235- if m .author != self .bot .user
236- else None
232+ else m .author .display_avatar .url if m .author != self .bot .user else None
237233 ),
238234 }
239235 async for m in channel .history (limit = None , oldest_first = True )
@@ -849,11 +845,9 @@ async def send_genesis_message():
849845 if getattr (self , "_selected_thread_creation_menu_option" , None ) and self .bot .config .get (
850846 "thread_creation_menu_selection_log"
851847 ):
852- opt = self ._selected_thread_creation_menu_option
848+ path = self ._selected_thread_creation_menu_option
853849 try :
854- log_txt = f"Selected menu option: { opt .get ('label' )} ({ opt .get ('type' )} )"
855- if opt .get ("type" ) == "command" :
856- log_txt += f" -> { opt .get ('callback' )} "
850+ log_txt = f"Selected menu path: { ' -> ' .join (path )} "
857851 await channel .send (embed = discord .Embed (description = log_txt , color = self .bot .mod_color ))
858852 except Exception :
859853 logger .warning (
@@ -2659,29 +2653,44 @@ async def create(
26592653 placeholder = "Select an option to contact the staff team."
26602654 timeout = 20
26612655
2662- options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2663- submenus = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2664-
26652656 # Minimal inline view implementation (avoid importing plugin code)
26662657
26672658 thread .ready = False # not ready yet
26682659
26692660 class _ThreadCreationMenuSelect (discord .ui .Select ):
2670- def __init__ (self , outer_thread : Thread ):
2661+ def __init__ (
2662+ self ,
2663+ bot ,
2664+ outer_thread : Thread ,
2665+ option_data : dict ,
2666+ menu_msg : discord .Message ,
2667+ path : list ,
2668+ is_home : bool = True ,
2669+ ):
2670+ self .bot = bot
26712671 self .outer_thread = outer_thread
2672- opts = [
2672+ self .option_data = option_data
2673+ self .menu_msg = menu_msg
2674+ self .path = path
2675+ options = [
26732676 discord .SelectOption (
26742677 label = o ["label" ],
26752678 description = o ["description" ],
26762679 emoji = o ["emoji" ],
26772680 )
2678- for o in options .values ()
2681+ for o in option_data .values ()
26792682 ]
2683+ if not is_home :
2684+ options .append (
2685+ discord .SelectOption (
2686+ label = "main menu" , description = "Return to the main menu" , emoji = "🏠"
2687+ )
2688+ )
26802689 super ().__init__ (
26812690 placeholder = placeholder ,
26822691 min_values = 1 ,
26832692 max_values = 1 ,
2684- options = opts ,
2693+ options = options ,
26852694 )
26862695
26872696 async def callback (self , interaction : discord .Interaction ):
@@ -2696,8 +2705,45 @@ async def callback(self, interaction: discord.Interaction):
26962705 chosen_label = self .values [0 ]
26972706 # Resolve option key
26982707 key = chosen_label .lower ().replace (" " , "_" )
2699- selected = options .get (key )
2700- self .outer_thread ._selected_thread_creation_menu_option = selected
2708+ if key == "main_menu" :
2709+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
2710+ new_view = _ThreadCreationMenuView (
2711+ self .bot ,
2712+ self .outer_thread ,
2713+ option_data ,
2714+ self .menu_msg ,
2715+ path = [],
2716+ is_home = True ,
2717+ )
2718+ return await self .menu_msg .edit (view = new_view )
2719+ selected : dict = self .option_data .get (key , {})
2720+ next_path = [* self .path , chosen_label ]
2721+ if selected .get ("type" , "command" ) == "submenu" :
2722+ submenu_data = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2723+ submenu_key = selected .get ("callback" , key )
2724+ option_data = submenu_data .get (submenu_key , {})
2725+ if not option_data :
2726+ home_options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2727+ new_view = _ThreadCreationMenuView (
2728+ self .bot ,
2729+ self .outer_thread ,
2730+ home_options ,
2731+ self .menu_msg ,
2732+ path = [],
2733+ is_home = True ,
2734+ )
2735+ return await self .menu_msg .edit (view = new_view )
2736+ new_view = _ThreadCreationMenuView (
2737+ self .bot ,
2738+ self .outer_thread ,
2739+ option_data ,
2740+ self .menu_msg ,
2741+ path = next_path ,
2742+ is_home = False ,
2743+ )
2744+ return await self .menu_msg .edit (view = new_view )
2745+
2746+ self .outer_thread ._selected_thread_creation_menu_option = next_path
27012747 # Reflect the selection in the original DM by editing the embed/body
27022748 try :
27032749 msg = getattr (interaction , "message" , None )
@@ -2936,10 +2982,30 @@ async def callback(self, interaction: discord.Interaction):
29362982 ctx_ .command .checks = old_checks
29372983
29382984 class _ThreadCreationMenuView (discord .ui .View ):
2939- def __init__ (self , outer_thread : Thread ):
2985+ def __init__ (
2986+ self ,
2987+ bot ,
2988+ outer_thread : Thread ,
2989+ option_data : dict ,
2990+ menu_msg : discord .Message ,
2991+ path : list ,
2992+ is_home : bool = True ,
2993+ ):
29402994 super ().__init__ (timeout = timeout )
29412995 self .outer_thread = outer_thread
2942- self .add_item (_ThreadCreationMenuSelect (outer_thread ))
2996+ self .path = path
2997+ self .menu_msg = menu_msg
2998+ self .option_data = option_data
2999+ self .add_item (
3000+ _ThreadCreationMenuSelect (
3001+ bot ,
3002+ outer_thread ,
3003+ option_data = option_data ,
3004+ menu_msg = menu_msg ,
3005+ path = self .path ,
3006+ is_home = is_home ,
3007+ )
3008+ )
29433009
29443010 async def on_timeout (self ):
29453011 # Timeout -> abort thread creation
@@ -3061,8 +3127,12 @@ async def on_timeout(self):
30613127 embed .set_thumbnail (url = embed_thumb )
30623128 except Exception as e :
30633129 logger .debug ("Thumbnail set failed (ignored): %s" , e )
3064- menu_view = _ThreadCreationMenuView (thread )
3065- menu_msg = await recipient .send (embed = embed , view = menu_view )
3130+ menu_msg = await recipient .send (embed = embed )
3131+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
3132+ menu_view = _ThreadCreationMenuView (
3133+ self .bot , thread , option_data , menu_msg , path = [], is_home = True
3134+ )
3135+ menu_msg = await menu_msg .edit (view = menu_view )
30663136 # mark thread as pending menu selection
30673137 thread ._pending_menu = True
30683138 # Explicitly attach the message to the view for safety in callbacks
0 commit comments