@@ -855,11 +855,9 @@ async def send_genesis_message():
855855 if getattr (self , "_selected_thread_creation_menu_option" , None ) and self .bot .config .get (
856856 "thread_creation_menu_selection_log"
857857 ):
858- opt = self ._selected_thread_creation_menu_option
858+ path = self ._selected_thread_creation_menu_option
859859 try :
860- log_txt = f"Selected menu option: { opt .get ('label' )} ({ opt .get ('type' )} )"
861- if opt .get ("type" ) == "command" :
862- log_txt += f" -> { opt .get ('callback' )} "
860+ log_txt = f"Selected menu path: { ' -> ' .join (path )} "
863861 await channel .send (embed = discord .Embed (description = log_txt , color = self .bot .mod_color ))
864862 except Exception :
865863 logger .warning (
@@ -2665,29 +2663,44 @@ async def create(
26652663 placeholder = "Select an option to contact the staff team."
26662664 timeout = 20
26672665
2668- options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2669- submenus = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2670-
26712666 # Minimal inline view implementation (avoid importing plugin code)
26722667
26732668 thread .ready = False # not ready yet
26742669
26752670 class _ThreadCreationMenuSelect (discord .ui .Select ):
2676- def __init__ (self , outer_thread : Thread ):
2671+ def __init__ (
2672+ self ,
2673+ bot ,
2674+ outer_thread : Thread ,
2675+ option_data : dict ,
2676+ menu_msg : discord .Message ,
2677+ path : list ,
2678+ is_home : bool = True ,
2679+ ):
2680+ self .bot = bot
26772681 self .outer_thread = outer_thread
2678- opts = [
2682+ self .option_data = option_data
2683+ self .menu_msg = menu_msg
2684+ self .path = path
2685+ options = [
26792686 discord .SelectOption (
26802687 label = o ["label" ],
26812688 description = o ["description" ],
26822689 emoji = o ["emoji" ],
26832690 )
2684- for o in options .values ()
2691+ for o in option_data .values ()
26852692 ]
2693+ if not is_home :
2694+ options .append (
2695+ discord .SelectOption (
2696+ label = "main menu" , description = "Return to the main menu" , emoji = "🏠"
2697+ )
2698+ )
26862699 super ().__init__ (
26872700 placeholder = placeholder ,
26882701 min_values = 1 ,
26892702 max_values = 1 ,
2690- options = opts ,
2703+ options = options ,
26912704 )
26922705
26932706 async def callback (self , interaction : discord .Interaction ):
@@ -2702,8 +2715,45 @@ async def callback(self, interaction: discord.Interaction):
27022715 chosen_label = self .values [0 ]
27032716 # Resolve option key
27042717 key = chosen_label .lower ().replace (" " , "_" )
2705- selected = options .get (key )
2706- self .outer_thread ._selected_thread_creation_menu_option = selected
2718+ if key == "main_menu" :
2719+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
2720+ new_view = _ThreadCreationMenuView (
2721+ self .bot ,
2722+ self .outer_thread ,
2723+ option_data ,
2724+ self .menu_msg ,
2725+ path = [],
2726+ is_home = True ,
2727+ )
2728+ return await self .menu_msg .edit (view = new_view )
2729+ selected : dict = self .option_data .get (key , {})
2730+ next_path = [* self .path , chosen_label ]
2731+ if selected .get ("type" , "command" ) == "submenu" :
2732+ submenu_data = self .bot .config .get ("thread_creation_menu_submenus" ) or {}
2733+ submenu_key = selected .get ("callback" , key )
2734+ option_data = submenu_data .get (submenu_key , {})
2735+ if not option_data :
2736+ home_options = self .bot .config .get ("thread_creation_menu_options" ) or {}
2737+ new_view = _ThreadCreationMenuView (
2738+ self .bot ,
2739+ self .outer_thread ,
2740+ home_options ,
2741+ self .menu_msg ,
2742+ path = [],
2743+ is_home = True ,
2744+ )
2745+ return await self .menu_msg .edit (view = new_view )
2746+ new_view = _ThreadCreationMenuView (
2747+ self .bot ,
2748+ self .outer_thread ,
2749+ option_data ,
2750+ self .menu_msg ,
2751+ path = next_path ,
2752+ is_home = False ,
2753+ )
2754+ return await self .menu_msg .edit (view = new_view )
2755+
2756+ self .outer_thread ._selected_thread_creation_menu_option = next_path
27072757 # Reflect the selection in the original DM by editing the embed/body
27082758 try :
27092759 msg = getattr (interaction , "message" , None )
@@ -2942,10 +2992,30 @@ async def callback(self, interaction: discord.Interaction):
29422992 ctx_ .command .checks = old_checks
29432993
29442994 class _ThreadCreationMenuView (discord .ui .View ):
2945- def __init__ (self , outer_thread : Thread ):
2995+ def __init__ (
2996+ self ,
2997+ bot ,
2998+ outer_thread : Thread ,
2999+ option_data : dict ,
3000+ menu_msg : discord .Message ,
3001+ path : list ,
3002+ is_home : bool = True ,
3003+ ):
29463004 super ().__init__ (timeout = timeout )
29473005 self .outer_thread = outer_thread
2948- self .add_item (_ThreadCreationMenuSelect (outer_thread ))
3006+ self .path = path
3007+ self .menu_msg = menu_msg
3008+ self .option_data = option_data
3009+ self .add_item (
3010+ _ThreadCreationMenuSelect (
3011+ bot ,
3012+ outer_thread ,
3013+ option_data = option_data ,
3014+ menu_msg = menu_msg ,
3015+ path = self .path ,
3016+ is_home = is_home ,
3017+ )
3018+ )
29493019
29503020 async def on_timeout (self ):
29513021 # Timeout -> abort thread creation
@@ -3067,8 +3137,12 @@ async def on_timeout(self):
30673137 embed .set_thumbnail (url = embed_thumb )
30683138 except Exception as e :
30693139 logger .debug ("Thumbnail set failed (ignored): %s" , e )
3070- menu_view = _ThreadCreationMenuView (thread )
3071- menu_msg = await recipient .send (embed = embed , view = menu_view )
3140+ menu_msg = await recipient .send (embed = embed )
3141+ option_data = self .bot .config .get ("thread_creation_menu_options" ) or {}
3142+ menu_view = _ThreadCreationMenuView (
3143+ self .bot , thread , option_data , menu_msg , path = [], is_home = True
3144+ )
3145+ menu_msg = await menu_msg .edit (view = menu_view )
30723146 # mark thread as pending menu selection
30733147 thread ._pending_menu = True
30743148 # Explicitly attach the message to the view for safety in callbacks
0 commit comments