161 lines
5.6 KiB
C#
161 lines
5.6 KiB
C#
using SkyBot.Helpers;
|
|
using SkyBot.Models;
|
|
using Valour.Sdk.Models.Messages.Embeds;
|
|
|
|
namespace SkyBot.Commands
|
|
{
|
|
public class Help : ICommand
|
|
{
|
|
public string Name => "help";
|
|
public string[] Aliases => ["cmds"];
|
|
public string Description => "Shows all commands by category.";
|
|
public string Category => "Info";
|
|
public string Usage => "help";
|
|
public string[] SubCommands => [];
|
|
|
|
private const int PageSize = 10;
|
|
|
|
public async Task Execute(CommandContext ctx)
|
|
{
|
|
if (!ctx.ChannelCache.TryGetValue(ctx.Channel.Id, out var channel)) return;
|
|
|
|
var categories = CommandRegistry.Categories
|
|
.Where(c => c.Key != "template")
|
|
.Where(c => c.Key != "dev" || PermissionHelper.IsOwner(ctx.Member))
|
|
.OrderBy(c => c.Key)
|
|
.ToList();
|
|
|
|
var categoryFirstPage = new Dictionary<string, int>();
|
|
var allChunks = new List<(string CategoryName, List<ICommand> Cmds, int ChunkIndex, int TotalChunks)>();
|
|
|
|
int nextPageIndex = 1;
|
|
foreach (var (categoryName, cmds) in categories)
|
|
{
|
|
var ordered = cmds.OrderBy(c => c.Name).ToList();
|
|
var chunks = ordered
|
|
.Select((cmd, i) => (cmd, i))
|
|
.GroupBy(x => x.i / PageSize)
|
|
.Select(g => g.Select(x => x.cmd).ToList())
|
|
.ToList();
|
|
|
|
categoryFirstPage[categoryName] = nextPageIndex;
|
|
for (int c = 0; c < chunks.Count; c++)
|
|
allChunks.Add((categoryName, chunks[c], c, chunks.Count));
|
|
|
|
nextPageIndex += chunks.Count;
|
|
}
|
|
|
|
var allCmds = allChunks
|
|
.SelectMany(chunk => chunk.Cmds)
|
|
.DistinctBy(cmd => cmd.Name)
|
|
.ToList();
|
|
|
|
var cmdDetailPage = new Dictionary<string, int>();
|
|
int detailPageIndex = nextPageIndex;
|
|
foreach (var cmd in allCmds)
|
|
cmdDetailPage[cmd.Name] = detailPageIndex++;
|
|
|
|
var builder = new EmbedBuilder();
|
|
builder.embed.HideChangePageArrows = true;
|
|
|
|
// Home page
|
|
builder.AddPage("✦ Help Menu", $"Prefix: {Config.Prefix}");
|
|
builder.AddRow()
|
|
.AddText("Select a Category")
|
|
.WithStyles(EmbedStyles.LabelText)
|
|
.CloseRow();
|
|
|
|
builder.AddRow();
|
|
foreach (var (categoryName, cmds) in categories)
|
|
{
|
|
builder.AddButton($"{categoryName.ToTitleCase()} ({cmds.Count})")
|
|
.WithStyles(EmbedStyles.CategoryBtn)
|
|
.OnClickGoToEmbedPage(categoryFirstPage[categoryName]);
|
|
}
|
|
builder.CloseRow();
|
|
|
|
// Category pages
|
|
int embedPage = 1;
|
|
foreach (var (categoryName, cmds, chunkIndex, totalChunks) in allChunks)
|
|
{
|
|
string? footer = totalChunks > 1
|
|
? $"Page {chunkIndex + 1}/{totalChunks} | Prefix: {Config.Prefix}"
|
|
: $"Prefix: {Config.Prefix}";
|
|
|
|
builder.AddPage($"✦ {categoryName.ToTitleCase()} Commands", footer);
|
|
|
|
foreach (var cmd in cmds)
|
|
{
|
|
builder.AddRow()
|
|
.AddButton(cmd.Name)
|
|
.WithStyles(EmbedStyles.CommandBtn)
|
|
.OnClickGoToEmbedPage(cmdDetailPage[cmd.Name])
|
|
.CloseRow();
|
|
}
|
|
|
|
builder.AddRow()
|
|
.AddButton("← Back")
|
|
.WithStyles(EmbedStyles.BackBtn)
|
|
.OnClickGoToEmbedPage(0);
|
|
|
|
if (chunkIndex > 0)
|
|
{
|
|
builder.AddButton("← Prev")
|
|
.WithStyles(EmbedStyles.NavBtn)
|
|
.OnClickGoToEmbedPage(embedPage - 1);
|
|
}
|
|
|
|
if (chunkIndex < totalChunks - 1)
|
|
{
|
|
builder.AddButton("Next →")
|
|
.WithStyles(EmbedStyles.NavBtn)
|
|
.OnClickGoToEmbedPage(embedPage + 1);
|
|
}
|
|
|
|
builder.CloseRow();
|
|
|
|
embedPage++;
|
|
}
|
|
|
|
// Command detail pages
|
|
foreach (var cmd in allCmds)
|
|
{
|
|
builder.AddPage($"✦ {cmd.Name.ToTitleCase()}", $"Prefix: {Config.Prefix}");
|
|
|
|
builder.AddRow()
|
|
.AddText("Description", cmd.Description)
|
|
.CloseRow();
|
|
|
|
if (cmd.Aliases.Length > 0)
|
|
{
|
|
builder.AddRow()
|
|
.AddText("Aliases", string.Join(", ", cmd.Aliases))
|
|
.CloseRow();
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(cmd.Usage))
|
|
{
|
|
builder.AddRow()
|
|
.AddText("Usage", $"{Config.Prefix}{cmd.Usage}")
|
|
.CloseRow();
|
|
}
|
|
|
|
if (cmd.SubCommands.Length > 0)
|
|
{
|
|
builder.AddRow()
|
|
.AddText("Sub-commands", string.Join(", ", cmd.SubCommands.Select(s => s.ToTitleCase())))
|
|
.CloseRow();
|
|
}
|
|
|
|
builder.AddRow()
|
|
.AddButton("← Back")
|
|
.WithStyles(EmbedStyles.BackBtn)
|
|
.OnClickGoToEmbedPage(categoryFirstPage[cmd.Category.ToLower()])
|
|
.CloseRow();
|
|
}
|
|
|
|
await MessageHelper.ReplyAsync(ctx, null, builder.embed);
|
|
}
|
|
}
|
|
}
|