| @@ -34,7 +34,7 @@ namespace Discord.Interactions.Builders | |||||
| public override ModalCommandParameterBuilder SetParameterType(Type type) | public override ModalCommandParameterBuilder SetParameterType(Type type) | ||||
| { | { | ||||
| if (typeof(IModal).IsAssignableFrom(type)) | if (typeof(IModal).IsAssignableFrom(type)) | ||||
| Modal = ModalUtils.GetOrAdd(type); | |||||
| Modal = ModalUtils.GetOrAdd(type, Command.Module.InteractionService); | |||||
| return base.SetParameterType(type); | return base.SetParameterType(type); | ||||
| } | } | ||||
| @@ -20,6 +20,7 @@ namespace Discord.Interactions | |||||
| /// </summary> | /// </summary> | ||||
| public class ModalInfo | public class ModalInfo | ||||
| { | { | ||||
| internal readonly InteractionService _interactionService; | |||||
| internal readonly ModalInitializer _initializer; | internal readonly ModalInitializer _initializer; | ||||
| /// <summary> | /// <summary> | ||||
| @@ -54,6 +55,7 @@ namespace Discord.Interactions | |||||
| TextComponents = Components.OfType<TextInputComponentInfo>().ToImmutableArray(); | TextComponents = Components.OfType<TextInputComponentInfo>().ToImmutableArray(); | ||||
| _interactionService = builder._interactionService; | |||||
| _initializer = builder.ModalInitializer; | _initializer = builder.ModalInitializer; | ||||
| } | } | ||||
| @@ -199,7 +199,8 @@ namespace Discord.Interactions | |||||
| _compTypeConverterMap = new TypeMap<ComponentTypeConverter, IComponentInteractionData>(this, new Dictionary<Type, ComponentTypeConverter>(), | _compTypeConverterMap = new TypeMap<ComponentTypeConverter, IComponentInteractionData>(this, new Dictionary<Type, ComponentTypeConverter>(), | ||||
| new Dictionary<Type, Type> | new Dictionary<Type, Type> | ||||
| { | { | ||||
| [typeof(Array)] = typeof(DefaultArrayComponentConverter<>) | |||||
| [typeof(Array)] = typeof(DefaultArrayComponentConverter<>), | |||||
| [typeof(IConvertible)] = typeof(DefaultValueComponentConverter<>) | |||||
| }); | }); | ||||
| _typeReaderMap = new TypeMap<TypeReader, string>(this, new Dictionary<Type, TypeReader>(), | _typeReaderMap = new TypeMap<TypeReader, string>(this, new Dictionary<Type, TypeReader>(), | ||||
| @@ -876,6 +877,24 @@ namespace Discord.Interactions | |||||
| public void AddGenericTypeReader(Type targetType, Type readerType) => | public void AddGenericTypeReader(Type targetType, Type readerType) => | ||||
| _typeReaderMap.AddGeneric(targetType, readerType); | _typeReaderMap.AddGeneric(targetType, readerType); | ||||
| /// <summary> | |||||
| /// Loads and caches an <see cref="ModalInfo"/> for the provided <see cref="IModal"/>. | |||||
| /// </summary> | |||||
| /// <typeparam name="T">Type of <see cref="IModal"/> to be loaded.</typeparam> | |||||
| /// <returns> | |||||
| /// The built <see cref="ModalInfo"/> instance. | |||||
| /// </returns> | |||||
| /// <exception cref="InvalidOperationException"></exception> | |||||
| public ModalInfo AddModalInfo<T>() where T : class, IModal | |||||
| { | |||||
| var type = typeof(T); | |||||
| if (_modalInfos.ContainsKey(type)) | |||||
| throw new InvalidOperationException($"Modal type {type.FullName} already exists."); | |||||
| return ModalUtils.GetOrAdd(type, this); | |||||
| } | |||||
| internal IAutocompleteHandler GetAutocompleteHandler(Type autocompleteHandlerType, IServiceProvider services = null) | internal IAutocompleteHandler GetAutocompleteHandler(Type autocompleteHandlerType, IServiceProvider services = null) | ||||
| { | { | ||||
| services ??= EmptyServiceProvider.Instance; | services ??= EmptyServiceProvider.Instance; | ||||
| @@ -39,7 +39,7 @@ namespace Discord.Interactions | |||||
| else if (_concretes.Any(x => x.Value.CanConvertTo(type))) | else if (_concretes.Any(x => x.Value.CanConvertTo(type))) | ||||
| return _concretes.First(x => x.Value.CanConvertTo(type)).Value; | return _concretes.First(x => x.Value.CanConvertTo(type)).Value; | ||||
| throw new ArgumentException($"No type {nameof(TConverter)} is defined for this {type.FullName}", "type"); | |||||
| throw new ArgumentException($"No type {typeof(TConverter).Name} is defined for this {type.FullName}", "type"); | |||||
| } | } | ||||
| public void AddConcrete<TTarget>(TConverter converter) => | public void AddConcrete<TTarget>(TConverter converter) => | ||||
| @@ -12,7 +12,7 @@ namespace Discord.Interactions | |||||
| { | { | ||||
| return option.Type switch | return option.Type switch | ||||
| { | { | ||||
| ComponentType.SelectMenu => Task.FromResult(TypeConverterResult.FromSuccess(Convert.ChangeType(string.Join(',', option.Values), typeof(T)))), | |||||
| ComponentType.SelectMenu => Task.FromResult(TypeConverterResult.FromSuccess(Convert.ChangeType(string.Join(",", option.Values), typeof(T)))), | |||||
| ComponentType.TextInput => Task.FromResult(TypeConverterResult.FromSuccess(Convert.ChangeType(option.Value, typeof(T)))), | ComponentType.TextInput => Task.FromResult(TypeConverterResult.FromSuccess(Convert.ChangeType(option.Value, typeof(T)))), | ||||
| _ => Task.FromResult(TypeConverterResult.FromError(InteractionCommandError.ConvertFailed, $"{option.Type} doesn't have a convertible value.")) | _ => Task.FromResult(TypeConverterResult.FromError(InteractionCommandError.ConvertFailed, $"{option.Type} doesn't have a convertible value.")) | ||||
| }; | }; | ||||