Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions DSharpPlus.Interactivity/InteractivityExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(c => c.Type is ComponentType.Button))
if (!message.FilterComponents<DiscordButtonComponent>().Any())
throw new ArgumentException("Provided message does not contain any button components.");


Expand Down Expand Up @@ -246,10 +246,12 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(c => c.Type is ComponentType.Button))
IReadOnlyList<DiscordButtonComponent> buttons = message.FilterComponents<DiscordButtonComponent>();

if (!buttons.Any())
throw new ArgumentException("Provided message does not contain any button components.");

var ids = message.Components.SelectMany(m => m.Components).Select(c => c.CustomId);
var ids = buttons.Select(c => c.CustomId);

var result =
await this
Expand Down Expand Up @@ -289,7 +291,7 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(c => c.Type is ComponentType.Button))
if (!message.FilterComponents<DiscordButtonComponent>().Any())
throw new ArgumentException("Provided message does not contain any button components.");

var result = await this
Expand Down Expand Up @@ -330,10 +332,10 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(c => c.Type is ComponentType.Button))
if (!message.FilterComponents<DiscordButtonComponent>().Any())
throw new ArgumentException("Provided message does not contain any button components.");

if (!message.Components.SelectMany(c => c.Components).OfType<DiscordButtonComponent>().Any(c => c.CustomId == id))
if (!message.FilterComponents<DiscordButtonComponent>().Any(c => c.CustomId == id))
throw new ArgumentException($"Provided message does not contain button with Id of '{id}'.");

var result = await this
Expand Down Expand Up @@ -367,7 +369,7 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(c => c.Type is ComponentType.Button))
if (!message.FilterComponents<DiscordButtonComponent>().Any())
throw new ArgumentException("Provided message does not contain any button components.");

var result = await this
Expand Down Expand Up @@ -403,7 +405,7 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(this.IsSelect))
if (!message.FilterComponents<DiscordComponent>().Any(this.IsSelect))
throw new ArgumentException("Provided message does not contain any select components.");


Expand Down Expand Up @@ -442,10 +444,10 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(this.IsSelect))
if (!message.FilterComponents<DiscordComponent>().Any(this.IsSelect))
throw new ArgumentException("Provided message does not contain any select components.");

if (message.Components.SelectMany(c => c.Components).Where(this.IsSelect).All(c => c.CustomId != id))
if (message.FilterComponents<DiscordComponent>().Where(this.IsSelect).All(c => c.CustomId != id))
throw new ArgumentException($"Provided message does not contain select component with Id of '{id}'.");

var result = await this
Expand Down Expand Up @@ -495,10 +497,10 @@ public async Task<InteractivityResult<ComponentInteractionCreateEventArgs>> Wait
if (!message.Components.Any())
throw new ArgumentException("Provided message does not contain any components.");

if (!message.Components.SelectMany(c => c.Components).Any(this.IsSelect))
if (!message.FilterComponents<DiscordComponent>().Any(this.IsSelect))
throw new ArgumentException("Provided message does not contain any select components.");

if (message.Components.SelectMany(c => c.Components).Where(this.IsSelect).All(c => c.CustomId != id))
if (message.FilterComponents<DiscordComponent>().Where(this.IsSelect).All(c => c.CustomId != id))
throw new ArgumentException($"Provided message does not contain button with Id of '{id}'.");

var result = await this
Expand Down
2 changes: 1 addition & 1 deletion DSharpPlus.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionPrefix>4.4.9</VersionPrefix>
<VersionPrefix>4.5.0</VersionPrefix>
<NoWarn>1591</NoWarn>
<LangVersion>9.0</LangVersion>
<Optimize>True</Optimize>
Expand Down
32 changes: 31 additions & 1 deletion DSharpPlus/Entities/Channel/Message/DiscordMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Newtonsoft.Json;

Expand Down Expand Up @@ -102,7 +103,7 @@ public DiscordChannel Channel
/// Gets the components this message was sent with.
/// </summary>
[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
public IReadOnlyCollection<DiscordActionRowComponent> Components { get; internal set; }
public IReadOnlyCollection<DiscordComponent> Components { get; internal set; }

/// <summary>
/// Gets the user or member that sent the message.
Expand Down Expand Up @@ -440,6 +441,35 @@ internal void PopulateMentions()
this._mentionedUsers = mentionedUsers.ToList();
}

/// <summary>
/// Searches the components on this message for an aggregate of all components of a certain type.
/// </summary>
public IReadOnlyList<T> FilterComponents<T>()
where T : DiscordComponent
{
List<T> components = new();

foreach (DiscordComponent component in this.Components)
{
if (component is DiscordActionRowComponent actionRowComponent)
{
foreach (DiscordComponent subComponent in actionRowComponent.Components)
{
if (subComponent is T filteredComponent)
{
components.Add(filteredComponent);
}
}
}
else if (component is T filteredComponent)
{
components.Add(filteredComponent);
}
}

return components;
}

/// <summary>
/// Edits the message.
/// </summary>
Expand Down
5 changes: 4 additions & 1 deletion DSharpPlus/Entities/Channel/Message/DiscordMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ public DiscordMessageBuilder(DiscordMessage baseMessage)
{
this.IsTTS = baseMessage.IsTTS;
this.ReplyId = baseMessage.ReferencedMessage?.Id;
this._components = baseMessage.Components.ToList(); // Calling ToList copies the list instead of referencing it

// calling tolist copies the list, which is good since we inaccurately reflect the message in case of
// unknown components
this._components = baseMessage.Components.OfType<DiscordActionRowComponent>().ToList();
this._content = baseMessage.Content;
this._embeds = baseMessage.Embeds.ToList();
this._stickers = baseMessage.Stickers.ToList();
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus/Entities/Interaction/DiscordInteractionData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ public sealed class DiscordInteractionData : SnowflakeObject
/// <summary>
/// Components on this interaction. Only applies to modal interactions.
/// </summary>
public IReadOnlyList<DiscordActionRowComponent> Components => this._components;
public IReadOnlyList<DiscordComponent> Components => this._components;

[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
internal List<DiscordActionRowComponent> _components;
internal List<DiscordComponent> _components;

/// <summary>
/// The Id of the target. Applicable for context menus.
Expand Down
2 changes: 1 addition & 1 deletion DSharpPlus/EventArgs/Interaction/ModalSubmitEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal ModalSubmitEventArgs(DiscordInteraction interaction)
var dict = new Dictionary<string, string>();

foreach (var component in interaction.Data._components)
if (component.Components.First() is TextInputComponent input)
if ((component as DiscordActionRowComponent)?.Components.First() is TextInputComponent input)
dict.Add(input.CustomId, input.Value);

this.Values = dict;
Expand Down