mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 02:08:27 -04:00
211 lines
7.6 KiB
C#
211 lines
7.6 KiB
C#
namespace NadekoBot.Extensions;
|
|
|
|
public static class MessageChannelExtensions
|
|
{
|
|
private static readonly IEmote _arrowLeft = new Emoji("⬅");
|
|
private static readonly IEmote _arrowRight = new Emoji("➡");
|
|
|
|
public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, IEmbedBuilder embed, string msg = "")
|
|
=> ch.SendMessageAsync(msg, embed: embed.Build(), options: new() { RetryMode = RetryMode.AlwaysRetry });
|
|
|
|
public static Task<IUserMessage> SendAsync(
|
|
this IMessageChannel channel,
|
|
string? plainText,
|
|
Embed? embed,
|
|
bool sanitizeAll = false)
|
|
{
|
|
plainText = sanitizeAll ? plainText?.SanitizeAllMentions() ?? "" : plainText?.SanitizeMentions() ?? "";
|
|
|
|
return channel.SendMessageAsync(plainText, embed: embed);
|
|
}
|
|
|
|
public static Task<IUserMessage> SendAsync(this IMessageChannel channel, SmartText text, bool sanitizeAll = false)
|
|
=> text switch
|
|
{
|
|
SmartEmbedText set => channel.SendAsync(set.PlainText, set.GetEmbed().Build(), sanitizeAll),
|
|
SmartPlainText st => channel.SendAsync(st.Text, null, sanitizeAll),
|
|
_ => throw new ArgumentOutOfRangeException(nameof(text))
|
|
};
|
|
|
|
// this is a huge problem, because now i don't have
|
|
// access to embed builder service
|
|
// as this is an extension of the message channel
|
|
public static Task<IUserMessage> SendErrorAsync(
|
|
this IMessageChannel ch,
|
|
IEmbedBuilderService eb,
|
|
string title,
|
|
string error,
|
|
string? url = null,
|
|
string? footer = null)
|
|
{
|
|
var embed = eb.Create().WithErrorColor().WithDescription(error).WithTitle(title);
|
|
|
|
if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
|
embed.WithUrl(url);
|
|
|
|
if (!string.IsNullOrWhiteSpace(footer))
|
|
embed.WithFooter(footer);
|
|
|
|
return ch.SendMessageAsync("", embed: embed.Build());
|
|
}
|
|
|
|
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, IEmbedBuilderService eb, string error)
|
|
=> ch.SendMessageAsync("", embed: eb.Create().WithErrorColor().WithDescription(error).Build());
|
|
|
|
public static Task<IUserMessage> SendPendingAsync(this IMessageChannel ch, IEmbedBuilderService eb, string message)
|
|
=> ch.SendMessageAsync("", embed: eb.Create().WithPendingColor().WithDescription(message).Build());
|
|
|
|
public static Task<IUserMessage> SendConfirmAsync(
|
|
this IMessageChannel ch,
|
|
IEmbedBuilderService eb,
|
|
string title,
|
|
string text,
|
|
string? url = null,
|
|
string? footer = null)
|
|
{
|
|
var embed = eb.Create().WithOkColor().WithDescription(text).WithTitle(title);
|
|
|
|
if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
|
embed.WithUrl(url);
|
|
|
|
if (!string.IsNullOrWhiteSpace(footer))
|
|
embed.WithFooter(footer);
|
|
|
|
return ch.SendMessageAsync("", embed: embed.Build());
|
|
}
|
|
|
|
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, IEmbedBuilderService eb, string text)
|
|
=> ch.SendMessageAsync("", embed: eb.Create().WithOkColor().WithDescription(text).Build());
|
|
|
|
public static Task<IUserMessage> SendTableAsync<T>(
|
|
this IMessageChannel ch,
|
|
string seed,
|
|
IEnumerable<T> items,
|
|
Func<T, string> howToPrint,
|
|
int columns = 3)
|
|
=> ch.SendMessageAsync($@"{seed}```css
|
|
{string.Join("\n", items.Chunk(columns)
|
|
.Select(ig => string.Concat(ig.Select(howToPrint))))}
|
|
```");
|
|
|
|
public static Task<IUserMessage> SendTableAsync<T>(
|
|
this IMessageChannel ch,
|
|
IEnumerable<T> items,
|
|
Func<T, string> howToPrint,
|
|
int columns = 3)
|
|
=> ch.SendTableAsync("", items, howToPrint, columns);
|
|
|
|
public static Task SendPaginatedConfirmAsync(
|
|
this ICommandContext ctx,
|
|
int currentPage,
|
|
Func<int, IEmbedBuilder> pageFunc,
|
|
int totalElements,
|
|
int itemsPerPage,
|
|
bool addPaginatedFooter = true)
|
|
=> ctx.SendPaginatedConfirmAsync(currentPage,
|
|
x => Task.FromResult(pageFunc(x)),
|
|
totalElements,
|
|
itemsPerPage,
|
|
addPaginatedFooter);
|
|
|
|
/// <summary>
|
|
/// danny kamisama
|
|
/// </summary>
|
|
public static async Task SendPaginatedConfirmAsync(
|
|
this ICommandContext ctx,
|
|
int currentPage,
|
|
Func<int, Task<IEmbedBuilder>> pageFunc,
|
|
int totalElements,
|
|
int itemsPerPage,
|
|
bool addPaginatedFooter = true)
|
|
{
|
|
var embed = await pageFunc(currentPage);
|
|
|
|
var lastPage = (totalElements - 1) / itemsPerPage;
|
|
|
|
var canPaginate = true;
|
|
if (ctx.Guild is SocketGuild sg && !sg.CurrentUser.GetPermissions((IGuildChannel)ctx.Channel).AddReactions)
|
|
canPaginate = false;
|
|
|
|
if (!canPaginate)
|
|
embed.WithFooter("⚠️ AddReaction permission required for pagination.");
|
|
else if (addPaginatedFooter)
|
|
embed.AddPaginatedFooter(currentPage, lastPage);
|
|
|
|
var msg = await ctx.Channel.EmbedAsync(embed);
|
|
|
|
if (lastPage == 0 || !canPaginate)
|
|
return;
|
|
|
|
await msg.AddReactionAsync(_arrowLeft);
|
|
await msg.AddReactionAsync(_arrowRight);
|
|
|
|
await Task.Delay(2000);
|
|
|
|
var lastPageChange = DateTime.MinValue;
|
|
|
|
async Task ChangePage(SocketReaction r)
|
|
{
|
|
try
|
|
{
|
|
if (r.UserId != ctx.User.Id)
|
|
return;
|
|
if (DateTime.UtcNow - lastPageChange < TimeSpan.FromSeconds(1))
|
|
return;
|
|
if (r.Emote.Name == _arrowLeft.Name)
|
|
{
|
|
if (currentPage == 0)
|
|
return;
|
|
lastPageChange = DateTime.UtcNow;
|
|
var toSend = await pageFunc(--currentPage);
|
|
if (addPaginatedFooter)
|
|
toSend.AddPaginatedFooter(currentPage, lastPage);
|
|
await msg.ModifyAsync(x => x.Embed = toSend.Build());
|
|
}
|
|
else if (r.Emote.Name == _arrowRight.Name)
|
|
{
|
|
if (lastPage > currentPage)
|
|
{
|
|
lastPageChange = DateTime.UtcNow;
|
|
var toSend = await pageFunc(++currentPage);
|
|
if (addPaginatedFooter)
|
|
toSend.AddPaginatedFooter(currentPage, lastPage);
|
|
await msg.ModifyAsync(x => x.Embed = toSend.Build());
|
|
}
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//ignored
|
|
}
|
|
}
|
|
|
|
using (msg.OnReaction((DiscordSocketClient)ctx.Client, ChangePage, ChangePage))
|
|
{
|
|
await Task.Delay(30000);
|
|
}
|
|
|
|
try
|
|
{
|
|
if (msg.Channel is ITextChannel && ((SocketGuild)ctx.Guild).CurrentUser.GuildPermissions.ManageMessages)
|
|
await msg.RemoveAllReactionsAsync();
|
|
else
|
|
await msg.Reactions.Where(x => x.Value.IsMe)
|
|
.Select(x => msg.RemoveReactionAsync(x.Key, ctx.Client.CurrentUser))
|
|
.WhenAll();
|
|
}
|
|
catch
|
|
{
|
|
// ignored
|
|
}
|
|
}
|
|
|
|
public static Task OkAsync(this ICommandContext ctx)
|
|
=> ctx.Message.AddReactionAsync(new Emoji("✅"));
|
|
|
|
public static Task ErrorAsync(this ICommandContext ctx)
|
|
=> ctx.Message.AddReactionAsync(new Emoji("❌"));
|
|
|
|
public static Task WarningAsync(this ICommandContext ctx)
|
|
=> ctx.Message.AddReactionAsync(new Emoji("⚠️"));
|
|
} |