Add component => builder converters (#3119)

This commit is contained in:
Mihail Gribkov
2025-05-09 13:13:25 +03:00
committed by GitHub
parent 4760dc5efd
commit b72938028f
10 changed files with 234 additions and 6 deletions

View File

@@ -10,8 +10,10 @@ namespace Discord;
/// </summary> /// </summary>
public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponentContainer public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponentContainer
{ {
/// <inheritdoc />
public ComponentType Type => ComponentType.ActionRow; public ComponentType Type => ComponentType.ActionRow;
/// <inheritdoc />
public int? Id { get; set; } public int? Id { get; set; }
/// <summary> /// <summary>
@@ -41,7 +43,24 @@ public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponent
} }
} }
/// <summary>
/// Initializes a new <see cref="ActionRowBuilder"/>.
/// </summary>
public ActionRowBuilder(params IMessageComponentBuilder[] components)
{
Components = components?.ToList();
}
/// <summary>
/// Initializes a new <see cref="ActionRowBuilder"/> from existing component.
/// </summary>
public ActionRowBuilder(ActionRowComponent actionRow)
{
Components = actionRow.Components.Select(x => x.ToBuilder()).ToList();
Id = actionRow.Id;
}
/// <inheritdoc cref="IComponentContainer.AddComponents"/>
public ActionRowBuilder AddComponents(params IMessageComponentBuilder[] components) public ActionRowBuilder AddComponents(params IMessageComponentBuilder[] components)
{ {
foreach (var component in components) foreach (var component in components)
@@ -49,6 +68,7 @@ public class ActionRowBuilder : IMessageComponentBuilder, IInteractableComponent
return this; return this;
} }
/// <inheritdoc cref="IComponentContainer.WithComponents"/>
public ActionRowBuilder WithComponents(IEnumerable<IMessageComponentBuilder> components) public ActionRowBuilder WithComponents(IEnumerable<IMessageComponentBuilder> components)
{ {
Components = components.ToList(); Components = components.ToList();

View File

@@ -1,3 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Discord; namespace Discord;
public static class ComponentBuilderExtensions public static class ComponentBuilderExtensions
@@ -14,4 +18,102 @@ public static class ComponentBuilderExtensions
builder.Id = id; builder.Id = id;
return builder; return builder;
} }
/// <summary>
/// Converts a <see cref="IMessageComponent"/> to a builder.
/// </summary>
/// <exception cref="ArgumentException">Unknown component type</exception>
public static IMessageComponentBuilder ToBuilder(this IMessageComponent component)
=> component switch
{
ActionRowComponent actionRow => actionRow.ToBuilder(),
ButtonComponent button => button.ToBuilder(),
SelectMenuComponent select => select.ToBuilder(),
SectionComponent section => section.ToBuilder(),
TextDisplayComponent textDisplay => textDisplay.ToBuilder(),
ThumbnailComponent thumbnail => thumbnail.ToBuilder(),
MediaGalleryComponent mediaGallery => mediaGallery.ToBuilder(),
FileComponent file => file.ToBuilder(),
SeparatorComponent separator => separator.ToBuilder(),
ContainerComponent container => container.ToBuilder(),
_ => throw new ArgumentException("Unknown component type")
};
/// <summary>
/// Converts a <see cref="FileComponent"/> to a <see cref="FileComponentBuilder"/>.
/// </summary>
public static FileComponentBuilder ToBuilder(this FileComponent file)
=> new(file);
/// <summary>
/// Converts a <see cref="SeparatorComponent"/> to a <see cref="SeparatorBuilder"/>.
/// </summary>
public static SeparatorBuilder ToBuilder(this SeparatorComponent separator)
=> new(separator);
/// <summary>
/// Converts a <see cref="MediaGalleryComponent"/> to a <see cref="MediaGalleryBuilder"/>.
/// </summary>
public static MediaGalleryBuilder ToBuilder(this MediaGalleryComponent mediaGallery)
=> new(mediaGallery);
/// <summary>
/// Converts a <see cref="ButtonComponent"/> to a <see cref="ButtonBuilder"/>.
/// </summary>
public static ButtonBuilder ToBuilder(this ButtonComponent button)
=> new(button);
/// <summary>
/// Converts a <see cref="SelectMenuComponent"/> to a <see cref="SelectMenuBuilder"/>.
/// </summary>
public static SelectMenuBuilder ToBuilder(this SelectMenuComponent select)
=> new(select);
/// <summary>
/// Converts a <see cref="ActionRowComponent"/> to a <see cref="ActionRowBuilder"/>.
/// </summary>
public static ActionRowBuilder ToBuilder(this ActionRowComponent actionRow)
=> new(actionRow);
/// <summary>
/// Converts a <see cref="ContainerComponent"/> to a <see cref="ContainerBuilder"/>.
/// </summary>
public static ContainerBuilder ToBuilder(this ContainerComponent container)
=> new(container);
/// <summary>
/// Converts a <see cref="SectionComponent"/> to a <see cref="SectionBuilder"/>.
/// </summary>
public static SectionBuilder ToBuilder(this SectionComponent section)
=> new(section);
/// <summary>
/// Converts a <see cref="ThumbnailComponent"/> to a <see cref="ThumbnailBuilder"/>.
/// </summary>
public static ThumbnailBuilder ToBuilder(this ThumbnailComponent thumbnail)
=> new(thumbnail);
/// <summary>
/// Converts a <see cref="TextDisplayComponent"/> to a <see cref="TextDisplayBuilder"/>.
/// </summary>
public static TextDisplayBuilder ToBuilder(this TextDisplayComponent textDisplay)
=> new (textDisplay);
/// <summary>
/// Converts a <see cref="MediaGalleryItem"/> to a <see cref="MediaGalleryItemProperties"/>.
/// </summary>
public static MediaGalleryItemProperties ToProperties(this MediaGalleryItem item)
=> new(item.Media.ToProperties(), item.Description, item.IsSpoiler);
/// <summary>
/// Converts a <see cref="UnfurledMediaItem"/> to a <see cref="UnfurledMediaItemProperties"/>.
/// </summary>
public static UnfurledMediaItemProperties ToProperties(this UnfurledMediaItem item)
=> new(item.Url);
/// <summary>
/// Converts a collection of <see cref="IMessageComponent"/> to a <see cref="ComponentBuilderV2"/>.
/// </summary>
public static ComponentBuilderV2 ToBuilder(this IEnumerable<IMessageComponent> components)
=> new(components);
} }

