@@ -865,11 +865,9 @@ async def send_genesis_message():
865865 if getattr (self , "_selected_thread_creation_menu_option" , None ) and self .bot .config .get (
866866 "thread_creation_menu_selection_log"
867867 ):
868- opt = self ._selected_thread_creation_menu_option
868+ path = self ._selected_thread_creation_menu_option
869869 try :
870- log_txt = f"Selected menu option: { opt .get ('label' )} ({ opt .get ('type' )} )"
871- if opt .get ("type" ) == "command" :
872- log_txt += f" -> { opt .get ('callback' )} "
870+ log_txt = f"Selected menu path: { ' -> ' .join (path )} "
873871 await channel .send (embed = discord .Embed (description = log_txt , color = self .bot .mod_color ))
874872 except Exception :
875873 logger .warning (
@@ -2668,29 +2666,44 @@ async def create(
26682666 placeholder = "Select an option to contact the staff team."
26692667 timeout = 20
26702668
2671- options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2672- submenus = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2673-
26742669 # Minimal inline view implementation (avoid importing plugin code)
26752670
26762671 thread .ready = False # not ready yet
26772672
26782673 class _ThreadCreationMenuSelect (discord .ui .Select ):
2679- def __init__ (self , outer_thread : Thread ):
2674+ def __init__ (
2675+ self ,
2676+ bot ,
2677+ outer_thread : Thread ,
2678+ option_data : dict ,
2679+ menu_msg : discord .Message ,
2680+ path : list ,
2681+ is_home : bool = True ,
2682+ ):
2683+ self .bot = bot
26802684 self .outer_thread = outer_thread
2681- opts = [
2685+ self .option_data = option_data
2686+ self .menu_msg = menu_msg
2687+ self .path = path
2688+ options = [
26822689 discord .SelectOption (
26832690 label = o ["label" ],
26842691 description = o ["description" ],
26852692 emoji = o ["emoji" ],
26862693 )
2687- for o in options .values ()
2694+ for o in option_data .values ()
26882695 ]
2696+ if not is_home :
2697+ options .append (
2698+ discord .SelectOption (
2699+ label = "main menu" , description = "Return to the main menu" , emoji = "🏠"
2700+ )
2701+ )
26892702 super ().__init__ (
26902703 placeholder = placeholder ,
26912704 min_values = 1 ,
26922705 max_values = 1 ,
2693- options = opts ,
2706+ options = options ,
26942707 )
26952708
26962709 async def callback (self , interaction : discord .Interaction ):
@@ -2705,8 +2718,45 @@ async def callback(self, interaction: discord.Interaction):
27052718 chosen_label = self .values [0 ]
27062719 # Resolve option key
27072720 key = chosen_label .lower ().replace (" " , "_" )
2708- selected = options .get (key )
2709- self .outer_thread ._selected_thread_creation_menu_option = selected
2721+ if key == "main_menu" :
2722+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
2723+ new_view = _ThreadCreationMenuView (
2724+ self .bot ,
2725+ self .outer_thread ,
2726+ option_data ,
2727+ self .menu_msg ,
2728+ path = [],
2729+ is_home = True ,
2730+ )
2731+ return await self .menu_msg .edit (view = new_view )
2732+ selected : dict = self .option_data .get (key , {})
2733+ next_path = [* self .path , chosen_label ]
2734+ if selected .get ("type" , "command" ) == "submenu" :
2735+ submenu_data = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2736+ submenu_key = selected .get ("callback" , key )
2737+ option_data = submenu_data .get (submenu_key , {})
2738+ if not option_data :
2739+ home_options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2740+ new_view = _ThreadCreationMenuView (
2741+ self .bot ,
2742+ self .outer_thread ,
2743+ home_options ,
2744+ self .menu_msg ,
2745+ path = [],
2746+ is_home = True ,
2747+ )
2748+ return await self .menu_msg .edit (view = new_view )
2749+ new_view = _ThreadCreationMenuView (
2750+ self .bot ,
2751+ self .outer_thread ,
2752+ option_data ,
2753+ self .menu_msg ,
2754+ path = next_path ,
2755+ is_home = False ,
2756+ )
2757+ return await self .menu_msg .edit (view = new_view )
2758+
2759+ self .outer_thread ._selected_thread_creation_menu_option = next_path
27102760 # Reflect the selection in the original DM by editing the embed/body
27112761 try :
27122762 msg = getattr (interaction , "message" , None )
@@ -2945,10 +2995,30 @@ async def callback(self, interaction: discord.Interaction):
29452995 ctx_ .command .checks = old_checks
29462996
29472997 class _ThreadCreationMenuView (discord .ui .View ):
2948- def __init__ (self , outer_thread : Thread ):
2998+ def __init__ (
2999+ self ,
3000+ bot ,
3001+ outer_thread : Thread ,
3002+ option_data : dict ,
3003+ menu_msg : discord .Message ,
3004+ path : list ,
3005+ is_home : bool = True ,
3006+ ):
29493007 super ().__init__ (timeout = timeout )
29503008 self .outer_thread = outer_thread
2951- self .add_item (_ThreadCreationMenuSelect (outer_thread ))
3009+ self .path = path
3010+ self .menu_msg = menu_msg
3011+ self .option_data = option_data
3012+ self .add_item (
3013+ _ThreadCreationMenuSelect (
3014+ bot ,
3015+ outer_thread ,
3016+ option_data = option_data ,
3017+ menu_msg = menu_msg ,
3018+ path = self .path ,
3019+ is_home = is_home ,
3020+ )
3021+ )
29523022
29533023 async def on_timeout (self ):
29543024 # Timeout -> abort thread creation
@@ -3070,8 +3140,12 @@ async def on_timeout(self):
30703140 embed .set_thumbnail (url = embed_thumb )
30713141 except Exception as e :
30723142 logger .debug ("Thumbnail set failed (ignored): %s" , e )
3073- menu_view = _ThreadCreationMenuView (thread )
3074- menu_msg = await recipient .send (embed = embed , view = menu_view )
3143+ menu_msg = await recipient .send (embed = embed )
3144+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
3145+ menu_view = _ThreadCreationMenuView (
3146+ self .bot , thread , option_data , menu_msg , path = [], is_home = True
3147+ )
3148+ menu_msg = await menu_msg .edit (view = menu_view )
30753149 # mark thread as pending menu selection
30763150 thread ._pending_menu = True
30773151 # Explicitly attach the message to the view for safety in callbacks
0 commit comments