Greatly unboilerplated and simplified nadeko interaction button construction

This commit is contained in:
Kwoth
2022-08-07 17:00:36 +02:00
parent 13d2fbd560
commit 38e3badb87
18 changed files with 110 additions and 291 deletions

View File

@@ -0,0 +1,8 @@
namespace NadekoBot;
public interface INadekoInteractionService
{
public NadekoInteraction Create<T>(
ulong userId,
SimpleInteraction<T> inter);
}

View File

@@ -1,29 +0,0 @@
namespace NadekoBot;
public sealed class NadekoButtonActionInteraction : NadekoButtonOwnInteraction
{
private readonly NadekoInteractionData _data;
private readonly Func<SocketMessageComponent, Task> _action;
public NadekoButtonActionInteraction(
DiscordSocketClient client,
ulong authorId,
NadekoInteractionData data,
Func<SocketMessageComponent, Task> action
)
: base(client, authorId)
{
_data = data;
_action = action;
}
protected override string Name
=> _data.CustomId;
protected override IEmote Emote
=> _data.Emote;
protected override string? Text
=> _data.Text;
public override Task ExecuteOnActionAsync(SocketMessageComponent smc)
=> _action(smc);
}

View File

@@ -1,25 +1,30 @@
namespace NadekoBot; namespace NadekoBot;
public abstract class NadekoButtonInteraction public sealed class NadekoInteraction
{ {
// improvements: private readonly ulong _authorId;
// - state in OnAction private readonly ButtonBuilder _button;
// - configurable delay private readonly Func<SocketMessageComponent, Task> _onClick;
// - private readonly bool _onlyAuthor;
protected abstract string Name { get; }
protected abstract IEmote Emote { get; }
protected virtual string? Text { get; } = null;
public DiscordSocketClient Client { get; } public DiscordSocketClient Client { get; }
protected readonly TaskCompletionSource<bool> _interactionCompletedSource; private readonly TaskCompletionSource<bool> _interactionCompletedSource;
protected IUserMessage message = null!; private IUserMessage message = null!;
protected NadekoButtonInteraction(DiscordSocketClient client) public NadekoInteraction(DiscordSocketClient client,
ulong authorId,
ButtonBuilder button,
Func<SocketMessageComponent, Task> onClick,
bool onlyAuthor)
{ {
Client = client; _authorId = authorId;
_button = button;
_onClick = onClick;
_onlyAuthor = onlyAuthor;
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously); _interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
Client = client;
} }
public async Task RunAsync(IUserMessage msg) public async Task RunAsync(IUserMessage msg)
@@ -27,13 +32,12 @@ public abstract class NadekoButtonInteraction
message = msg; message = msg;
Client.InteractionCreated += OnInteraction; Client.InteractionCreated += OnInteraction;
await Task.WhenAny(Task.Delay(10_000), _interactionCompletedSource.Task); await Task.WhenAny(Task.Delay(15_000), _interactionCompletedSource.Task);
Client.InteractionCreated -= OnInteraction; Client.InteractionCreated -= OnInteraction;
await msg.ModifyAsync(m => m.Components = new ComponentBuilder().Build()); await msg.ModifyAsync(m => m.Components = new ComponentBuilder().Build());
} }
protected abstract ValueTask<bool> Validate(SocketMessageComponent smc);
private async Task OnInteraction(SocketInteraction arg) private async Task OnInteraction(SocketInteraction arg)
{ {
if (arg is not SocketMessageComponent smc) if (arg is not SocketMessageComponent smc)
@@ -42,14 +46,11 @@ public abstract class NadekoButtonInteraction
if (smc.Message.Id != message.Id) if (smc.Message.Id != message.Id)
return; return;
if (smc.Data.CustomId != Name) if (_onlyAuthor && smc.User.Id != _authorId)
return; return;
if (!await Validate(smc)) if (smc.Data.CustomId != _button.CustomId)
{
await smc.DeferAsync();
return; return;
}
_ = Task.Run(async () => _ = Task.Run(async () =>
{ {
@@ -66,18 +67,14 @@ public abstract class NadekoButtonInteraction
} }
public virtual MessageComponent CreateComponent() public MessageComponent CreateComponent()
{ {
var comp = new ComponentBuilder() var comp = new ComponentBuilder()
.WithButton(GetButtonBuilder()); .WithButton(_button);
return comp.Build(); return comp.Build();
} }
public ButtonBuilder GetButtonBuilder() public Task ExecuteOnActionAsync(SocketMessageComponent smc)
=> new ButtonBuilder(style: ButtonStyle.Secondary, emote: Emote, customId: Name, label: Text); => _onClick(smc);
}
public abstract Task ExecuteOnActionAsync(SocketMessageComponent smc);
}
// this is all so wrong ...

View File

@@ -1,43 +0,0 @@
// namespace NadekoBot;
//
// public class NadekoButtonInteractionArray : NadekoButtonInteraction
// {
// private readonly ButtonBuilder[] _bbs;
// private readonly NadekoButtonInteraction[] _inters;
//
// public NadekoButtonInteractionArray(params NadekoButtonInteraction[] inters)
// : base(inters[0].Client)
// {
// _inters = inters;
// _bbs = inters.Map(x => x.GetButtonBuilder());
// }
//
// protected override string Name
// => throw new NotSupportedException();
// protected override IEmote Emote
// => throw new NotSupportedException();
//
// protected override ValueTask<bool> Validate(SocketMessageComponent smc)
// => new(true);
//
// public override Task ExecuteOnActionAsync(SocketMessageComponent smc)
// {
// for (var i = 0; i < _bbs.Length; i++)
// {
// if (_bbs[i].CustomId == smc.Data.CustomId)
// return _inters[i].ExecuteOnActionAsync(smc);
// }
//
// return Task.CompletedTask;
// }
//
// public override MessageComponent CreateComponent()
// {
// var comp = new ComponentBuilder();
//
// foreach (var bb in _bbs)
// comp.WithButton(bb);
//
// return comp.Build();
// }
// }

View File

@@ -1,42 +0,0 @@
namespace NadekoBot;
/// <summary>
/// Builder class for NadekoInteractions
/// </summary>
public class NadekoInteractionBuilder
{
private NadekoInteractionData? iData;
private Func<SocketMessageComponent, Task>? action;
// private bool isOwn;
public NadekoInteractionBuilder WithData<T>(in T data)
where T : NadekoInteractionData
{
iData = data;
return this;
}
// public NadekoOwnInteractionBuiler WithIsOwn(bool isOwn = true)
// {
// this.isOwn = isOwn;
// return this;
// }
public NadekoInteractionBuilder WithAction(in Func<SocketMessageComponent, Task> fn)
{
this.action = fn;
return this;
}
public NadekoButtonActionInteraction Build(DiscordSocketClient client, ulong userId)
{
if (iData is null)
throw new InvalidOperationException("You have to specify the data before building the interaction");
if (action is null)
throw new InvalidOperationException("You have to specify the action before building the interaction");
return new(client, userId, iData, action);
}
}

View File

@@ -0,0 +1,20 @@
namespace NadekoBot;
public class NadekoInteractionService : INadekoInteractionService, INService
{
private readonly DiscordSocketClient _client;
public NadekoInteractionService(DiscordSocketClient client)
{
_client = client;
}
public NadekoInteraction Create<T>(
ulong userId,
SimpleInteraction<T> inter)
=> new NadekoInteraction(_client,
userId,
inter.Button,
inter.TriggerAsync,
onlyAuthor: true);
}

View File

@@ -1,15 +0,0 @@
namespace NadekoBot;
/// <summary>
/// Interaction which only the author can use
/// </summary>
public abstract class NadekoButtonOwnInteraction : NadekoButtonInteraction
{
protected readonly ulong _authorId;
protected NadekoButtonOwnInteraction(DiscordSocketClient client, ulong authorId) : base(client)
=> _authorId = authorId;
protected override ValueTask<bool> Validate(SocketMessageComponent smc)
=> new(smc.User.Id == _authorId);
}

View File

@@ -1,26 +0,0 @@
namespace NadekoBot.Common;
public abstract class NInteraction
{
private readonly DiscordSocketClient _client;
private readonly ulong _userId;
private readonly Func<SocketMessageComponent, Task> _action;
protected abstract NadekoInteractionData Data { get; }
public NInteraction(
DiscordSocketClient client,
ulong userId,
Func<SocketMessageComponent, Task> action)
{
_client = client;
_userId = userId;
_action = action;
}
public NadekoButtonInteraction GetInteraction()
=> new NadekoInteractionBuilder()
.WithData(Data)
.WithAction(_action)
.Build(_client, _userId);
}

View File

@@ -18,6 +18,7 @@ public abstract class NadekoModule : ModuleBase
public CommandHandler _cmdHandler { get; set; } public CommandHandler _cmdHandler { get; set; }
public ILocalization _localization { get; set; } public ILocalization _localization { get; set; }
public IEmbedBuilderService _eb { get; set; } public IEmbedBuilderService _eb { get; set; }
public INadekoInteractionService _inter { get; set; }
protected string prefix protected string prefix
=> _cmdHandler.GetPrefix(ctx.Guild); => _cmdHandler.GetPrefix(ctx.Guild);
@@ -36,7 +37,7 @@ public abstract class NadekoModule : ModuleBase
string error, string error,
string url = null, string url = null,
string footer = null, string footer = null,
NadekoButtonInteraction inter = null) NadekoInteraction inter = null)
=> ctx.Channel.SendErrorAsync(_eb, title, error, url, footer); => ctx.Channel.SendErrorAsync(_eb, title, error, url, footer);
public Task<IUserMessage> SendConfirmAsync( public Task<IUserMessage> SendConfirmAsync(
@@ -47,32 +48,32 @@ public abstract class NadekoModule : ModuleBase
=> ctx.Channel.SendConfirmAsync(_eb, title, text, url, footer); => ctx.Channel.SendConfirmAsync(_eb, title, text, url, footer);
// //
public Task<IUserMessage> SendErrorAsync(string text, NadekoButtonInteraction inter = null) public Task<IUserMessage> SendErrorAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MessageType.Error, inter); => ctx.Channel.SendAsync(_eb, text, MessageType.Error, inter);
public Task<IUserMessage> SendConfirmAsync(string text, NadekoButtonInteraction inter = null) public Task<IUserMessage> SendConfirmAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MessageType.Ok, inter); => ctx.Channel.SendAsync(_eb, text, MessageType.Ok, inter);
public Task<IUserMessage> SendPendingAsync(string text, NadekoButtonInteraction inter = null) public Task<IUserMessage> SendPendingAsync(string text, NadekoInteraction inter = null)
=> ctx.Channel.SendAsync(_eb, text, MessageType.Pending, inter); => ctx.Channel.SendAsync(_eb, text, MessageType.Pending, inter);
// localized normal // localized normal
public Task<IUserMessage> ErrorLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> ErrorLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendErrorAsync(GetText(str), inter); => SendErrorAsync(GetText(str), inter);
public Task<IUserMessage> PendingLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> PendingLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendPendingAsync(GetText(str), inter); => SendPendingAsync(GetText(str), inter);
public Task<IUserMessage> ConfirmLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> ConfirmLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendConfirmAsync(GetText(str), inter); => SendConfirmAsync(GetText(str), inter);
// localized replies // localized replies
public Task<IUserMessage> ReplyErrorLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> ReplyErrorLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); => SendErrorAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
public Task<IUserMessage> ReplyPendingLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> ReplyPendingLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); => SendPendingAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
public Task<IUserMessage> ReplyConfirmLocalizedAsync(LocStr str, NadekoButtonInteraction inter = null) public Task<IUserMessage> ReplyConfirmLocalizedAsync(LocStr str, NadekoInteraction inter = null)
=> SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter); => SendConfirmAsync($"{Format.Bold(ctx.User.ToString())} {GetText(str)}", inter);
public async Task<bool> PromptUserConfirmAsync(IEmbedBuilder embed) public async Task<bool> PromptUserConfirmAsync(IEmbedBuilder embed)

