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()));
}