View File

@@ -26,7 +26,18 @@ public class ComponentBuilderV2 : IStaticComponentContainer
/// <summary> /// <summary>
/// Initializes a new instance of <see cref="ComponentBuilderV2"/>. /// Initializes a new instance of <see cref="ComponentBuilderV2"/>.
/// </summary> /// </summary>
public ComponentBuilderV2() { } public ComponentBuilderV2(params IEnumerable<IMessageComponentBuilder> components)
{
Components = components?.ToList();
}
/// <summary>
/// Initializes a new instance of <see cref="ComponentBuilderV2"/> from existing components.
/// </summary>
public ComponentBuilderV2(IEnumerable<IMessageComponent> components)
{
Components = components?.Select(x => x.ToBuilder()).ToList();
}
/// <inheritdoc cref="IComponentContainer.AddComponent"/> /// <inheritdoc cref="IComponentContainer.AddComponent"/>
public ComponentBuilderV2 AddComponent(IMessageComponentBuilder component) public ComponentBuilderV2 AddComponent(IMessageComponentBuilder component)

View File

@@ -32,6 +32,25 @@ public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContai
/// </summary> /// </summary>
public bool? IsSpoiler { get; set; } public bool? IsSpoiler { get; set; }
/// <summary>
/// Initializes a new <see cref="ContainerBuilder"/>.
/// </summary>
public ContainerBuilder(params IEnumerable<IMessageComponentBuilder> components)
{
Components = components?.ToList();
}
/// <summary>
/// Initializes a new <see cref="ContainerBuilder"/> from existing component.
/// </summary>
public ContainerBuilder(ContainerComponent container)
{
Components = container.Components.Select(x => x.ToBuilder()).ToList();
AccentColor = container.AccentColor;
IsSpoiler = container.IsSpoiler;
Id = container.Id;
}
/// <summary> /// <summary>
/// Sets the accent color of this container. /// Sets the accent color of this container.
/// </summary> /// </summary>
@@ -50,7 +69,7 @@ public class ContainerBuilder : IMessageComponentBuilder, IStaticComponentContai
/// <returns> /// <returns>
/// The current builder. /// The current builder.
/// </returns> /// </returns>
public ContainerBuilder WithSpoiler(bool isSpoiler) public ContainerBuilder WithSpoiler(bool? isSpoiler)
{ {
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
return this; return this;

View File

@@ -26,7 +26,7 @@ public class FileComponentBuilder : IMessageComponentBuilder
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FileComponentBuilder"/>. /// Initializes a new instance of the <see cref="FileComponentBuilder"/>.
/// </summary> /// </summary>
public FileComponentBuilder() {} public FileComponentBuilder() { }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FileComponentBuilder"/>. /// Initializes a new instance of the <see cref="FileComponentBuilder"/>.
@@ -38,6 +38,16 @@ public class FileComponentBuilder : IMessageComponentBuilder
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
} }
/// <summary>
/// Initializes a new <see cref="FileComponentBuilder"/> from existing component.
/// </summary>
public FileComponentBuilder(FileComponent file)
{
File = file.File.ToProperties();
IsSpoiler = file.IsSpoiler;
Id = file.Id;
}
/// <summary> /// <summary>
/// Sets the file for the component. /// Sets the file for the component.
/// </summary> /// </summary>

