Skip to content

Commit

Permalink
feat: default values for select menus
Browse files Browse the repository at this point in the history
  • Loading branch information
Lulalaby committed Sep 21, 2023
1 parent cf22cfa commit fce77ee
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

using DisCatSharp.Enums;

Expand Down Expand Up @@ -41,6 +43,11 @@ public class DiscordBaseSelectComponent : DiscordComponent
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
public string Label { get; internal set; } = null;

/// <summary>
/// The default values of this select menu.
/// </summary>
[JsonProperty("default_values", NullValueHandling = NullValueHandling.Ignore)]
public List<DiscordSelectDefaultValue>? DefaultValues { get; internal set; } = null;

/// <summary>
/// Constructs a new <see cref="DiscordBaseSelectComponent"/>.
Expand All @@ -51,14 +58,29 @@ public class DiscordBaseSelectComponent : DiscordComponent
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
internal DiscordBaseSelectComponent(ComponentType type, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
/// <param name="defaultValues">The default values of this select menu. Not valid for <see cref="ComponentType.StringSelect"/>.</param>
internal DiscordBaseSelectComponent(ComponentType type, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
{
this.Type = type;
this.CustomId = customId ?? Guid.NewGuid().ToString(); ;
this.Disabled = disabled;
this.Placeholder = placeholder;
this.MinimumSelectedValues = minOptions;
this.MaximumSelectedValues = maxOptions;
if (defaultValues is not null)
{
if (defaultValues.Count() > maxOptions)
throw new OverflowException("The amount of default values cannot exceed the maximum amount of selectable options.");
if (type == ComponentType.MentionableSelect && defaultValues.Any(x => x.Type == "channel"))
throw new ArgumentException("The default values for a mentionable select must be of type user or role.", nameof(defaultValues));
if (type == ComponentType.ChannelSelect && defaultValues.Any(x => x.Type == "channel"))
throw new ArgumentException("The default values for a channel select menus must be of type channel.", nameof(defaultValues));
if (type == ComponentType.UserSelect && defaultValues.Any(x => x.Type != "user"))
throw new ArgumentException("The default values for a user select menus must be of type user.", nameof(defaultValues));
if (type == ComponentType.RoleSelect && defaultValues.Any(x => x.Type != "role"))
throw new ArgumentException("The default values for a role select menus must be of type role.", nameof(defaultValues));
}
this.DefaultValues = defaultValues?.ToList();
}

/// <summary>
Expand All @@ -71,7 +93,8 @@ internal DiscordBaseSelectComponent(ComponentType type, string placeholder, stri
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
internal DiscordBaseSelectComponent(ComponentType type, string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
/// <param name="defaultValues">The default values of this select menu. Not valid for <see cref="ComponentType.StringSelect"/>.</param>
internal DiscordBaseSelectComponent(ComponentType type, string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
{
this.Type = type;
this.Label = label;
Expand All @@ -80,6 +103,20 @@ internal DiscordBaseSelectComponent(ComponentType type, string label, string pla
this.Placeholder = placeholder;
this.MinimumSelectedValues = minOptions;
this.MaximumSelectedValues = maxOptions;
if (defaultValues is not null)
{
if (defaultValues.Count() > maxOptions)
throw new OverflowException("The amount of default values cannot exceed the maximum amount of selectable options.");
if (type == ComponentType.MentionableSelect && defaultValues.Any(x => x.Type == "channel"))
throw new ArgumentException("The default values for a mentionable select must be of type user or role.", nameof(defaultValues));
if (type == ComponentType.ChannelSelect && defaultValues.Any(x => x.Type == "channel"))
throw new ArgumentException("The default values for a channel select menus must be of type channel.", nameof(defaultValues));
if (type == ComponentType.UserSelect && defaultValues.Any(x => x.Type != "user"))
throw new ArgumentException("The default values for a user select menus must be of type user.", nameof(defaultValues));
if (type == ComponentType.RoleSelect && defaultValues.Any(x => x.Type != "role"))
throw new ArgumentException("The default values for a role select menus must be of type role.", nameof(defaultValues));
}
this.DefaultValues = defaultValues?.ToList();
}

internal DiscordBaseSelectComponent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public sealed class DiscordChannelSelectComponent : DiscordBaseSelectComponent
/// The channel types to filter by.
/// </summary>
[JsonProperty("channel_types", NullValueHandling = NullValueHandling.Ignore)]
public IReadOnlyList<ChannelType> ChannelTypes { get; internal set; } = null;
public IReadOnlyList<ChannelType>? ChannelTypes { get; internal set; } = null;

/// <summary>
/// Enables this component if it was disabled before.
Expand Down Expand Up @@ -50,8 +50,9 @@ public DiscordChannelSelectComponent Disable()
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordChannelSelectComponent(string placeholder, IEnumerable<ChannelType> channelTypes = null, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.ChannelSelect, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordChannelSelectComponent(string placeholder, IEnumerable<ChannelType> channelTypes = null, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.ChannelSelect, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{
this.ChannelTypes = channelTypes?.ToArray() ?? Array.Empty<ChannelType>();
}
Expand All @@ -66,8 +67,9 @@ public DiscordChannelSelectComponent(string placeholder, IEnumerable<ChannelType
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordChannelSelectComponent(string label, string placeholder, IEnumerable<ChannelType> channelTypes = null, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.ChannelSelect, label, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordChannelSelectComponent(string label, string placeholder, IEnumerable<ChannelType> channelTypes = null, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.ChannelSelect, label, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{
this.ChannelTypes = channelTypes?.ToArray() ?? Array.Empty<ChannelType>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.Collections.Generic;
using System.Linq;

using DisCatSharp.Enums;

namespace DisCatSharp.Entities;
Expand Down Expand Up @@ -59,8 +62,9 @@ public DiscordMentionableSelectComponent Disable()
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordMentionableSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.MentionableSelect, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordMentionableSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.MentionableSelect, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand All @@ -72,8 +76,9 @@ public DiscordMentionableSelectComponent(string placeholder, string customId = n
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordMentionableSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.MentionableSelect, label, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordMentionableSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.MentionableSelect, label, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.Collections.Generic;

using DisCatSharp.Enums;

namespace DisCatSharp.Entities;
Expand Down Expand Up @@ -59,8 +61,9 @@ public DiscordRoleSelectComponent Disable()
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordRoleSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.RoleSelect, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordRoleSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.RoleSelect, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand All @@ -72,8 +75,9 @@ public DiscordRoleSelectComponent(string placeholder, string customId = null, in
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordRoleSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.RoleSelect, label, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordRoleSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.RoleSelect, label, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using DisCatSharp.Enums;

using Newtonsoft.Json;

namespace DisCatSharp.Entities;

/// <summary>
/// A select default value for use with <see cref="ComponentType.UserSelect"/>, <see cref="ComponentType.RoleSelect"/>, <see cref="ComponentType.ChannelSelect"/> or <see cref="ComponentType.MentionableSelect"/>.
/// </summary>
public sealed class DiscordSelectDefaultValue
{
/// <summary>
/// The id of a user, role, or channel.
/// </summary>
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public ulong Id { get; internal set; }

/// <summary>
/// The type of value that <see cref="Id"/> represents.
/// </summary>
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public string Type { get; internal set; }

/// <summary>
/// Constructs a new <see cref="DiscordSelectDefaultValue"/> for an <paramref name="id"/> with corrosponding <paramref name="type"/>.
/// </summary>
/// <param name="id">The id to set.</param>
/// <param name="type">The type of the <paramref name="id"/>. Can be <c>user</c>, <c>role</c> or <c>channel</c></param>
public DiscordSelectDefaultValue(ulong id, string type)
{
this.Id = id;
this.Type = type;
}

/// <summary>
/// Constructs a new <see cref="DiscordSelectDefaultValue"/> for a role.
/// </summary>
/// <param name="role">The role to set.</param>
public DiscordSelectDefaultValue(DiscordRole role)
{
this.Id = role.Id;
this.Type = "role";
}

/// <summary>
/// Constructs a new <see cref="DiscordSelectDefaultValue"/> for a user.
/// </summary>
/// <param name="user">The user to set.</param>
public DiscordSelectDefaultValue(DiscordUser user)
{
this.Id = user.Id;
this.Type = "user";
}

/// <summary>
/// Constructs a new <see cref="DiscordSelectDefaultValue"/> for a channel.
/// </summary>
/// <param name="channel">The channel to set.</param>
public DiscordSelectDefaultValue(DiscordChannel channel)
{
this.Id = channel.Id;
this.Type = "channel";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.Collections.Generic;

using DisCatSharp.Enums;

namespace DisCatSharp.Entities;
Expand Down Expand Up @@ -57,8 +59,9 @@ public DiscordUserSelectComponent Disable()
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordUserSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.UserSelect, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordUserSelectComponent(string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.UserSelect, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand All @@ -70,8 +73,9 @@ public DiscordUserSelectComponent(string placeholder, string customId = null, in
/// <param name="minOptions">Minimum count of selectable options.</param>
/// <param name="maxOptions">Maximum count of selectable options.</param>
/// <param name="disabled">Whether this select component should be initialized as being disabled. User sees a greyed out select component that cannot be interacted with.</param>
public DiscordUserSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false)
: base(ComponentType.UserSelect, label, placeholder, customId, minOptions, maxOptions, disabled)
/// <param name="defaultValues">The default values of this select menu.</param>
public DiscordUserSelectComponent(string label, string placeholder, string customId = null, int minOptions = 1, int maxOptions = 1, bool disabled = false, IEnumerable<DiscordSelectDefaultValue>? defaultValues = null)
: base(ComponentType.UserSelect, label, placeholder, customId, minOptions, maxOptions, disabled, defaultValues)
{ }

/// <summary>
Expand Down

0 comments on commit fce77ee

Please sign in to comment.