Skip to content

Commit

Permalink
Change EmbedBuilder extension method AddPaginatedFooter to take the t…
Browse files Browse the repository at this point in the history
…otal number of pages as the last argument.
  • Loading branch information
expeehaa committed Aug 16, 2020
1 parent 91c4d57 commit ca062d7
Show file tree
Hide file tree
Showing 19 changed files with 143 additions and 148 deletions.
4 changes: 2 additions & 2 deletions src/MitternachtBot/Extensions/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public static ConcurrentDictionary<TKey, TValue> ToConcurrent<TKey, TValue>(this
public static string FormattedSummary(this CommandInfo cmd, string prefix) => string.Format(cmd.Summary, prefix);
public static string FormattedRemarks(this CommandInfo cmd, string prefix) => string.Format(cmd.Remarks, prefix);

public static EmbedBuilder AddPaginatedFooter(this EmbedBuilder embed, int curPage, int? lastPage) {
return lastPage != null ? embed.WithFooter(efb => efb.WithText($"{curPage + 1} / {lastPage + 1}")) : embed.WithFooter(efb => efb.WithText(curPage.ToString()));
public static EmbedBuilder AddPaginatedFooter(this EmbedBuilder embed, int curPage, int? pageCount) {
return pageCount != null ? embed.WithFooter(efb => efb.WithText($"{curPage + 1} / {pageCount}")) : embed.WithFooter(efb => efb.WithText(curPage.ToString()));
}

public static EmbedBuilder WithOkColor(this EmbedBuilder eb)
Expand Down
38 changes: 19 additions & 19 deletions src/MitternachtBot/Extensions/MessageChannelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, stri
/// <param name="client">DiscordSocketClient instance</param>
/// <param name="currentPage">current page from 0 to lastpage</param>
/// <param name="pageFunc">Func returning EmbedBuilder for each page</param>
/// <param name="lastPage">Last page number, 0 based.</param>
/// <param name="pageCount">Total number of pages.</param>
/// <param name="addPaginatedFooter">whether footer with current page numbers should be added or not</param>
/// <param name="reactUsers">additional users which can change pages</param>
/// <param name="hasPerms">overturn reactUsers if certain permission is available</param>
/// <returns></returns>
public static Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordSocketClient client, int currentPage, Func<int, EmbedBuilder> pageFunc, int? lastPage = null, bool addPaginatedFooter = true, IGuildUser[] reactUsers = null, Func<GuildPermissions, bool> hasPerms = null)
=> channel.SendPaginatedConfirmAsync(client, currentPage, x => Task.FromResult(pageFunc(x)), lastPage, addPaginatedFooter, reactUsers, hasPerms);
public static Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordSocketClient client, int currentPage, Func<int, EmbedBuilder> pageFunc, int? pageCount = null, bool addPaginatedFooter = true, IGuildUser[] reactUsers = null, Func<GuildPermissions, bool> hasPerms = null)
=> channel.SendPaginatedConfirmAsync(client, currentPage, x => Task.FromResult(pageFunc(x)), pageCount, addPaginatedFooter, reactUsers, hasPerms);

