This commit is contained in:
Mihail Gribkov
2025-05-09 18:18:16 +03:00
committed by GitHub
parent c888c84752
commit 4ab96c7721
27 changed files with 264 additions and 236 deletions

View File

@@ -18,10 +18,19 @@ public class ActionRowComponent : IMessageComponent
/// </summary> /// </summary>
public IReadOnlyCollection<IMessageComponent> Components { get; internal set; } public IReadOnlyCollection<IMessageComponent> Components { get; internal set; }
/// <summary>
/// Converts a <see cref="ActionRowComponent"/> to a <see cref="ActionRowBuilder"/>.
/// </summary>
public ActionRowBuilder ToBuilder()
=> new(this);
internal ActionRowComponent() { } internal ActionRowComponent() { }
internal ActionRowComponent(IReadOnlyCollection<IMessageComponent> components) internal ActionRowComponent(IReadOnlyCollection<IMessageComponent> components)
{ {
Components = components; Components = components;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -19,98 +19,6 @@ public static class ComponentBuilderExtensions
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> /// <summary>
/// Converts a collection of <see cref="IMessageComponent"/> to a <see cref="ComponentBuilderV2"/>. /// Converts a collection of <see cref="IMessageComponent"/> to a <see cref="ComponentBuilderV2"/>.
/// </summary> /// </summary>

View File

@@ -169,6 +169,22 @@ public class TextInputBuilder : IInteractableComponentBuilder
} }
/// <summary>
/// Creates a new instance of a <see cref="TextInputBuilder"/> from existing component.
/// </summary>
public TextInputBuilder(TextInputComponent textInput)
{
Label = textInput.Label;
Style = textInput.Style;
CustomId = textInput.CustomId;
Placeholder = textInput.Placeholder;
MinLength = textInput.MinLength;
MaxLength = textInput.MaxLength;
Required = textInput.Required;
Value = textInput.Value;
Id = textInput.Id;
}
/// <summary> /// <summary>
/// Sets the label of the current builder. /// Sets the label of the current builder.
/// </summary> /// </summary>

View File

