2222
2323FEATURES_PREFIX = "features_"
2424FEATURE_VIEW_PREFIX = FEATURES_PREFIX + "view_"
25+ """{FEATURE_VIEW_PREFIX}{feature.name}:1:{guild_to_check}:{show_all_flag}"""
2526FEATURES_MAIN_LIST = FEATURES_PREFIX + "main_list"
27+ """{FEATURES_MAIN_LIST}:{feature.name}:{guild_to_check or ''}:{show_all_flag}"""
28+ FEATURES_GLOBAL_TOGGLE = FEATURES_PREFIX + "global_toggle_"
29+ """{FEATURES_GLOBAL_TOGGLE}:{feature.name}:{guild_to_check or ''}:{'1' if show_all else '0'}"""
2630FEATURES_GUILD_TOGGLE = FEATURES_PREFIX + "guild_toggle_"
31+ """{FEATURES_GUILD_TOGGLE}:{feature.name}:{guild_id}:{'1' if show_all else '0'}"""
2732
2833FEATURES_PAGINATOR_PREFIX = FEATURES_PREFIX + "paginator_"
2934FEATURES_PER_PAGE = 10
@@ -208,7 +213,7 @@ async def show_feature(
208213 accessory = disnake .ui .Button (
209214 label = "Click to disable in Guild" if guild_has_feature else "Click to enable in Guild" ,
210215 style = disnake .ButtonStyle .green if guild_has_feature else disnake .ButtonStyle .grey ,
211- custom_id = f"guild_feature_toggle :{ guild_to_check or '' } :{ feature .name } :{ show_all_flag } " ,
216+ custom_id = f"{ FEATURES_GUILD_TOGGLE } :{ guild_to_check or '' } :{ feature .name } :{ show_all_flag } " ,
212217 ),
213218 )
214219 )
@@ -234,7 +239,7 @@ async def show_feature(
234239 disnake .ui .ActionRow (
235240 disnake .ui .StringSelect (
236241 placeholder = status_options [feature .enabled ].label ,
237- custom_id = f"{ FEATURES_GUILD_TOGGLE } :{ feature .name } :"
242+ custom_id = f"{ FEATURES_GLOBAL_TOGGLE } :{ feature .name } :"
238243 f"{ guild_to_check or '' } :{ '1' if show_all else '0' } " ,
239244 options = [v for k , v in status_options .items () if k != feature .enabled ],
240245 )
@@ -370,9 +375,15 @@ def _get_feature_page(
370375 show_all = False
371376
372377 guild_to_check : int | None = None
378+ # if guild_to_check isn't set, set it to the current guild if available
379+ # and enable show_all
380+ if not for_guild and getattr (ctx , "guild" , None ):
381+ for_guild = ctx .guild
382+ show_all = True
383+
373384 if for_guild :
374385 title = "Guild Features"
375- guild_to_check = getattr (for_guild , "id" , None ) or for_guild # type: ignore
386+ guild_to_check = getattr (for_guild , "id" , None ) or for_guild or getattr ( ctx . guild , "id" , None ) # type: ignore
376387 guild_db = await self .bot .ensure_guild (guild_to_check )
377388 if show_all :
378389 features = sorted (self .features .items ())
@@ -409,42 +420,51 @@ def _get_feature_page(
409420
410421 # Determine if a guild_id should be included in the feature view button
411422 show_all_flag = "1" if show_all else "0"
412- for _ , feature in page_features :
413- if feature .enabled is True :
414- button_style = disnake .ButtonStyle .green
415- guild_status = "\U0001f7e2 " # green circle
416- elif feature .enabled is None :
417- button_style = disnake .ButtonStyle .gray
418- guild_status = "\U000026ab " # black circle
419- else :
420- button_style = disnake .ButtonStyle .danger
421- guild_status = "\U0001f534 " # red circle
423+ if page_features :
424+ for _ , feature in page_features :
425+ if feature .enabled is True :
426+ button_style = disnake .ButtonStyle .green
427+ guild_status = "\U0001f7e2 " # green circle
428+ elif feature .enabled is None :
429+ button_style = disnake .ButtonStyle .gray
430+ guild_status = "\U000026ab " # black circle
431+ else :
432+ button_style = disnake .ButtonStyle .danger
433+ guild_status = "\U0001f534 " # red circle
422434
423- if check_guild :
424- if feature .name in guild_feature_ids :
425- guild_status = "\U0001f7e0 " # orange circle
426- elif await self .bot .guild_has_feature (guild_to_check , feature .name , include_feature_status = False ):
427- guild_status = "\U0001f7e1 " # yellow circle
435+ if check_guild :
436+ if feature .name in guild_feature_ids :
437+ guild_status = "\U0001f7e0 " # orange circle
438+ elif await self .bot .guild_has_feature (guild_to_check , feature .name , include_feature_status = False ):
439+ guild_status = "\U0001f7e1 " # yellow circle
428440
429- if button_style not in needed_keys :
430- needed_keys [button_style ] = key_defaults [button_style ]
431- if guild_status in key_defaults and guild_status not in needed_keys :
432- needed_keys [guild_status ] = key_defaults [guild_status ]
441+ if button_style not in needed_keys :
442+ needed_keys [button_style ] = key_defaults [button_style ]
443+ if guild_status in key_defaults and guild_status not in needed_keys :
444+ needed_keys [guild_status ] = key_defaults [guild_status ]
433445
434- components [- 1 ].children .append (
435- disnake .ui .Section (
436- f"{ feature .name } " ,
437- accessory = disnake .ui .Button (
438- emoji = guild_status ,
439- style = button_style ,
440- custom_id = (
441- f"{ FEATURE_VIEW_PREFIX } { feature .name } :1:{ guild_to_check } :{ show_all_flag } "
442- if guild_to_check
443- else f"{ FEATURE_VIEW_PREFIX } { feature .name } :1:::"
446+ components [- 1 ].children .append (
447+ disnake .ui .Section (
448+ f"{ feature .name } " ,
449+ accessory = disnake .ui .Button (
450+ emoji = guild_status ,
451+ style = button_style ,
452+ custom_id = (
453+ f"{ FEATURE_VIEW_PREFIX } { feature .name } :1:{ guild_to_check } :{ show_all_flag } "
454+ if guild_to_check
455+ else f"{ FEATURE_VIEW_PREFIX } { feature .name } :1:::"
456+ ),
444457 ),
445- ),
458+ )
446459 )
447- )
460+ # we are here because there are no features
461+ else :
462+ if guild_to_check :
463+ components [- 1 ].children .append (
464+ disnake .ui .TextDisplay (f"No features are overridden for { guild_to_check } " )
465+ )
466+ else :
467+ components [- 1 ].children .append (disnake .ui .TextDisplay ("No features are overridden." ))
448468
449469 # Paginator buttons
450470 if total >= FEATURES_PER_PAGE :
@@ -705,14 +725,14 @@ async def cmd_guild_remove(
705725 )
706726
707727 @commands .Cog .listener (disnake .Event .dropdown )
708- async def features_guild_toggle_listener (self , inter : disnake .MessageInteraction ) -> None :
728+ async def FEATURES_GLOBAL_TOGGLE_listener (self , inter : disnake .MessageInteraction ) -> None :
709729 """Listen for guild feature toggle select."""
710- if not inter .component .custom_id or not inter .component .custom_id .startswith (FEATURES_GUILD_TOGGLE ):
730+ if not inter .component .custom_id or not inter .component .custom_id .startswith (FEATURES_GLOBAL_TOGGLE ):
711731 return
712732 if not await self .bot .is_owner (inter .author ):
713733 await inter .response .send_message ("You do not own this bot." , ephemeral = True )
714734 return
715- # Parse custom_id: FEATURES_GUILD_TOGGLE :feature_name:guild_id:show_all_flag
735+ # Parse custom_id: FEATURES_GLOBAL_TOGGLE :feature_name:guild_id:show_all_flag
716736 _ , feature_name , guild_id , show_all_flag = inter .component .custom_id .split (":" , 3 )
717737 show_all = show_all_flag == "1"
718738 feature = self .features .get (feature_name )
@@ -755,12 +775,11 @@ async def features_guild_toggle_listener(self, inter: disnake.MessageInteraction
755775 @commands .Cog .listener ("on_button_click" )
756776 async def guild_feature_toggle_listener (self , inter : disnake .MessageInteraction ) -> None :
757777 """Listen for guild feature toggle button."""
758- if not inter .component .custom_id or not inter .component .custom_id .startswith ("guild_feature_toggle: " ):
778+ if not inter .component .custom_id or not inter .component .custom_id .startswith (f" { FEATURES_GUILD_TOGGLE } " ):
759779 return
760780 if not await self .bot .is_owner (inter .author ):
761781 await inter .response .send_message ("You do not own this bot." , ephemeral = True )
762782 return
763- # Parse custom_id: guild_feature_toggle:guild_id:feature_name:show_all_flag
764783 _ , guild_id , feature_name , show_all_flag = inter .component .custom_id .split (":" , 3 )
765784 feature = self .features .get (feature_name )
766785 if not feature :
@@ -801,8 +820,6 @@ async def guild_feature_toggle_listener(self, inter: disnake.MessageInteraction)
801820 async def cog_check (self , ctx : commands .Context ) -> bool :
802821 """Require all commands in this cog are by the bot author and are in guilds."""
803822 if await self .bot .is_owner (ctx .author ):
804- if not ctx .guild :
805- raise commands .NoPrivateMessage ()
806823 return True
807824
808825 raise commands .NotOwner ("You do not own this bot." )
0 commit comments