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" />
|
||||
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.");
|
||||
|
||||
var ids = this.GetComponentIds().ToList();
|
||||
if (ids.Count != ids.Distinct().Count())
|
||||
throw new InvalidOperationException("Components must have unique ids.");
|
||||
|
||||
if (_components.Any(x =>
|
||||
x is not ActionRowBuilder
|
||||
and not SectionBuilder
|
||||
|
||||
@@ -321,4 +321,43 @@ public static class ComponentContainerExtensions
|
||||
=> container.WithActionRow(new ActionRowBuilder()
|
||||
.WithComponents(components)
|
||||
.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