Browse Source

Support Min and Max values on ApplicationCommandOptions (#273)

* Support Min and Max values on ApplicationCommandOptions

* Support decimal min/max values

* Docs imrpovments + use ToNullable
pull/1923/head
CottageDwellingCat GitHub 3 years ago
parent
commit
8e5e360103
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 12 deletions
  1. +11
    -0
      src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs
  2. +10
    -0
      src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs
  3. +55
    -6
      src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs
  4. +10
    -0
      src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs
  5. +13
    -0
      src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs
  6. +12
    -6
      src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs

+ 11
- 0
src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs View File

@@ -66,6 +66,17 @@ namespace Discord
/// Gets or sets whether or not this option supports autocomplete. /// Gets or sets whether or not this option supports autocomplete.
/// </summary> /// </summary>
public bool Autocomplete { get; set; } public bool Autocomplete { get; set; }

/// <summary>
/// Gets or sets the smallest number value the user can input.
/// </summary>
public double? MinValue { get; set; }

/// <summary>
/// Gets or sets the largest number value the user can input.
/// </summary>
public double? MaxValue { get; set; }

/// <summary> /// <summary>
/// Gets or sets the choices for string and int types for the user to pick from. /// Gets or sets the choices for string and int types for the user to pick from.
/// </summary> /// </summary>


+ 10
- 0
src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs View File

@@ -32,6 +32,16 @@ namespace Discord
/// </summary> /// </summary>
bool? IsRequired { get; } bool? IsRequired { get; }


/// <summary>
/// The smallest number value the user can input.
/// </summary>
double? MinValue { get; }

/// <summary>
/// The largest number value the user can input.
/// </summary>
double? MaxValue { get; }

/// <summary> /// <summary>
/// Choices for string and int types for the user to pick from. /// Choices for string and int types for the user to pick from.
/// </summary> /// </summary>


+ 55
- 6
src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs View File

@@ -155,10 +155,12 @@ namespace Discord
/// <param name="options">The options of the option to add.</param> /// <param name="options">The options of the option to add.</param>
/// <param name="channelTypes">The allowed channel types for this option.</param> /// <param name="channelTypes">The allowed channel types for this option.</param>
/// <param name="choices">The choices of this option.</param> /// <param name="choices">The choices of this option.</param>
/// <param name="minValue">The smallest number value the user can input.</param>
/// <param name="maxValue">The largest number value the user can input.</param>
/// <returns>The current builder.</returns> /// <returns>The current builder.</returns>
public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type, public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type,
string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, List<SlashCommandOptionBuilder> options = null,
List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
{ {
// Make sure the name matches the requirements from discord // Make sure the name matches the requirements from discord
Preconditions.NotNullOrEmpty(name, nameof(name)); Preconditions.NotNullOrEmpty(name, nameof(name));
@@ -189,7 +191,9 @@ namespace Discord
Type = type, Type = type,
Autocomplete = isAutocomplete, Autocomplete = isAutocomplete,
Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(), Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(),
ChannelTypes = channelTypes
ChannelTypes = channelTypes,
MinValue = minValue,
MaxValue = maxValue,
}; };


return AddOption(option); return AddOption(option);
@@ -321,6 +325,16 @@ namespace Discord
/// </summary> /// </summary>
public bool Autocomplete { get; set; } public bool Autocomplete { get; set; }


/// <summary>
/// Gets or sets the smallest number value the user can input.
/// </summary>
public double? MinValue { get; set; }

/// <summary>
/// Gets or sets the largest number value the user can input.
/// </summary>
public double? MaxValue { get; set; }

/// <summary> /// <summary>
/// Gets or sets the choices for string and int types for the user to pick from. /// Gets or sets the choices for string and int types for the user to pick from.
/// </summary> /// </summary>
@@ -343,6 +357,7 @@ namespace Discord
public ApplicationCommandOptionProperties Build() public ApplicationCommandOptionProperties Build()
{ {
bool isSubType = Type == ApplicationCommandOptionType.SubCommandGroup; bool isSubType = Type == ApplicationCommandOptionType.SubCommandGroup;
bool isIntType = Type == ApplicationCommandOptionType.Integer;


if (isSubType && (Options == null || !Options.Any())) if (isSubType && (Options == null || !Options.Any()))
throw new InvalidOperationException("SubCommands/SubCommandGroups must have at least one option"); throw new InvalidOperationException("SubCommands/SubCommandGroups must have at least one option");
@@ -350,6 +365,12 @@ namespace Discord
if (!isSubType && Options != null && Options.Any() && Type != ApplicationCommandOptionType.SubCommand) if (!isSubType && Options != null && Options.Any() && Type != ApplicationCommandOptionType.SubCommand)
throw new InvalidOperationException($"Cannot have options on {Type} type"); throw new InvalidOperationException($"Cannot have options on {Type} type");


if (isIntType && MinValue != null && MinValue % 1 != 0)
throw new InvalidOperationException("MinValue cannot have decimals on Integer command options.");

if (isIntType && MaxValue != null && MaxValue % 1 != 0)
throw new InvalidOperationException("MaxValue cannot have decimals on Integer command options.");

return new ApplicationCommandOptionProperties return new ApplicationCommandOptionProperties
{ {
Name = Name, Name = Name,
@@ -360,7 +381,9 @@ namespace Discord
Options = Options?.Count > 0 ? Options.Select(x => x.Build()).ToList() : new List<ApplicationCommandOptionProperties>(), Options = Options?.Count > 0 ? Options.Select(x => x.Build()).ToList() : new List<ApplicationCommandOptionProperties>(),
Choices = Choices, Choices = Choices,
Autocomplete = Autocomplete, Autocomplete = Autocomplete,
ChannelTypes = ChannelTypes
ChannelTypes = ChannelTypes,
MinValue = MinValue,
MaxValue = MaxValue
}; };
} }


@@ -376,10 +399,12 @@ namespace Discord
/// <param name="options">The options of the option to add.</param> /// <param name="options">The options of the option to add.</param>
/// <param name="channelTypes">The allowed channel types for this option.</param> /// <param name="channelTypes">The allowed channel types for this option.</param>
/// <param name="choices">The choices of this option.</param> /// <param name="choices">The choices of this option.</param>
/// <param name="minValue">The smallest number value the user can input.</param>
/// <param name="maxValue">The largest number value the user can input.</param>
/// <returns>The current builder.</returns> /// <returns>The current builder.</returns>
public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOptionType type, public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOptionType type,
string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, List<SlashCommandOptionBuilder> options = null,
List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null,
List<SlashCommandOptionBuilder> options = null, List<ChannelType> channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices)
{ {
// Make sure the name matches the requirements from discord // Make sure the name matches the requirements from discord
Preconditions.NotNullOrEmpty(name, nameof(name)); Preconditions.NotNullOrEmpty(name, nameof(name));
@@ -407,6 +432,8 @@ namespace Discord
Required = required, Required = required,
Default = isDefault, Default = isDefault,
Autocomplete = isAutocomplete, Autocomplete = isAutocomplete,
MinValue = minValue,
MaxValue = maxValue,
Options = options, Options = options,
Type = type, Type = type,
Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(), Choices = (choices ?? Array.Empty<ApplicationCommandOptionChoiceProperties>()).ToList(),
@@ -561,6 +588,28 @@ namespace Discord
return this; return this;
} }


