@@ -9,17 +9,19 @@ namespace Discord.Interactions;
99internal sealed class EnumModalComponentConverter < T > : ModalComponentTypeConverter < T >
1010 where T : struct , Enum
1111{
12+ private record Option ( SelectMenuOptionBuilder OptionBuilder , Predicate < IDiscordInteraction > Predicate , T Value ) ;
13+
1214 private readonly bool _isFlags ;
13- private readonly ImmutableArray < ( SelectMenuOptionBuilder Option , Predicate < IDiscordInteraction > Predicate ) > _options ;
15+ private readonly ImmutableArray < Option > _options ;
1416
1517 public EnumModalComponentConverter ( )
1618 {
1719 var names = Enum . GetNames ( typeof ( T ) ) ;
1820 var members = names . SelectMany ( x => typeof ( T ) . GetMember ( x ) ) ;
1921
20- _isFlags = typeof ( T ) . GetCustomAttribute < FlagsAttribute > ( ) is not null ;
22+ _isFlags = typeof ( T ) . IsDefined ( typeof ( FlagsAttribute ) ) ;
2123
22- _options = members . Select ( x =>
24+ _options = members . Select < MemberInfo , Option > ( x =>
2325 {
2426 var selectMenuOptionAttr = x . GetCustomAttribute < SelectMenuOptionAttribute > ( ) ;
2527
@@ -29,10 +31,13 @@ public EnumModalComponentConverter()
2931 if ( ! string . IsNullOrEmpty ( selectMenuOptionAttr ? . Emote ) && ! ( Emote . TryParse ( selectMenuOptionAttr . Emote , out emote ) || Emoji . TryParse ( selectMenuOptionAttr . Emote , out emoji ) ) )
3032 throw new ArgumentException ( $ "Unable to parse { selectMenuOptionAttr . Emote } of { x . DeclaringType . Name } .{ x . Name } into an { typeof ( Emote ) . Name } or an { typeof ( Emoji ) . Name } ") ;
3133
32-
3334 var hideAttr = x . GetCustomAttribute < HideAttribute > ( ) ;
3435 Predicate < IDiscordInteraction > predicate = hideAttr != null ? hideAttr . Predicate : null ;
35- return ( new SelectMenuOptionBuilder ( x . GetCustomAttribute < ChoiceDisplayAttribute > ( ) ? . Name ?? x . Name , x . Name , selectMenuOptionAttr ? . Description , emote != null ? emote : emoji , selectMenuOptionAttr ? . IsDefault ) , predicate ) ;
36+
37+ var value = Enum . Parse < T > ( x . Name ) ;
38+ var optionBuilder = new SelectMenuOptionBuilder ( x . GetCustomAttribute < ChoiceDisplayAttribute > ( ) ? . Name ?? x . Name , x . Name , selectMenuOptionAttr ? . Description , emote != null ? emote : emoji , selectMenuOptionAttr ? . IsDefault ) ;
39+
40+ return new ( optionBuilder , predicate , value ) ;
3641 } ) . ToImmutableArray ( ) ;
3742 }
3843
@@ -62,7 +67,17 @@ public override Task WriteAsync<TBuilder>(TBuilder builder, IDiscordInteraction
6267 if ( selectMenu . MaxValues > 1 && ! _isFlags )
6368 throw new InvalidOperationException ( $ "Enum type { typeof ( T ) . FullName } is not a [Flags] enum, so it cannot be used in a multi-select menu.") ;
6469
65- selectMenu . WithOptions ( [ .. _options . Where ( x => ! x . Predicate ? . Invoke ( interaction ) ?? true ) . Select ( x => x . Option ) ] ) ;
70+ var visibleOptions = _options . Where ( x => ! x . Predicate ? . Invoke ( interaction ) ?? true ) ;
71+
72+ if ( value is T enumValue )
73+ {
74+ foreach ( var option in visibleOptions )
75+ {
76+ option . OptionBuilder . IsDefault = _isFlags ? enumValue . HasFlag ( option . Value ) : enumValue . Equals ( option . Value ) ;
77+ }
78+ }
79+
80+ selectMenu . WithOptions ( [ .. visibleOptions . Select ( x => x . OptionBuilder ) ] ) ;
6681
6782 return Task . CompletedTask ;
6883 }
0 commit comments