@@ -849,11 +849,9 @@ async def send_genesis_message():
849849 if getattr (self , "_selected_thread_creation_menu_option" , None ) and self .bot .config .get (
850850 "thread_creation_menu_selection_log"
851851 ):
852- opt = self ._selected_thread_creation_menu_option
852+ path = self ._selected_thread_creation_menu_option
853853 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' )} "
854+ log_txt = f"Selected menu path: { ' -> ' .join (path )} "
857855 await channel .send (embed = discord .Embed (description = log_txt , color = self .bot .mod_color ))
858856 except Exception :
859857 logger .warning (
@@ -2659,29 +2657,44 @@ async def create(
26592657 placeholder = "Select an option to contact the staff team."
26602658 timeout = 20
26612659
2662- options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2663- submenus = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2664-
26652660 # Minimal inline view implementation (avoid importing plugin code)
26662661
26672662 thread .ready = False # not ready yet
26682663
26692664 class _ThreadCreationMenuSelect (discord .ui .Select ):
2670- def __init__ (self , outer_thread : Thread ):
2665+ def __init__ (
2666+ self ,
2667+ bot ,
2668+ outer_thread : Thread ,
2669+ option_data : dict ,
2670+ menu_msg : discord .Message ,
2671+ path : list ,
2672+ is_home : bool = True ,
2673+ ):
2674+ self .bot = bot
26712675 self .outer_thread = outer_thread
2672- opts = [
2676+ self .option_data = option_data
2677+ self .menu_msg = menu_msg
2678+ self .path = path
2679+ options = [
26732680 discord .SelectOption (
26742681 label = o ["label" ],
26752682 description = o ["description" ],
26762683 emoji = o ["emoji" ],
26772684 )
2678- for o in options .values ()
2685+ for o in option_data .values ()
26792686 ]
2687+ if not is_home :
2688+ options .append (
2689+ discord .SelectOption (
2690+ label = "main menu" , description = "Return to the main menu" , emoji = "🏠"
2691+ )
2692+ )
26802693 super ().__init__ (
26812694 placeholder = placeholder ,
26822695 min_values = 1 ,
26832696 max_values = 1 ,
2684- options = opts ,
2697+ options = options ,
26852698 )
26862699
26872700 async def callback (self , interaction : discord .Interaction ):
@@ -2696,8 +2709,45 @@ async def callback(self, interaction: discord.Interaction):
26962709 chosen_label = self .values [0 ]
26972710 # Resolve option key
26982711 key = chosen_label .lower ().replace (" " , "_" )
2699- selected = options .get (key )
2700- self .outer_thread ._selected_thread_creation_menu_option = selected
2712+ if key == "main_menu" :
2713+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
2714+ new_view = _ThreadCreationMenuView (
2715+ self .bot ,
2716+ self .outer_thread ,
2717+ option_data ,
2718+ self .menu_msg ,
2719+ path = [],
2720+ is_home = True ,
2721+ )
2722+ return await self .menu_msg .edit (view = new_view )
2723+ selected : dict = self .option_data .get (key , {})
2724+ next_path = [* self .path , chosen_label ]
2725+ if selected .get ("type" , "command" ) == "submenu" :
2726+ submenu_data = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2727+ submenu_key = selected .get ("callback" , key )
2728+ option_data = submenu_data .get (submenu_key , {})
2729+ if not option_data :
2730+ home_options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2731+ new_view = _ThreadCreationMenuView (
2732+ self .bot ,
2733+ self .outer_thread ,
2734+ home_options ,
2735+ self .menu_msg ,
2736+ path = [],
2737+ is_home = True ,
2738+ )
2739+ return await self .menu_msg .edit (view = new_view )
2740+ new_view = _ThreadCreationMenuView (
2741+ self .bot ,
2742+ self .outer_thread ,
2743+ option_data ,
2744+ self .menu_msg ,
2745+ path = next_path ,
2746+ is_home = False ,
2747+ )
2748+ return await self .menu_msg .edit (view = new_view )
2749+
2750+ self .outer_thread ._selected_thread_creation_menu_option = next_path
27012751 # Reflect the selection in the original DM by editing the embed/body
27022752 try :
27032753 msg = getattr (interaction , "message" , None )
@@ -2936,10 +2986,30 @@ async def callback(self, interaction: discord.Interaction):
29362986 ctx_ .command .checks = old_checks
29372987
29382988 class _ThreadCreationMenuView (discord .ui .View ):
2939- def __init__ (self , outer_thread : Thread ):
2989+ def __init__ (
2990+ self ,
2991+ bot ,
2992+ outer_thread : Thread ,
2993+ option_data : dict ,
2994+ menu_msg : discord .Message ,
2995+ path : list ,
2996+ is_home : bool = True ,
2997+ ):
29402998 super ().__init__ (timeout = timeout )
29412999 self .outer_thread = outer_thread
2942- self .add_item (_ThreadCreationMenuSelect (outer_thread ))
3000+ self .path = path
3001+ self .menu_msg = menu_msg
3002+ self .option_data = option_data
3003+ self .add_item (
3004+ _ThreadCreationMenuSelect (
3005+ bot ,
3006+ outer_thread ,
3007+ option_data = option_data ,
3008+ menu_msg = menu_msg ,
3009+ path = self .path ,
3010+ is_home = is_home ,
3011+ )
3012+ )
29433013
29443014 async def on_timeout (self ):
29453015 # Timeout -> abort thread creation
@@ -3061,8 +3131,12 @@ async def on_timeout(self):
30613131 embed .set_thumbnail (url = embed_thumb )
30623132 except Exception as e :
30633133 logger .debug ("Thumbnail set failed (ignored): %s" , e )
3064- menu_view = _ThreadCreationMenuView (thread )
3065- menu_msg = await recipient .send (embed = embed , view = menu_view )
3134+ menu_msg = await recipient .send (embed = embed )
3135+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
3136+ menu_view = _ThreadCreationMenuView (
3137+ self .bot , thread , option_data , menu_msg , path = [], is_home = True
3138+ )
3139+ menu_msg = await menu_msg .edit (view = menu_view )
30663140 # mark thread as pending menu selection
30673141 thread ._pending_menu = True
30683142 # Explicitly attach the message to the view for safety in callbacks
0 commit comments