@@ -51,13 +51,10 @@ public class ButtonComponent : IInteractableComponent
public ulong? SkuId { get; } public ulong? SkuId { get; }
/// <summary> /// <summary>
/// Turns this button into a button builder. /// Converts a <see cref="ButtonComponent"/> to a <see cref="ButtonBuilder"/>.
/// </summary> /// </summary>
/// <returns>
/// A newly created button builder with the same properties as this button.
/// </returns>
public ButtonBuilder ToBuilder() public ButtonBuilder ToBuilder()
=> new (Label, CustomId, Style, Url, Emote, IsDisabled); => new(this);
internal ButtonComponent(ButtonStyle style, string label, IEmote emote, string customId, string url, bool isDisabled, ulong? skuId, int? id) internal ButtonComponent(ButtonStyle style, string label, IEmote emote, string customId, string url, bool isDisabled, ulong? skuId, int? id)
{ {
@@ -70,4 +67,7 @@ public class ButtonComponent : IInteractableComponent
IsDisabled = isDisabled; IsDisabled = isDisabled;
SkuId = skuId; SkuId = skuId;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -28,6 +28,12 @@ public class ContainerComponent : IMessageComponent
/// </summary> /// </summary>
public bool? IsSpoiler { get; } public bool? IsSpoiler { get; }
/// <summary>
/// Converts a <see cref="ContainerComponent"/> to a <see cref="ContainerBuilder"/>.
/// </summary>
public ContainerBuilder ToBuilder()
=> new(this);
internal ContainerComponent(IReadOnlyCollection<IMessageComponent> components, Color? accentColor, bool? isSpoiler, int? id = null) internal ContainerComponent(IReadOnlyCollection<IMessageComponent> components, Color? accentColor, bool? isSpoiler, int? id = null)
{ {
Components = components; Components = components;
@@ -35,4 +41,7 @@ public class ContainerComponent : IMessageComponent
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
Id = id; Id = id;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -21,10 +21,19 @@ public class FileComponent : IMessageComponent
/// </summary> /// </summary>
public bool? IsSpoiler { get; } public bool? IsSpoiler { get; }
/// <summary>
/// Converts a <see cref="FileComponent"/> to a <see cref="FileComponentBuilder"/>.
/// </summary>
public FileComponentBuilder ToBuilder()
=> new(this);
internal FileComponent(UnfurledMediaItem file, bool? isSpoiler, int? id = null) internal FileComponent(UnfurledMediaItem file, bool? isSpoiler, int? id = null)
{ {
File = file; File = file;
IsSpoiler = isSpoiler; IsSpoiler = isSpoiler;
Id = id; Id = id;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -10,5 +10,13 @@ public interface IMessageComponent
/// </summary> /// </summary>
ComponentType Type { get; } ComponentType Type { get; }
/// <summary>
///
/// </summary>
int? Id { get; } int? Id { get; }
/// <summary>
/// Converts a <see cref="IMessageComponent"/> to a <see cref="IMessageComponentBuilder"/>.
/// </summary>
public IMessageComponentBuilder ToBuilder();
} }

View File

@@ -18,9 +18,18 @@ public class MediaGalleryComponent : IMessageComponent
/// </summary> /// </summary>
public IReadOnlyCollection<MediaGalleryItem> Items { get; } public IReadOnlyCollection<MediaGalleryItem> Items { get; }
/// <summary>
/// Converts a <see cref="MediaGalleryComponent"/> to a <see cref="MediaGalleryBuilder"/>.
/// </summary>
public MediaGalleryBuilder ToBuilder()
=> new(this);
internal MediaGalleryComponent(IReadOnlyCollection<MediaGalleryItem> items, int? id) internal MediaGalleryComponent(IReadOnlyCollection<MediaGalleryItem> items, int? id)
{ {
Items = items; Items = items;
Id = id; Id = id;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -20,6 +20,12 @@ public readonly struct MediaGalleryItem
/// </summary> /// </summary>
public bool IsSpoiler { get; } public bool IsSpoiler { get; }
/// <summary>
/// Converts a <see cref="MediaGalleryItem"/> to a <see cref="MediaGalleryItemProperties"/>.
/// </summary>
public MediaGalleryItemProperties ToProperties()
=> new(Media.ToProperties(), Description, IsSpoiler);
internal MediaGalleryItem(UnfurledMediaItem media, string description, bool? isSpoiler) internal MediaGalleryItem(UnfurledMediaItem media, string description, bool? isSpoiler)
{ {
Media = media; Media = media;

View File

@@ -23,10 +23,19 @@ public class SectionComponent : IMessageComponent
/// </summary> /// </summary>
public IMessageComponent Accessory { get; } public IMessageComponent Accessory { get; }
/// <summary>
/// Converts a <see cref="SectionComponent"/> to a <see cref="SectionBuilder"/>.
/// </summary>
public SectionBuilder ToBuilder()
=> new(this);
internal SectionComponent(int? id, IReadOnlyCollection<IMessageComponent> components, IMessageComponent accessory) internal SectionComponent(int? id, IReadOnlyCollection<IMessageComponent> components, IMessageComponent accessory)
{ {
Id = id; Id = id;
Components = components; Components = components;
Accessory = accessory; Accessory = accessory;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Discord namespace Discord;
{
/// <summary> /// <summary>
/// Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/> /// Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/>
/// </summary> /// </summary>
@@ -54,20 +53,10 @@ namespace Discord
public IReadOnlyCollection<SelectMenuDefaultValue> DefaultValues { get; } public IReadOnlyCollection<SelectMenuDefaultValue> DefaultValues { get; }
/// <summary> /// <summary>
/// Turns this select menu into a builder. /// Converts a <see cref="SelectMenuComponent"/> to a <see cref="SelectMenuBuilder"/>.
/// </summary> /// </summary>
/// <returns>
/// A newly create builder with the same properties as this select menu.
/// </returns>
public SelectMenuBuilder ToBuilder() public SelectMenuBuilder ToBuilder()
=> new SelectMenuBuilder( => new(this);
CustomId,
Options.Select(x => new SelectMenuOptionBuilder(x.Label, x.Value, x.Description, x.Emote, x.IsDefault)).ToList(),
Placeholder,
MaxValues,
MinValues,
IsDisabled, Type, ChannelTypes.ToList(),
DefaultValues.ToList());
internal SelectMenuComponent(string customId, List<SelectMenuOption> options, string placeholder, int minValues, int maxValues, internal SelectMenuComponent(string customId, List<SelectMenuOption> options, string placeholder, int minValues, int maxValues,
bool disabled, ComponentType type, int? id, IEnumerable<ChannelType> channelTypes = null, IEnumerable<SelectMenuDefaultValue> defaultValues = null) bool disabled, ComponentType type, int? id, IEnumerable<ChannelType> channelTypes = null, IEnumerable<SelectMenuDefaultValue> defaultValues = null)
@@ -83,5 +72,7 @@ namespace Discord
ChannelTypes = channelTypes?.ToArray() ?? []; ChannelTypes = channelTypes?.ToArray() ?? [];
DefaultValues = defaultValues?.ToArray() ?? []; DefaultValues = defaultValues?.ToArray() ?? [];
} }
}
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -21,10 +21,19 @@ public class SeparatorComponent : IMessageComponent
/// </summary> /// </summary>
public SeparatorSpacingSize? Spacing { get; } public SeparatorSpacingSize? Spacing { get; }
/// <summary>
/// Converts a <see cref="SeparatorComponent"/> to a <see cref="SeparatorBuilder"/>.
/// </summary>
public SeparatorBuilder ToBuilder()
=> new(this);
internal SeparatorComponent(bool? isDivider, SeparatorSpacingSize? spacing, int? id = null) internal SeparatorComponent(bool? isDivider, SeparatorSpacingSize? spacing, int? id = null)
{ {
IsDivider = isDivider; IsDivider = isDivider;
Spacing = spacing; Spacing = spacing;
Id = id; Id = id;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -16,9 +16,18 @@ public class TextDisplayComponent : IMessageComponent
/// </summary> /// </summary>
public string Content { get; } public string Content { get; }
/// <summary>
/// Converts a <see cref="TextDisplayComponent"/> to a <see cref="TextDisplayBuilder"/>.
/// </summary>
public TextDisplayBuilder ToBuilder()
=> new(this);
internal TextDisplayComponent(string content, int? id = null) internal TextDisplayComponent(string content, int? id = null)
{ {
Id = id; Id = id;
Content = content; Content = content;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -1,5 +1,5 @@
namespace Discord namespace Discord;
{
/// <summary> /// <summary>
/// Represents a <see cref="IMessageComponent"/> text input. /// Represents a <see cref="IMessageComponent"/> text input.
/// </summary> /// </summary>
@@ -49,6 +49,13 @@ namespace Discord
/// </summary> /// </summary>
public string Value { get; } public string Value { get; }
/// <summary>
/// Converts a <see cref="TextInputComponent"/> to a <see cref="TextInputBuilder"/>.
/// </summary>
public TextInputBuilder ToBuilder()
=> new TextInputBuilder(this);
internal TextInputComponent(string customId, string label, string placeholder, int? minLength, int? maxLength, internal TextInputComponent(string customId, string label, string placeholder, int? minLength, int? maxLength,
TextInputStyle style, bool? required, string value, int? id) TextInputStyle style, bool? required, string value, int? id)
{ {
@@ -62,5 +69,7 @@ namespace Discord
Value = value; Value = value;
Id = id; Id = id;
} }
}
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -26,6 +26,12 @@ public class ThumbnailComponent : IMessageComponent
/// </summary> /// </summary>
public bool IsSpoiler { get; } public bool IsSpoiler { get; }
/// <summary>
/// Converts a <see cref="ThumbnailComponent"/> to a <see cref="ThumbnailBuilder"/>.
/// </summary>
public ThumbnailBuilder ToBuilder()
=> new(this);
internal ThumbnailComponent(int? id, UnfurledMediaItem media, string description, bool? isSpoiler) internal ThumbnailComponent(int? id, UnfurledMediaItem media, string description, bool? isSpoiler)
{ {
Id = id; Id = id;
@@ -33,4 +39,7 @@ public class ThumbnailComponent : IMessageComponent
Description = description; Description = description;
IsSpoiler = isSpoiler ?? false; IsSpoiler = isSpoiler ?? false;
} }
/// <inheritdoc />
IMessageComponentBuilder IMessageComponent.ToBuilder() => ToBuilder();
} }

View File

@@ -10,6 +10,12 @@ public class UnfurledMediaItem
/// </summary> /// </summary>
public string Url { get; } public string Url { get; }
/// <summary>
/// Converts a <see cref="UnfurledMediaItem"/> to a <see cref="UnfurledMediaItemProperties"/>.
/// </summary>
public UnfurledMediaItemProperties ToProperties()
=> new(Url);
internal UnfurledMediaItem(string url) internal UnfurledMediaItem(string url)
{ {
Url = url; Url = url;

View File

@@ -37,5 +37,6 @@ namespace Discord.API
[JsonIgnore] [JsonIgnore]
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }
} }

View File

@@ -70,5 +70,7 @@ namespace Discord.API
[JsonIgnore] [JsonIgnore]
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }
} }

View File

@@ -33,4 +33,5 @@ internal class ContainerComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -27,4 +27,5 @@ internal class FileComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -30,4 +30,5 @@ internal class MediaGalleryComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -29,4 +29,5 @@ internal class SectionComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -58,5 +58,6 @@ namespace Discord.API
[JsonIgnore] [JsonIgnore]
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }
} }

View File

@@ -27,4 +27,5 @@ internal class SeparatorComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -23,4 +23,5 @@ internal class TextDisplayComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }

View File

@@ -52,5 +52,6 @@ namespace Discord.API
[JsonIgnore] [JsonIgnore]
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }
} }

View File

@@ -32,4 +32,5 @@ internal class ThumbnailComponent : IMessageComponent
} }
int? IMessageComponent.Id => Id.ToNullable(); int? IMessageComponent.Id => Id.ToNullable();
IMessageComponentBuilder IMessageComponent.ToBuilder() => null;
} }