/// <summary>
/// Sets the current builders min value field.
/// </summary>
/// <param name="value">The value to set.</param>
/// <returns>The current builder.</returns>
public SlashCommandOptionBuilder WithMinValue(double value)
{
MinValue = value;
return this;
}
/// <summary>
/// Sets the current builders max value field.
/// </summary>
/// <param name="value">The value to set.</param>
/// <returns>The current builder.</returns>
public SlashCommandOptionBuilder WithMaxValue(double value)
{
MaxValue = value;
return this;
}

/// <summary> /// <summary>
/// Sets the current type of this builder. /// Sets the current type of this builder.
/// </summary> /// </summary>


+ 10
- 0
src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs View File

@@ -29,6 +29,12 @@ namespace Discord.API
[JsonProperty("autocomplete")] [JsonProperty("autocomplete")]
public Optional<bool> Autocomplete { get; set; } public Optional<bool> Autocomplete { get; set; }


[JsonProperty("min_value")]
public Optional<double> MinValue { get; set; }

[JsonProperty("max_value")]
public Optional<double> MaxValue { get; set; }

[JsonProperty("channel_types")] [JsonProperty("channel_types")]
public Optional<ChannelType[]> ChannelTypes { get; set; } public Optional<ChannelType[]> ChannelTypes { get; set; }


@@ -48,6 +54,8 @@ namespace Discord.API