/// <summary>
/// Creates a paginated confirm embed.
Expand All @@ -62,24 +62,24 @@ public static Task SendPaginatedConfirmAsync(this IMessageChannel channel, Disco
/// <param name="client">DiscordSocketClient instance</param>
/// <param name="currentPage">current page from 0 to lastpage</param>
/// <param name="pageFunc">Func returning EmbedBuilder for each page</param>
/// <param name="lastPage">Last page number, 0 based.</param>
/// <param name="pageCount">Total number of pages.</param>
/// <param name="addPaginatedFooter">whether footer with current page numbers should be added or not</param>
/// <param name="reactUsers">additional users which can change pages</param>
/// <param name="hasPerms">overturn reactUsers if certain permission is available</param>
/// <returns></returns>
public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordSocketClient client, int currentPage, Func<int, Task<EmbedBuilder>> pageFunc, int? lastPage = null, bool addPaginatedFooter = true, IGuildUser[] reactUsers = null, Func<GuildPermissions, bool> hasPerms = null) {
public static async Task SendPaginatedConfirmAsync(this IMessageChannel channel, DiscordSocketClient client, int currentPage, Func<int, Task<EmbedBuilder>> pageFunc, int? pageCount = null, bool addPaginatedFooter = true, IGuildUser[] reactUsers = null, Func<GuildPermissions, bool> hasPerms = null) {
reactUsers ??= new IGuildUser[0];
if(hasPerms == null)
hasPerms = gp => !reactUsers.Any();

var embed = await pageFunc(currentPage).ConfigureAwait(false);

if(addPaginatedFooter)
embed.AddPaginatedFooter(currentPage, lastPage);
embed.AddPaginatedFooter(currentPage, pageCount);

var msg = await channel.EmbedAsync(embed);

if(lastPage == 0)
if(pageCount == 0)
return;

var _ = Task.Run(async () => {
Expand All @@ -94,19 +94,19 @@ async void ChangePage(SocketReaction r) {
return;

if(r.Emote.Name == ArrowLeft.Name) {
if(currentPage == 0)
return;
var toSend = await pageFunc(--currentPage).ConfigureAwait(false);
if(addPaginatedFooter)
toSend.AddPaginatedFooter(currentPage, lastPage);
await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false);
if(currentPage != 0) {
var toSend = await pageFunc(--currentPage).ConfigureAwait(false);
if(addPaginatedFooter)
toSend.AddPaginatedFooter(currentPage, pageCount);
await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false);
}
} else if(r.Emote.Name == ArrowRight.Name) {
if(lastPage != null && !(lastPage > currentPage))
return;
var toSend = await pageFunc(++currentPage).ConfigureAwait(false);
if(addPaginatedFooter)
toSend.AddPaginatedFooter(currentPage, lastPage);
await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false);
if(pageCount == null || currentPage < pageCount-1) {
var toSend = await pageFunc(++currentPage).ConfigureAwait(false);
if(addPaginatedFooter)
toSend.AddPaginatedFooter(currentPage, pageCount);
await msg.ModifyAsync(x => x.Embed = toSend.Build()).ConfigureAwait(false);
}
}
} catch(InvalidOperationException e) {
LogManager.GetCurrentClassLogger().Error(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,12 @@ public async Task Lsar(int page = 1) {
roles.AddRange(toRemove.Select(role => GetText("role_clean", role.RoleId)));
await uow.SaveChangesAsync(false);

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, curPage => new EmbedBuilder()
const int elementsPerPage = 10;

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage => new EmbedBuilder()
.WithTitle(GetText("self_assign_list", roleCnt))
.WithDescription(string.Join("\n", roles.Skip(curPage * 10).Take(10)))
.WithOkColor(), roles.Count / 10, reactUsers: new[] { Context.User as IGuildUser });
.WithDescription(string.Join("\n", roles.Skip(currentPage * elementsPerPage).Take(elementsPerPage)))
.WithOkColor(), (int)Math.Ceiling(roles.Count * 1d / elementsPerPage), reactUsers: new[] { Context.User as IGuildUser });
}

[MitternachtCommand, Usage, Description, Aliases]
Expand Down
6 changes: 3 additions & 3 deletions src/MitternachtBot/Modules/Administration/TimeZoneCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public async Task Timezones(int page = 1)
const int timezonesPerPage = 20;

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page,
curPage => new EmbedBuilder()
currentPage => new EmbedBuilder()
.WithOkColor()
.WithTitle(GetText("timezones_available"))
.WithDescription(string.Join("\n", timezones.Skip(curPage * timezonesPerPage).Take(timezonesPerPage).Select(x => $"`{x.Id,-25}` {(x.BaseUtcOffset < TimeSpan.Zero? "-" : "+")}{x.BaseUtcOffset:hhmm}"))),
timezones.Length / timezonesPerPage, reactUsers: new[] { Context.User as IGuildUser });
.WithDescription(string.Join("\n", timezones.Skip(currentPage * timezonesPerPage).Take(timezonesPerPage).Select(x => $"`{x.Id,-25}` {(x.BaseUtcOffset < TimeSpan.Zero? "-" : "+")}{x.BaseUtcOffset:hhmm}"))),
(int)Math.Ceiling(timezones.Length * 1d / timezonesPerPage), reactUsers: new[] { Context.User as IGuildUser });
}