View File

@@ -1,13 +0,0 @@
#nullable disable
namespace NadekoBot.Modules.Gambling;
public class CashInteraction : NInteraction
{
protected override NadekoInteractionData Data
=> new NadekoInteractionData(new Emoji("🏦"), "cash:bank_show_balance");
public CashInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
: base(client, userId, action)
{
}
}

View File

@@ -99,39 +99,20 @@ public partial class Gambling : GamblingModule<GamblingService>
PrettyName = "Timely" PrettyName = "Timely"
}; };
public class RemindMeInteraction : NInteraction private async Task RemindTimelyAction(SocketMessageComponent smc, DateTime when)
{ {
public RemindMeInteraction( var tt = TimestampTag.FromDateTime(when, TimestampTagStyles.Relative);
[NotNull] DiscordSocketClient client,
ulong userId,
[NotNull] Func<SocketMessageComponent, Task> action)
: base(client, userId, action)
{
}
protected override NadekoInteractionData Data await _remind.AddReminderAsync(ctx.User.Id,
=> new NadekoInteractionData( ctx.User.Id,
Emote: Emoji.Parse("⏰"), ctx.Guild.Id,
CustomId: "timely:remind_me", true,
Text: "Remind me" when,
); GetText(strs.timely_time));
await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true);
} }
private Func<SocketMessageComponent, Task> RemindTimelyAction(DateTime when)
=> async smc =>
{
var tt = TimestampTag.FromDateTime(when, TimestampTagStyles.Relative);
await _remind.AddReminderAsync(ctx.User.Id,
ctx.User.Id,
ctx.Guild.Id,
true,
when,
GetText(strs.timely_time));
await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true);
};
[Cmd] [Cmd]
public async Task Timely() public async Task Timely()
{ {
@@ -157,11 +138,17 @@ public partial class Gambling : GamblingModule<GamblingService>
await _cs.AddAsync(ctx.User.Id, val, new("timely", "claim")); await _cs.AddAsync(ctx.User.Id, val, new("timely", "claim"));
var inter = new RemindMeInteraction(_client, var inter = _inter
ctx.User.Id, .Create(ctx.User.Id,
RemindTimelyAction(DateTime.UtcNow.Add(TimeSpan.FromHours(period)))); new SimpleInteraction<DateTime>(
new ButtonBuilder(
await ReplyConfirmLocalizedAsync(strs.timely(N(val), period), inter.GetInteraction()); label: "Remind me",
emote: Emoji.Parse("⏰"),
customId: "timely:remind_me"),
RemindTimelyAction,
DateTime.UtcNow.Add(TimeSpan.FromHours(period))));
await ReplyConfirmLocalizedAsync(strs.timely(N(val), period), inter);
} }
[Cmd] [Cmd]
@@ -362,7 +349,7 @@ public partial class Gambling : GamblingModule<GamblingService>
await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), cur)); await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), cur));
} }
private async Task BankAction(SocketMessageComponent smc) private async Task BankAction(SocketMessageComponent smc, object _)
{ {
var balance = await _bank.GetBalanceAsync(ctx.User.Id); var balance = await _bank.GetBalanceAsync(ctx.User.Id);
@@ -372,8 +359,12 @@ public partial class Gambling : GamblingModule<GamblingService>
.Pipe(text => smc.RespondConfirmAsync(_eb, text, ephemeral: true)); .Pipe(text => smc.RespondConfirmAsync(_eb, text, ephemeral: true));
} }
private NadekoButtonInteraction CreateCashInteraction() private NadekoInteraction CreateCashInteraction()
=> new CashInteraction(_client, ctx.User.Id, BankAction).GetInteraction(); => _inter.Create<object>(ctx.User.Id,
new(new(
customId: "cash:bank_show_balance",
emote: new Emoji("🏦")),
BankAction));
[Cmd] [Cmd]
[Priority(1)] [Priority(1)]