Required = cmd.IsRequired ?? Optional<bool>.Unspecified; Required = cmd.IsRequired ?? Optional<bool>.Unspecified;
Default = cmd.IsDefault ?? Optional<bool>.Unspecified; Default = cmd.IsDefault ?? Optional<bool>.Unspecified;
MinValue = cmd.MinValue ?? Optional<double>.Unspecified;
MaxValue = cmd.MaxValue ?? Optional<double>.Unspecified;


Name = cmd.Name; Name = cmd.Name;
Type = cmd.Type; Type = cmd.Type;
@@ -66,6 +74,8 @@ namespace Discord.API
Required = option.Required ?? Optional<bool>.Unspecified; Required = option.Required ?? Optional<bool>.Unspecified;


Default = option.Default ?? Optional<bool>.Unspecified; Default = option.Default ?? Optional<bool>.Unspecified;
MinValue = option.MinValue ?? Optional<double>.Unspecified;
MaxValue = option.MaxValue ?? Optional<double>.Unspecified;


ChannelTypes = option.ChannelTypes?.ToArray() ?? Optional<ChannelType[]>.Unspecified; ChannelTypes = option.ChannelTypes?.ToArray() ?? Optional<ChannelType[]>.Unspecified;




+ 13
- 0
src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs View File

@@ -26,6 +26,12 @@ namespace Discord.Rest
/// <inheritdoc/> /// <inheritdoc/>
public bool? IsRequired { get; private set; } public bool? IsRequired { get; private set; }


/// <inheritdoc/>
public double? MinValue { get; private set; }

/// <inheritdoc/>
public double? MaxValue { get; private set; }

/// <summary> /// <summary>
/// A collection of <see cref="RestApplicationCommandChoice"/>'s for this command. /// A collection of <see cref="RestApplicationCommandChoice"/>'s for this command.
/// </summary> /// </summary>
@@ -41,6 +47,7 @@ namespace Discord.Rest
/// </summary> /// </summary>
public IReadOnlyCollection<ChannelType> ChannelTypes { get; private set; } public IReadOnlyCollection<ChannelType> ChannelTypes { get; private set; }



internal RestApplicationCommandOption() { } internal RestApplicationCommandOption() { }


internal static RestApplicationCommandOption Create(Model model) internal static RestApplicationCommandOption Create(Model model)
@@ -62,6 +69,12 @@ namespace Discord.Rest
if (model.Required.IsSpecified) if (model.Required.IsSpecified)
IsRequired = model.Required.Value; IsRequired = model.Required.Value;


if (model.MinValue.IsSpecified)
MinValue = model.MinValue.Value;

if (model.MaxValue.IsSpecified)
MaxValue = model.MaxValue.Value;

Options = model.Options.IsSpecified Options = model.Options.IsSpecified
? model.Options.Value.Select(Create).ToImmutableArray() ? model.Options.Value.Select(Create).ToImmutableArray()
: ImmutableArray.Create<RestApplicationCommandOption>(); : ImmutableArray.Create<RestApplicationCommandOption>();


+ 12
- 6
src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs View File

@@ -25,6 +25,12 @@ namespace Discord.WebSocket
/// <inheritdoc/> /// <inheritdoc/>
public bool? IsRequired { get; private set; } public bool? IsRequired { get; private set; }


/// <inheritdoc/>
public double? MinValue { get; private set; }

/// <inheritdoc/>
public double? MaxValue { get; private set; }

/// <summary> /// <summary>
/// Choices for string and int types for the user to pick from. /// Choices for string and int types for the user to pick from.
/// </summary> /// </summary>
@@ -54,13 +60,13 @@ namespace Discord.WebSocket
Type = model.Type; Type = model.Type;
Description = model.Description; Description = model.Description;


IsDefault = model.Default.IsSpecified
? model.Default.Value
: null;
IsDefault = model.Default.ToNullable();

IsRequired = model.Required.ToNullable();

MinValue = model.MinValue.ToNullable();


IsRequired = model.Required.IsSpecified
? model.Required.Value
: null;
MaxValue = model.MaxValue.ToNullable();


Choices = model.Choices.IsSpecified Choices = model.Choices.IsSpecified
? model.Choices.Value.Select(SocketApplicationCommandChoice.Create).ToImmutableArray() ? model.Choices.Value.Select(SocketApplicationCommandChoice.Create).ToImmutableArray()


Loading…
Cancel
Save