[MitternachtCommand, Usage, Description, Aliases]
Expand Down
13 changes: 7 additions & 6 deletions src/MitternachtBot/Modules/Administration/UserPunishCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private async Task InternalWarnlog(ulong userId, int page) {
var showMods = (Context.User as IGuildUser).GuildPermissions.ViewAuditLog;
var textKey = showMods ? "warned_on_by" : "warned_on";

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, p => {
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage => {
var warnings = allWarnings.Skip(page * warnsPerPage).Take(warnsPerPage).ToArray();

if(!warnings.Any()) {
Expand All @@ -103,7 +103,7 @@ await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketC
}

return embed;
}, allWarnings.Count() / warnsPerPage, reactUsers: new[] {Context.User as IGuildUser}, hasPerms: gp => gp.KickMembers);
}, (int)Math.Ceiling(allWarnings.Count() * 1d / warnsPerPage), reactUsers: new[] {Context.User as IGuildUser}, hasPerms: gp => gp.KickMembers);
}

[MitternachtCommand, Usage, Description, Aliases]
Expand All @@ -114,9 +114,10 @@ public async Task WarnlogAll(int page = 1) {

var warnings = uow.Warnings.GetForGuild(Context.Guild.Id).OrderByDescending(w => w.DateAdded).ToList().GroupBy(x => x.UserId);

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, async curPage => {
var ws = await Task.WhenAll(warnings.Skip(curPage * 15)
.Take(15)
const int elementsPerPage = 15;
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, async currentPage => {
var ws = await Task.WhenAll(warnings.Skip(currentPage * elementsPerPage)
.Take(elementsPerPage)
.ToArray()
.Select(async x => {
var all = x.Count();
Expand All @@ -126,7 +127,7 @@ await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketC
}));

return new EmbedBuilder().WithTitle(GetText("warnings_list")).WithDescription(string.Join("\n", ws));
}, warnings.Count() / 15, reactUsers: new[] {Context.User as IGuildUser}, hasPerms: gp => gp.KickMembers)
}, (int)Math.Ceiling(warnings.Count() * 1d / elementsPerPage), reactUsers: new[] {Context.User as IGuildUser}, hasPerms: gp => gp.KickMembers)
.ConfigureAwait(false);
}

Expand Down
12 changes: 6 additions & 6 deletions src/MitternachtBot/Modules/Birthday/Birthday.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ public async Task BirthdaysAll(int page = 1) {
return;
}

const int itemcount = 10;
var pagecount = (int)Math.Ceiling(birthdates.Count / (itemcount * 1d));
page = page > pagecount ? pagecount : page;
const int elementsPerPage = 10;
var pageCount = (int)Math.Ceiling(birthdates.Count * 1d / elementsPerPage);
page = page > pageCount ? pageCount : page;

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page - 1,
p => new EmbedBuilder().WithOkColor().WithTitle(GetText("all_title")).WithDescription(string.Join("\n",
birthdates.Skip(itemcount * p).Take(itemcount).Select(BdmToString))),
pagecount - 1, reactUsers: new[] { Context.User as IGuildUser }).ConfigureAwait(false);
currentPage => new EmbedBuilder().WithOkColor().WithTitle(GetText("all_title")).WithDescription(string.Join("\n",
birthdates.Skip(elementsPerPage * currentPage).Take(elementsPerPage).Select(BdmToString))),
pageCount, reactUsers: new[] { Context.User as IGuildUser }).ConfigureAwait(false);
}