View File

@@ -73,16 +73,6 @@ public partial class Gambling
await ctx.Channel.EmbedAsync(embed); await ctx.Channel.EmbedAsync(embed);
} }
public sealed class SlotInteraction : NInteraction
{
public SlotInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action) : base(client, userId, action)
{
}
protected override NadekoInteractionData Data { get; } = new(Emoji.Parse("🔁"),
"slot:again",
"Pull Again");
}
[Cmd] [Cmd]
public async Task Slot(ShmartNumber amount) public async Task Slot(ShmartNumber amount)
@@ -117,7 +107,7 @@ public partial class Gambling
.WithImageUrl($"attachment://result.png") .WithImageUrl($"attachment://result.png")
.WithOkColor(); .WithOkColor();
// var inter = slotInteraction.GetInteraction(); //new(Emoji.Parse("🔁"), "slot:again", "Pull Again");
await ctx.Channel.SendFileAsync(imgStream, await ctx.Channel.SendFileAsync(imgStream,
"result.png", "result.png",
embed: eb.Build() embed: eb.Build()

View File

@@ -424,7 +424,7 @@ public partial class Help : NadekoModule<HelpService>
} }
catch (Exception) catch (Exception)
{ {
Log.Information("No old version list found. Creating a new one."); Log.Information("No old version list found. Creating a new one");
} }
var versionList = JsonSerializer.Deserialize<List<string>>(versionListString); var versionList = JsonSerializer.Deserialize<List<string>>(versionListString);
@@ -469,7 +469,7 @@ public partial class Help : NadekoModule<HelpService>
"https://nadekobot.readthedocs.io/en/latest/")); "https://nadekobot.readthedocs.io/en/latest/"));
private Task SelfhostAction(SocketMessageComponent smc) private Task SelfhostAction(SocketMessageComponent smc, object _)
=> smc.RespondConfirmAsync(_eb, => smc.RespondConfirmAsync(_eb,
@"- In case you don't want or cannot Donate to NadekoBot project, but you @"- In case you don't want or cannot Donate to NadekoBot project, but you
- NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own ""selfhosted"" instance on your computer or server for free. - NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own ""selfhosted"" instance on your computer or server for free.
@@ -484,7 +484,13 @@ public partial class Help : NadekoModule<HelpService>
[OnlyPublicBot] [OnlyPublicBot]
public async Task Donate() public async Task Donate()
{ {
var selfhostInter = new DonateSelfhostingInteraction(_client, ctx.User.Id, SelfhostAction); // => new NadekoInteractionData(new Emoji("🖥️"), "donate:selfhosting", "Selfhosting");
var selfhostInter = _inter.Create(ctx.User.Id,
new SimpleInteraction<object>(new ButtonBuilder(
emote: new Emoji("🖥️"),
customId: "donate:selfhosting",
label: "Selfhosting"),
SelfhostAction));
var eb = _eb.Create(ctx) var eb = _eb.Create(ctx)
.WithOkColor() .WithOkColor()
@@ -525,7 +531,7 @@ Nadeko will DM you the welcome instructions, and you may start using the patron-
try try
{ {
await (await ctx.User.CreateDMChannelAsync()).EmbedAsync(eb, inter: selfhostInter.GetInteraction()); await (await ctx.User.CreateDMChannelAsync()).EmbedAsync(eb, inter: selfhostInter);
_ = ctx.OkAsync(); _ = ctx.OkAsync();
} }
catch catch

View File

@@ -1,12 +0,0 @@
namespace NadekoBot.Modules.Help;
public class DonateSelfhostingInteraction : NInteraction
{
protected override NadekoInteractionData Data
=> new NadekoInteractionData(new Emoji("🖥️"), "donate:selfhosting", "Selfhosting");
public DonateSelfhostingInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
: base(client, userId, action)
{
}
}

View File

@@ -1,12 +0,0 @@
namespace NadekoBot.Modules.Help;
public class DonateTroubleshootInteraction : NInteraction
{
protected override NadekoInteractionData Data
=> new NadekoInteractionData(new Emoji("❓"), "donate:troubleshoot", "Troubleshoot");
public DonateTroubleshootInteraction(DiscordSocketClient client, ulong userId, Func<SocketMessageComponent, Task> action)
: base(client, userId, action)
{
}
}

View File

@@ -433,7 +433,6 @@ public partial class Xp : NadekoModule<XpService>
? GetText(strs.in_use) ? GetText(strs.in_use)
: GetText(strs.use), : GetText(strs.use),
"XP_SHOP_USE", "XP_SHOP_USE",
ButtonStyle.Primary,
emote: Emoji.Parse("👐"), emote: Emoji.Parse("👐"),
isDisabled: ownedItem.IsUsing); isDisabled: ownedItem.IsUsing);
@@ -448,7 +447,6 @@ public partial class Xp : NadekoModule<XpService>
{ {
var button = new ButtonBuilder(GetText(strs.buy), var button = new ButtonBuilder(GetText(strs.buy),
"XP_SHOP_BUY", "XP_SHOP_BUY",
ButtonStyle.Primary,
emote: Emoji.Parse("💰")); emote: Emoji.Parse("💰"));
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>( var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(

View File

@@ -33,7 +33,7 @@ public static class MessageChannelExtensions
public static async Task<IUserMessage> SendAsync( public static async Task<IUserMessage> SendAsync(
this IMessageChannel channel, this IMessageChannel channel,
string? plainText, string? plainText,
NadekoButtonInteraction? inter, NadekoInteraction? inter,
Embed? embed = null, Embed? embed = null,
IReadOnlyCollection<Embed>? embeds = null, IReadOnlyCollection<Embed>? embeds = null,
bool sanitizeAll = false) bool sanitizeAll = false)
@@ -72,7 +72,7 @@ public static class MessageChannelExtensions
IEmbedBuilder? embed, IEmbedBuilder? embed,
string plainText = "", string plainText = "",
IReadOnlyCollection<IEmbedBuilder>? embeds = null, IReadOnlyCollection<IEmbedBuilder>? embeds = null,
NadekoButtonInteraction? inter = null) NadekoInteraction? inter = null)
=> ch.SendAsync(plainText, => ch.SendAsync(plainText,
inter, inter,
embed: embed?.Build(), embed: embed?.Build(),
@@ -83,7 +83,7 @@ public static class MessageChannelExtensions
IEmbedBuilderService eb, IEmbedBuilderService eb,
string text, string text,
MessageType type, MessageType type,
NadekoButtonInteraction? inter = null) NadekoInteraction? inter = null)
{ {
var builder = eb.Create().WithDescription(text); var builder = eb.Create().WithDescription(text);

View File

@@ -56,7 +56,7 @@ public static class SocketMessageComponentExtensions
IEmbedBuilder? embed, IEmbedBuilder? embed,
string plainText = "", string plainText = "",
IReadOnlyCollection<IEmbedBuilder>? embeds = null, IReadOnlyCollection<IEmbedBuilder>? embeds = null,
NadekoButtonInteraction? inter = null, NadekoInteraction? inter = null,
bool ephemeral = false) bool ephemeral = false)
=> smc.RespondAsync(plainText, => smc.RespondAsync(plainText,
embed: embed?.Build(), embed: embed?.Build(),
@@ -69,7 +69,7 @@ public static class SocketMessageComponentExtensions
string text, string text,
MessageType type, MessageType type,
bool ephemeral = false, bool ephemeral = false,
NadekoButtonInteraction? inter = null) NadekoInteraction? inter = null)
{ {
var builder = eb.Create().WithDescription(text); var builder = eb.Create().WithDescription(text);