From cc81669d838b6f160bfda113be26a8629817dbe0 Mon Sep 17 00:00:00 2001 From: Mihail Gribkov <61027276+Misha-133@users.noreply.github.com> Date: Thu, 8 May 2025 13:25:00 +0300 Subject: [PATCH] CV2 Find component by id (#3110) * Find components by id * i love when CI fails cuz of xmldoc --- .../Builders/ComponentBuilderV2.cs | 7 +++- .../Builders/ComponentContainerExtensions.cs | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentBuilderV2.cs b/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentBuilderV2.cs index 71bb127e..8689d708 100644 --- a/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentBuilderV2.cs +++ b/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentBuilderV2.cs @@ -53,9 +53,14 @@ public class ComponentBuilderV2 : IStaticComponentContainer /// 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 diff --git a/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentContainerExtensions.cs b/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentContainerExtensions.cs index 4e31e161..318367a5 100644 --- a/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentContainerExtensions.cs +++ b/src/Discord.Net.Core/Entities/Interactions/MessageComponents/Builders/ComponentContainerExtensions.cs @@ -321,4 +321,43 @@ public static class ComponentContainerExtensions => container.WithActionRow(new ActionRowBuilder() .WithComponents(components) .WithId(id)); + + /// + /// Finds the first in the + /// or any of its child s with matching id. + /// + /// + /// The with matching id, otherwise. + /// + public static IMessageComponentBuilder FindComponentById(this IComponentContainer container, int id) + => container.FindComponentById(id); + + /// + /// Finds the first ComponentT in the + /// or any of its child s with matching id. + /// + /// + /// The ComponentT with matching id, otherwise. + /// + public static ComponentT FindComponentById(this IComponentContainer container, int id) + where ComponentT : class, IMessageComponentBuilder + => container.Components + .OfType() + .FirstOrDefault(x => x.Id == id) + ?? container.Components + .OfType() + .Select(x => x.FindComponentById(id)) + .FirstOrDefault(x => x is not null); + + /// + /// Gets a IEnumerable containing ids of + /// in this and all child s. + /// + public static IEnumerable GetComponentIds(this IComponentContainer container) + => container.Components + .Where(x => x.Id is not null) + .Select(x => x.Id.Value) + .Concat(container.Components + .OfType() + .SelectMany(x => x.GetComponentIds())); }