CV2 Find component by id (#3110)
* Find components by id * i love when CI fails cuz of xmldoc
This commit is contained in:
@@ -53,9 +53,14 @@ public class ComponentBuilderV2 : IStaticComponentContainer
|
|||||||
/// <inheritdoc cref="IMessageComponentBuilder.Build" />
|
/// <inheritdoc cref="IMessageComponentBuilder.Build" />
|
||||||
public MessageComponent Build()
|
public MessageComponent Build()
|
||||||
{
|
{
|
||||||
Preconditions.AtLeast(Components?.Count ?? 0, 1, nameof(Components.Count), "At least 1 component must be added to this container.");
|
Preconditions.NotNull(Components, nameof(Components));
|
||||||
|
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(), MaxComponents, nameof(Components.Count), $"A message must contain {MaxComponents} components or less.");
|
||||||
|
|
||||||
|
var ids = this.GetComponentIds().ToList();
|
||||||
|
if (ids.Count != ids.Distinct().Count())
|
||||||
|
throw new InvalidOperationException("Components must have unique ids.");
|
||||||
|
|
||||||
if (_components.Any(x =>
|
if (_components.Any(x =>
|
||||||
x is not ActionRowBuilder
|
x is not ActionRowBuilder
|
||||||
and not SectionBuilder
|
and not SectionBuilder
|
||||||
|
|||||||
@@ -321,4 +321,43 @@ public static class ComponentContainerExtensions
|
|||||||
=> container.WithActionRow(new ActionRowBuilder()
|
=> container.WithActionRow(new ActionRowBuilder()
|
||||||
.WithComponents(components)
|
.WithComponents(components)
|
||||||
.WithId(id));
|
.WithId(id));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the first <see cref="IMessageComponentBuilder"/> in the <see cref="IComponentContainer"/>
|
||||||
|
/// or any of its child <see cref="IComponentContainer"/>s with matching id.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The <see cref="IMessageComponentBuilder"/> with matching id, <see langword="null"/> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public static IMessageComponentBuilder FindComponentById(this IComponentContainer container, int id)
|
||||||
|
=> container.FindComponentById<IMessageComponentBuilder>(id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the first <c>ComponentT</c> in the <see cref="IComponentContainer"/>
|
||||||
|
/// or any of its child <see cref="IComponentContainer"/>s with matching id.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The <c>ComponentT</c> with matching id, <see langword="null"/> otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public static ComponentT FindComponentById<ComponentT>(this IComponentContainer container, int id)
|
||||||
|
where ComponentT : class, IMessageComponentBuilder
|
||||||
|
=> container.Components
|
||||||
|
.OfType<ComponentT>()
|
||||||
|
.FirstOrDefault(x => x.Id == id)
|
||||||
|
?? container.Components
|
||||||
|
.OfType<IComponentContainer>()
|
||||||
|
.Select(x => x.FindComponentById<ComponentT>(id))
|
||||||
|
.FirstOrDefault(x => x is not null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="IEnumerable{T}">IEnumerable</see> containing ids of <see cref="IMessageComponentBuilder"/>
|
||||||
|
/// in this <see cref="IComponentContainer"/> and all child <see cref="IComponentContainer"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public static IEnumerable<int> GetComponentIds(this IComponentContainer container)
|
||||||
|
=> container.Components
|
||||||
|
.Where(x => x.Id is not null)
|
||||||
|
.Select(x => x.Id.Value)
|
||||||
|
.Concat(container.Components
|
||||||
|
.OfType<IComponentContainer>()
|
||||||
|
.SelectMany(x => x.GetComponentIds()));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user