View File

@@ -28,10 +28,18 @@ public class MediaGalleryBuilder : IMessageComponentBuilder
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="MediaGalleryBuilder"/>. /// Initializes a new instance of the <see cref="MediaGalleryBuilder"/>.
/// </summary> /// </summary>
public MediaGalleryBuilder(IEnumerable<MediaGalleryItemProperties> items, int? id = null) public MediaGalleryBuilder(params IEnumerable<MediaGalleryItemProperties> items)
{ {
Items = items.ToList(); Items = items?.ToList();
Id = id; }
/// <summary>
/// Initializes a new <see cref="MediaGalleryBuilder"/> from existing component.
/// </summary>
public MediaGalleryBuilder(MediaGalleryComponent mediaGallery)
{
Items = mediaGallery.Items.Select(x => x.ToProperties()).ToList();
Id = mediaGallery.Id;
} }
/// <summary> /// <summary>

View File

@@ -38,6 +38,25 @@ public class SectionBuilder : IMessageComponentBuilder, IStaticComponentContaine
set => _components = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Components)} cannot be null."); set => _components = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Components)} cannot be null.");
} }
/// <summary>
/// Initializes a new <see cref="SectionBuilder"/>.
/// </summary>
public SectionBuilder(IMessageComponentBuilder accessory = null, params IEnumerable<IMessageComponentBuilder> components)
{
Accessory = accessory;
Components = components?.ToList();
}
/// <summary>
/// Initializes a new <see cref="SectionBuilder"/> from existing component.
/// </summary>
public SectionBuilder(SectionComponent section)
{
Components = section.Components.Select(x => x.ToBuilder()).ToList();
Accessory = section.Accessory.ToBuilder();
Id = section.Id;
}
/// <inheritdoc cref="IComponentContainer.AddComponent"/> /// <inheritdoc cref="IComponentContainer.AddComponent"/>
/// <remarks> /// <remarks>
/// Only <see cref="TextDisplayBuilder"/> is supported. /// Only <see cref="TextDisplayBuilder"/> is supported.

View File

@@ -18,6 +18,25 @@ public class SeparatorBuilder : IMessageComponentBuilder
/// <inheritdoc/> /// <inheritdoc/>
public int? Id { get; set; } public int? Id { get; set; }
/// <summary>
/// Initializes a new <see cref="SeparatorBuilder"/>.
/// </summary>
public SeparatorBuilder(bool isDivider = true, SeparatorSpacingSize spacing = SeparatorSpacingSize.Small)
{
IsDivider = isDivider;
Spacing = spacing;
}
/// <summary>
/// Initializes a new <see cref="SeparatorBuilder"/> from existing component.
/// </summary>
public SeparatorBuilder(SeparatorComponent separator)
{
IsDivider = separator.IsDivider;
Spacing = separator.Spacing;
Id = separator.Id;
}
/// <summary> /// <summary>
/// Sets whether the component is a divider. /// Sets whether the component is a divider.
/// </summary> /// </summary>

View File

@@ -34,6 +34,15 @@ public class TextDisplayBuilder : IMessageComponentBuilder
Id = id; Id = id;
} }
/// <summary>
/// Initializes a new <see cref="TextDisplayBuilder"/> from existing component.
/// </summary>
public TextDisplayBuilder(TextDisplayComponent textDisplay)
{
Content = textDisplay.Content;
Id = textDisplay.Id;
}
/// <summary> /// <summary>
/// Sets the content of the text display. /// Sets the content of the text display.
/// </summary> /// </summary>

View File

@@ -45,6 +45,17 @@ public class ThumbnailBuilder : IMessageComponentBuilder
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
} }
/// <summary>
/// Initializes a new <see cref="ThumbnailBuilder"/> from existing component.
/// </summary>
public ThumbnailBuilder(ThumbnailComponent component)
{
Media = component.Media.ToProperties();
Description = component.Description;
IsSpoiler = component.IsSpoiler;
Id = component.Id;
}
/// <summary> /// <summary>
/// Sets the media of the thumbnail. /// Sets the media of the thumbnail.
/// </summary> /// </summary>