[CV2] QoL & fixes (#3153)
This commit is contained in:
@@ -2,6 +2,7 @@ using Discord.Utils;
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -13,6 +14,18 @@ namespace Discord;
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponentContainer
|
public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponentContainer
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ImmutableArray<ComponentType> SupportedComponentTypes { get; } =
|
||||||
|
[
|
||||||
|
ComponentType.Button,
|
||||||
|
ComponentType.SelectMenu,
|
||||||
|
ComponentType.UserSelect,
|
||||||
|
ComponentType.RoleSelect,
|
||||||
|
ComponentType.ChannelSelect,
|
||||||
|
ComponentType.MentionableSelect,
|
||||||
|
ComponentType.TextInput
|
||||||
|
];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ComponentType Type => ComponentType.ActionRow;
|
public ComponentType Type => ComponentType.ActionRow;
|
||||||
|
|
||||||
@@ -208,6 +221,9 @@ public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponent
|
|||||||
Preconditions.AtLeast(Components.Count, 1, nameof(Components), "There must be at least 1 component in a row.");
|
Preconditions.AtLeast(Components.Count, 1, nameof(Components), "There must be at least 1 component in a row.");
|
||||||
Preconditions.AtMost(Components.Count, MaxChildCount, nameof(Components), $"Action row can only contain {MaxChildCount} child components!");
|
Preconditions.AtMost(Components.Count, MaxChildCount, nameof(Components), $"Action row can only contain {MaxChildCount} child components!");
|
||||||
|
|
||||||
|
if (Components.Any(x => !SupportedComponentTypes.Contains(x.Type)))
|
||||||
|
throw new InvalidOperationException($"This component container only supports components of types: {string.Join(", ", SupportedComponentTypes)}");
|
||||||
|
|
||||||
return new ActionRowComponent(_components.Select(x => x.Build()).ToList(), Id);
|
return new ActionRowComponent(_components.Select(x => x.Build()).ToList(), Id);
|
||||||
}
|
}
|
||||||
IMessageComponent IMessageComponentBuilder.Build() => Build();
|
IMessageComponent IMessageComponentBuilder.Build() => Build();
|
||||||
@@ -242,6 +258,8 @@ public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponent
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
||||||
|
/// <inheritdoc />
|
||||||
|
int IComponentContainer.MaxChildCount => MaxChildCount;
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{nameof(ActionRowBuilder)}: {this.ComponentCount()} child components.";
|
private string DebuggerDisplay => $"{nameof(ActionRowBuilder)}: {this.ComponentCount()} child components.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -9,10 +10,22 @@ namespace Discord;
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class ComponentBuilderV2 : IStaticComponentContainer
|
public class ComponentBuilderV2 : IStaticComponentContainer
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ImmutableArray<ComponentType> SupportedComponentTypes { get; } =
|
||||||
|
[
|
||||||
|
ComponentType.ActionRow,
|
||||||
|
ComponentType.Section,
|
||||||
|
ComponentType.MediaGallery,
|
||||||
|
ComponentType.Separator,
|
||||||
|
ComponentType.Container,
|
||||||
|
ComponentType.File,
|
||||||
|
ComponentType.TextDisplay
|
||||||
|
];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum number of components that can be added to a message.
|
/// Gets the maximum number of components that can be added to a message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int MaxComponents = 40;
|
public const int MaxChildCount = 40;
|
||||||
|
|
||||||
private List<IMessageComponentBuilder> _components = new();
|
private List<IMessageComponentBuilder> _components = new();
|
||||||
|
|
||||||
@@ -74,21 +87,14 @@ public class ComponentBuilderV2 : IStaticComponentContainer
|
|||||||
{
|
{
|
||||||
Preconditions.NotNull(Components, nameof(Components));
|
Preconditions.NotNull(Components, nameof(Components));
|
||||||
Preconditions.AtLeast(Components.Count, 1, nameof(Components.Count), "At least 1 component must be added to this container.");
|
Preconditions.AtLeast(Components.Count, 1, nameof(Components.Count), "At least 1 component must be added to this container.");
|
||||||
Preconditions.AtMost(this.ComponentCount(), MaxComponents, nameof(Components.Count), $"A message must contain {MaxComponents} components or less.");
|
Preconditions.AtMost(this.ComponentCount(), MaxChildCount, nameof(Components.Count), $"A message must contain {MaxChildCount} components or less.");
|
||||||
|
|
||||||
var ids = this.GetComponentIds().ToList();
|
var ids = this.GetComponentIds().ToList();
|
||||||
if (ids.Count != ids.Distinct().Count())
|
if (ids.Count != ids.Distinct().Count())
|
||||||
throw new InvalidOperationException("Components must have unique ids.");
|
throw new InvalidOperationException("Components must have unique ids.");
|
||||||
|
|
||||||
if (_components.Any(x =>
|
if (Components.Any(x => !SupportedComponentTypes.Contains(x.Type)))
|
||||||
x is not ActionRowBuilder
|
throw new InvalidOperationException($"This component container only supports components of types: {string.Join(", ", SupportedComponentTypes)}");
|
||||||
and not SectionBuilder
|
|
||||||
and not TextDisplayBuilder
|
|
||||||
and not MediaGalleryBuilder
|
|
||||||
and not FileComponentBuilder
|
|
||||||
and not SeparatorBuilder
|
|
||||||
and not ContainerBuilder))
|
|
||||||
throw new InvalidOperationException($"Only the following components can be at the top level: {nameof(ActionRowBuilder)}, {nameof(TextDisplayBuilder)}, {nameof(SectionBuilder)}, {nameof(MediaGalleryBuilder)}, {nameof(SeparatorBuilder)}, or {nameof(FileComponentBuilder)} components.");
|
|
||||||
|
|
||||||
return new MessageComponent(Components.Select(x => x.Build()).ToList());
|
return new MessageComponent(Components.Select(x => x.Build()).ToList());
|
||||||
}
|
}
|
||||||
@@ -101,6 +107,8 @@ public class ComponentBuilderV2 : IStaticComponentContainer
|
|||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IComponentContainer.MaxChildCount => MaxChildCount;
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{nameof(ComponentBuilderV2)}: {this.ComponentCount()} child components.";
|
private string DebuggerDisplay => $"{nameof(ComponentBuilderV2)}: {this.ComponentCount()} child components.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -52,6 +53,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithContent(content)
|
.WithContent(content)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="TextDisplayBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithTextDisplay<BuilderT>(this BuilderT container,
|
||||||
|
Action<TextDisplayBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new TextDisplayBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithTextDisplay(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="SectionBuilder"/> to the container.
|
/// Adds a <see cref="SectionBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -65,6 +81,21 @@ public static class ComponentContainerExtensions
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="SectionBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithSection<BuilderT>(this BuilderT container,
|
||||||
|
Action<SectionBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new SectionBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithSection(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="SectionBuilder"/> to the container.
|
/// Adds a <see cref="SectionBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -122,6 +153,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithItems(urls.Select(x => new MediaGalleryItemProperties(new UnfurledMediaItemProperties(x))))
|
.WithItems(urls.Select(x => new MediaGalleryItemProperties(new UnfurledMediaItemProperties(x))))
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="MediaGalleryBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithMediaGallery<BuilderT>(this BuilderT container,
|
||||||
|
Action<MediaGalleryBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new MediaGalleryBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithMediaGallery(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="SeparatorBuilder"/> to the container.
|
/// Adds a <see cref="SeparatorBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -151,6 +197,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithIsDivider(isDivider)
|
.WithIsDivider(isDivider)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="SeparatorBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithSeparator<BuilderT>(this BuilderT container,
|
||||||
|
Action<SeparatorBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new SeparatorBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithSeparator(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="FileComponentBuilder"/> to the container.
|
/// Adds a <see cref="FileComponentBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -180,6 +241,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithIsSpoiler(isSpoiler)
|
.WithIsSpoiler(isSpoiler)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="FileComponentBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithFile<BuilderT>(this BuilderT container,
|
||||||
|
Action<FileComponentBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new FileComponentBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithFile(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="ContainerBuilder"/> to the container.
|
/// Adds a <see cref="ContainerBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -223,6 +299,21 @@ public static class ComponentContainerExtensions
|
|||||||
=> container.WithContainer(new ContainerBuilder()
|
=> container.WithContainer(new ContainerBuilder()
|
||||||
.WithComponents(components));
|
.WithComponents(components));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="ContainerBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithContainer<BuilderT>(this BuilderT container,
|
||||||
|
Action<ContainerBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new ContainerBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithContainer(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="ButtonBuilder"/> to the container.
|
/// Adds a <see cref="ButtonBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -262,6 +353,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithSkuId(skuId)
|
.WithSkuId(skuId)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="ButtonBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithButton<BuilderT>(this BuilderT container,
|
||||||
|
Action<ButtonBuilder> options)
|
||||||
|
where BuilderT : class, IInteractableComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new ButtonBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithButton(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="SelectMenuBuilder"/> to the container.
|
/// Adds a <see cref="SelectMenuBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -306,6 +412,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithDefaultValues(defaultValues)
|
.WithDefaultValues(defaultValues)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="ButtonBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithSelectMenu<BuilderT>(this BuilderT container,
|
||||||
|
Action<SelectMenuBuilder> options)
|
||||||
|
where BuilderT : class, IInteractableComponentContainer
|
||||||
|
{
|
||||||
|
var comp = new SelectMenuBuilder();
|
||||||
|
options(comp);
|
||||||
|
return container.WithSelectMenu(comp);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="ActionRowBuilder"/> to the container.
|
/// Adds a <see cref="ActionRowBuilder"/> to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -333,6 +454,21 @@ public static class ComponentContainerExtensions
|
|||||||
.WithComponents(components)
|
.WithComponents(components)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a <see cref="SectionBuilder"/> to the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current container.
|
||||||
|
/// </returns>
|
||||||
|
public static BuilderT WithActionRow<BuilderT>(this BuilderT container,
|
||||||
|
Action<ActionRowBuilder> options)
|
||||||
|
where BuilderT : class, IStaticComponentContainer
|
||||||
|
{
|
||||||
|
var cont = new ActionRowBuilder();
|
||||||
|
options(cont);
|
||||||
|
return container.WithActionRow(cont);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the first <see cref="IMessageComponentBuilder"/> in the <see cref="IComponentContainer"/>
|
/// Finds the first <see cref="IMessageComponentBuilder"/> in the <see cref="IComponentContainer"/>
|
||||||
/// or any of its child <see cref="IComponentContainer"/>s with matching id.
|
/// or any of its child <see cref="IComponentContainer"/>s with matching id.
|
||||||
|
|||||||
@@ -9,9 +9,25 @@ namespace Discord;
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContainer
|
public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContainer
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ImmutableArray<ComponentType> SupportedComponentTypes { get; } =
|
||||||
|
[
|
||||||
|
ComponentType.ActionRow,
|
||||||
|
ComponentType.Section,
|
||||||
|
ComponentType.Button,
|
||||||
|
ComponentType.MediaGallery,
|
||||||
|
ComponentType.Separator,
|
||||||
|
ComponentType.File,
|
||||||
|
ComponentType.SelectMenu,
|
||||||
|
ComponentType.TextDisplay
|
||||||
|
];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ComponentType Type => ComponentType.Container;
|
public ComponentType Type => ComponentType.Container;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IComponentContainer.MaxChildCount"/>
|
||||||
|
public const int MaxChildCount = 39;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -107,14 +123,11 @@ public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContai
|
|||||||
/// <inheritdoc cref="IMessageComponentBuilder.Build"/>
|
/// <inheritdoc cref="IMessageComponentBuilder.Build"/>
|
||||||
public ContainerComponent Build()
|
public ContainerComponent Build()
|
||||||
{
|
{
|
||||||
if (_components.Any(x => x
|
Preconditions.NotNull(Components, nameof(Components));
|
||||||
is not ActionRowBuilder
|
Preconditions.AtLeast(Components.Count, 1, nameof(Components.Count), "At least 1 component must be added to this container.");
|
||||||
and not TextDisplayBuilder
|
|
||||||
and not SectionBuilder
|
if (Components.Any(x => !SupportedComponentTypes.Contains(x.Type)))
|
||||||
and not MediaGalleryBuilder
|
throw new InvalidOperationException($"This component container only supports components of types: {string.Join(", ", SupportedComponentTypes)}");
|
||||||
and not SeparatorBuilder
|
|
||||||
and not FileComponentBuilder))
|
|
||||||
throw new InvalidOperationException($"A container can only contain {nameof(ActionRowBuilder)}, {nameof(TextDisplayBuilder)}, {nameof(SectionBuilder)}, {nameof(MediaGalleryBuilder)}, {nameof(SeparatorBuilder)}, or {nameof(FileComponentBuilder)} components.");
|
|
||||||
|
|
||||||
return new(Components.ConvertAll(x => x.Build()).ToImmutableArray(), AccentColor, IsSpoiler, Id);
|
return new(Components.ConvertAll(x => x.Build()).ToImmutableArray(), AccentColor, IsSpoiler, Id);
|
||||||
}
|
}
|
||||||
@@ -127,6 +140,8 @@ public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContai
|
|||||||
IComponentContainer IComponentContainer.AddComponents(params IMessageComponentBuilder[] components) => AddComponents(components);
|
IComponentContainer IComponentContainer.AddComponents(params IMessageComponentBuilder[] components) => AddComponents(components);
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components);
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IComponentContainer.MaxChildCount => MaxChildCount;
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{nameof(ContainerBuilder)}: {this.ComponentCount()} child components.";
|
private string DebuggerDisplay => $"{nameof(ContainerBuilder)}: {this.ComponentCount()} child components.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Discord;
|
namespace Discord;
|
||||||
|
|
||||||
@@ -7,6 +8,16 @@ namespace Discord;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IComponentContainer
|
public interface IComponentContainer
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the types of child components supported by this container.
|
||||||
|
/// </summary>
|
||||||
|
ImmutableArray<ComponentType> SupportedComponentTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum number of components allowed in the container.
|
||||||
|
/// </summary>
|
||||||
|
int MaxChildCount { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the components in the container.
|
/// Gets the components in the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -10,10 +10,14 @@ namespace Discord;
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class SectionBuilder : IMessageComponentBuilder, IStaticComponentContainer
|
public class SectionBuilder : IMessageComponentBuilder, IStaticComponentContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Gets the maximum number of components allowed in this container.
|
public ImmutableArray<ComponentType> SupportedComponentTypes { get; } =
|
||||||
/// </summary>
|
[
|
||||||
public const int MaxComponents = 3;
|
ComponentType.TextDisplay
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IComponentContainer.MaxChildCount"/>
|
||||||
|
public const int MaxChildCount = 3;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ComponentType Type => ComponentType.Section;
|
public ComponentType Type => ComponentType.Section;
|
||||||
@@ -108,17 +112,17 @@ public class SectionBuilder : IMessageComponentBuilder, IStaticComponentContaine
|
|||||||
/// <inheritdoc cref="IMessageComponentBuilder.Build"/>
|
/// <inheritdoc cref="IMessageComponentBuilder.Build"/>
|
||||||
public SectionComponent Build()
|
public SectionComponent Build()
|
||||||
{
|
{
|
||||||
if (_components.Count is 0 or > MaxComponents)
|
if (_components.Count is 0 or > MaxChildCount)
|
||||||
throw new InvalidOperationException($"Section component can only contain {MaxComponents} child components!");
|
throw new InvalidOperationException($"Section component can only contain {MaxChildCount} child components.");
|
||||||
|
|
||||||
if (_components.Any(x => x is not TextDisplayBuilder))
|
if (Components.Any(x => !SupportedComponentTypes.Contains(x.Type)))
|
||||||
throw new InvalidOperationException($"Section component can only contain {nameof(TextDisplayBuilder)}!");
|
throw new InvalidOperationException($"This component container only supports components of types: {string.Join(", ", SupportedComponentTypes)}");
|
||||||
|
|
||||||
if (Accessory is null)
|
if (Accessory is null)
|
||||||
throw new ArgumentNullException(nameof(Accessory), "A section must have an accessory");
|
throw new ArgumentNullException(nameof(Accessory), "A section must have an accessory.");
|
||||||
|
|
||||||
if (Accessory is not ButtonBuilder and not ThumbnailBuilder)
|
if (Accessory is not ButtonBuilder and not ThumbnailBuilder)
|
||||||
throw new InvalidOperationException($"Accessory component can only be {nameof(ButtonBuilder)} or {nameof(ThumbnailBuilder)}!");
|
throw new InvalidOperationException($"Accessory component can only be {nameof(ButtonBuilder)} or {nameof(ThumbnailBuilder)}.");
|
||||||
|
|
||||||
return new(Id, Components.Select(x => x.Build()).ToImmutableArray(), Accessory?.Build());
|
return new(Id, Components.Select(x => x.Build()).ToImmutableArray(), Accessory?.Build());
|
||||||
}
|
}
|
||||||
@@ -131,6 +135,7 @@ public class SectionBuilder : IMessageComponentBuilder, IStaticComponentContaine
|
|||||||
IComponentContainer IComponentContainer.AddComponents(params IMessageComponentBuilder[] components) => AddComponents(components);
|
IComponentContainer IComponentContainer.AddComponents(params IMessageComponentBuilder[] components) => AddComponents(components);
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components.ToList());
|
IComponentContainer IComponentContainer.WithComponents(IEnumerable<IMessageComponentBuilder> components) => WithComponents(components.ToList());
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IComponentContainer.MaxChildCount => MaxChildCount;
|
||||||
private string DebuggerDisplay => $"{nameof(SectionBuilder)}: {this.ComponentCount()} child components.";
|
private string DebuggerDisplay => $"{nameof(SectionBuilder)}: {this.ComponentCount()} child components.";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user