[MitternachtCommand, Usage, Description, Aliases]
Expand Down
32 changes: 13 additions & 19 deletions src/MitternachtBot/Modules/CustomReactions/CustomReactions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ namespace Mitternacht.Modules.CustomReactions {
public class CustomReactions : MitternachtTopLevelModule<CustomReactionsService> {
private readonly IBotCredentials _creds;
private readonly IUnitOfWork uow;
private readonly DiscordSocketClient _client;

public CustomReactions(IBotCredentials creds, IUnitOfWork uow, DiscordSocketClient client) {
public CustomReactions(IBotCredentials creds, IUnitOfWork uow) {
_creds = creds;
this.uow = uow;
_client = client;
}

[MitternachtCommand, Usage, Description, Aliases]
Expand Down Expand Up @@ -69,10 +67,9 @@ public async Task ListCustReact(int page = 1) {
return;
}

var lastPage = customReactions.Length / 20;
await Context.Channel.SendPaginatedConfirmAsync(_client, page,
curPage => new EmbedBuilder().WithOkColor().WithTitle(GetText("name")).WithDescription(string.Join("\n",
customReactions.OrderBy(cr => cr.Trigger).Skip(curPage * 20).Take(20).Select(cr => {
const int elementsPerPage = 20;
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage => new EmbedBuilder().WithOkColor().WithTitle(GetText("name")).WithDescription(string.Join("\n",
customReactions.OrderBy(cr => cr.Trigger).Skip(currentPage * elementsPerPage).Take(elementsPerPage).Select(cr => {
var str = $"`#{cr.Id}` {cr.Trigger}";
if(cr.AutoDeleteTrigger) {
str = "🗑" + str;
Expand All @@ -81,7 +78,7 @@ await Context.Channel.SendPaginatedConfirmAsync(_client, page,
str = "📪" + str;
}
return str;
}))), lastPage, reactUsers: new[] { Context.User as IGuildUser }).ConfigureAwait(false);
}))), (int)Math.Ceiling(customReactions.Length * 1d / elementsPerPage), reactUsers: new[] { Context.User as IGuildUser }).ConfigureAwait(false);
}

public enum All {
Expand Down Expand Up @@ -127,14 +124,14 @@ public async Task ListCustReactG(int page = 1) {
.OrderBy(cr => cr.Key)
.ToList();

var lastPage = ordered.Count / 20;
await Context.Channel.SendPaginatedConfirmAsync(_client, page, curPage =>
const int elementsPerPage = 20;
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage =>
new EmbedBuilder().WithOkColor()
.WithTitle(GetText("name"))
.WithDescription(string.Join("\r\n", ordered
.Skip(curPage * 20)
.Take(20)
.Select(cr => $"**{cr.Key.Trim().ToLowerInvariant()}** `x{cr.Count()}`"))), lastPage, reactUsers: new[] { Context.User as IGuildUser })
.Skip(currentPage * elementsPerPage)
.Take(elementsPerPage)
.Select(cr => $"**{cr.Key.Trim().ToLowerInvariant()}** `x{cr.Count()}`"))), (int)Math.Ceiling(ordered.Count * 1d / elementsPerPage), reactUsers: new[] { Context.User as IGuildUser })
.ConfigureAwait(false);
}
}
Expand Down Expand Up @@ -277,12 +274,9 @@ public async Task CrStats(int page = 1) {
var ordered = Service.ReactionStats.OrderByDescending(x => x.Value).ToArray();
if(!ordered.Any())
return;
var lastPage = ordered.Length / 9;
await Context.Channel.SendPaginatedConfirmAsync(_client, page,
curPage => ordered.Skip(curPage * 9).Take(9)
.Aggregate(new EmbedBuilder().WithOkColor().WithTitle(GetText("stats")),
(agg, cur) => agg.AddField(efb => efb.WithName(cur.Key).WithValue(cur.Value.ToString())
.WithIsInline(true))), lastPage, reactUsers: new[] { Context.User as IGuildUser }, hasPerms: gp => gp.KickMembers).ConfigureAwait(false);

const int elementsPerPage = 9;
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage => ordered.Skip(currentPage * elementsPerPage).Take(elementsPerPage).Aggregate(new EmbedBuilder().WithOkColor().WithTitle(GetText("stats")), (agg, cur) => agg.AddField(efb => efb.WithName(cur.Key).WithValue(cur.Value.ToString()).WithIsInline(true))), (int)Math.Ceiling(ordered.Length * 1d / elementsPerPage), reactUsers: new[] { Context.User as IGuildUser }, hasPerms: gp => gp.KickMembers).ConfigureAwait(false);
}
}
}
13 changes: 6 additions & 7 deletions src/MitternachtBot/Modules/Gambling/FlowerShopCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class FlowerShopCommands : MitternachtSubmodule {
private readonly IBotConfigProvider _bc;
private readonly IUnitOfWork uow;
private readonly CurrencyService _cs;
private readonly DiscordSocketClient _client;

public enum Role {
Role
Expand All @@ -31,11 +30,10 @@ public enum List {
List
}

public FlowerShopCommands(IBotConfigProvider bc, IUnitOfWork uow, CurrencyService cs, DiscordSocketClient client) {
public FlowerShopCommands(IBotConfigProvider bc, IUnitOfWork uow, CurrencyService cs) {
this.uow = uow;
_bc = bc;
_cs = cs;
_client = client;
}

[MitternachtCommand, Usage, Description, Aliases]
Expand All @@ -46,8 +44,9 @@ public async Task Shop(int page = 1) {

var entries = new IndexedCollection<ShopEntry>(uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items)).ShopEntries);

await Context.Channel.SendPaginatedConfirmAsync(_client, page, curPage => {
var theseEntries = entries.Skip(curPage * 9).Take(9).ToArray();
const int elementsPerPage = 9;
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page, currentPage => {
var theseEntries = entries.Skip(currentPage * elementsPerPage).Take(elementsPerPage).ToArray();

if(!theseEntries.Any())
return new EmbedBuilder().WithErrorColor()
Expand All @@ -57,10 +56,10 @@ await Context.Channel.SendPaginatedConfirmAsync(_client, page, curPage => {

for(var i = 0; i < theseEntries.Length; i++) {
var entry = theseEntries[i];
embed.AddField(efb => efb.WithName($"#{curPage * 9 + i + 1} - {entry.Price}{_bc.BotConfig.CurrencySign}").WithValue(EntryToString(entry)).WithIsInline(true));
embed.AddField(efb => efb.WithName($"#{currentPage * elementsPerPage + i + 1} - {entry.Price}{_bc.BotConfig.CurrencySign}").WithValue(EntryToString(entry)).WithIsInline(true));
}
return embed;
}, entries.Count / 9, reactUsers: new[] { Context.User as IGuildUser });
}, (int)Math.Ceiling(entries.Count * 1d / elementsPerPage), reactUsers: new[] { Context.User as IGuildUser });
}

[MitternachtCommand, Usage, Description, Aliases]
Expand Down
6 changes: 3 additions & 3 deletions src/MitternachtBot/Modules/Gambling/Gambling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,17 @@ public async Task Leaderboard(int page = 1) {
const int elementsPerPage = 9;
var currencyCount = uow.Currency.GetAll().Count();

await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page - 1, async p => {
await Context.Channel.SendPaginatedConfirmAsync(Context.Client as DiscordSocketClient, page - 1, async currentPage => {
var embedBuilder = new EmbedBuilder().WithOkColor().WithTitle($"{CurrencySign} {GetText("leaderboard")}");
using var unitOfWork = _db.UnitOfWork;
var leaderboardPage = unitOfWork.Currency.OrderByAmount().Skip(elementsPerPage * p).Take(elementsPerPage).ToList();
var leaderboardPage = unitOfWork.Currency.OrderByAmount().Skip(elementsPerPage * currentPage).Take(elementsPerPage).ToList();

if(leaderboardPage.Any()) {
foreach(var c in leaderboardPage) {
var user = await Context.Guild.GetUserAsync(c.UserId).ConfigureAwait(false);
var username = user?.Username.TrimTo(20, true) ?? c.UserId.ToString();

embedBuilder.AddField($"#{elementsPerPage * p + leaderboardPage.IndexOf(c) + 1} {username}", $"{c.Amount} {CurrencySign}", true);
embedBuilder.AddField($"#{elementsPerPage * currentPage + leaderboardPage.IndexOf(c) + 1} {username}", $"{c.Amount} {CurrencySign}", true);
}
} else {
embedBuilder.WithDescription(GetText("no_users_found"));
Expand Down
Loading

0 comments on commit ca062d7

Please sign in to comment.