add: Added dropdown menu for .cmds help and group help (part of cmds). Group help will no longer be on .h

fix: paginated response replies will no longer ping the author
This commit is contained in:
Kwoth
2024-05-20 00:37:29 +00:00
parent e2066f433f
commit 4e570475df
5 changed files with 124 additions and 61 deletions

View File

@@ -4,7 +4,6 @@ using NadekoBot.Modules.Help.Services;
using Newtonsoft.Json;
using System.Text;
using Nadeko.Common.Medusa;
using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping;
namespace NadekoBot.Modules.Help;
@@ -89,7 +88,7 @@ public sealed partial class Help : NadekoModule<HelpService>
var menu = new SelectMenuBuilder()
.WithPlaceholder("Select a module to see its commands")
.WithCustomId("modules");
.WithCustomId("cmds:modules_select");
foreach (var m in topLevelModules)
menu.AddOption(m.Name, m.Name, GetModuleEmoji(m.Name));
@@ -102,7 +101,7 @@ public sealed partial class Help : NadekoModule<HelpService>
var val = smc.Data.Values.FirstOrDefault();
if (val is null)
return;
await Commands(val);
});
@@ -242,10 +241,28 @@ public sealed partial class Help : NadekoModule<HelpService>
// order by name
var allowed = new List<CommandInfo>();
foreach (var cmd in _cmds.Commands
.Where(c => c.Module.GetTopLevelModule()
.Name
.StartsWith(module, StringComparison.InvariantCultureIgnoreCase)))
var mdls = _cmds.Commands
.Where(c => c.Module.GetTopLevelModule()
.Name
.StartsWith(module, StringComparison.InvariantCultureIgnoreCase))
.ToArray();
if (mdls.Length == 0)
{
var group = _cmds.Modules
.Where(x => x.Parent is not null)
.FirstOrDefault(x => string.Equals(x.Name.Replace("Commands", ""),
module,
StringComparison.InvariantCultureIgnoreCase));
if (group is not null)
{
await Group(group);
return;
}
}
foreach (var cmd in mdls)
{
var result = await _perms.CheckPermsAsync(ctx.Guild,
ctx.Channel,
@@ -257,6 +274,7 @@ public sealed partial class Help : NadekoModule<HelpService>
allowed.Add(cmd);
}
var cmds = allowed.OrderBy(c => c.Aliases[0])
.DistinctBy(x => x.Aliases[0])
.ToList();
@@ -296,55 +314,97 @@ public sealed partial class Help : NadekoModule<HelpService>
return;
}
var cnt = 0;
var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray();
var sb = new SelectMenuBuilder()
.WithCustomId("cmds:submodule_select")
.WithPlaceholder("Select a submodule to see detailed commands");
var groups = cmdsWithGroup.ToArray();
var embed = _sender.CreateEmbed().WithOkColor();
foreach (var g in groups)
{
var last = g.Count();
for (var i = 0; i < last; i++)
{
var transformed = g.ElementAt(i)
.Select(x =>
{
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
if (opts.View == CommandsOptions.ViewType.Cross)
{
return $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
}
sb.AddOption(g.Key, g.Key);
var transformed = g
.Select(x =>
{
//if cross is specified, and the command doesn't satisfy the requirements, cross it out
if (opts.View == CommandsOptions.ViewType.Cross)
{
return $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
}
if (x.Aliases.Count == 1)
return prefix + x.Aliases[0];
return prefix + x.Aliases[0] + " | " + prefix + x.Aliases[1];
});
if (x.Aliases.Count == 1)
return prefix + x.Aliases[0];
embed.AddField(g.ElementAt(i).Key, "" + string.Join("\n", transformed) + "", true);
}
return prefix + x.Aliases[0] + " | " + prefix + x.Aliases[1];
});
embed.AddField(g.Key, "" + string.Join("\n", transformed) + "", true);
}
embed.WithFooter(GetText(strs.commands_instr(prefix)));
await Response().Embed(embed).SendAsync();
var inter = _inter.Create(ctx.User.Id,
sb,
async (smc) =>
{
var groupName = smc.Data.Values.FirstOrDefault();
var mdl = _cmds.Modules.FirstOrDefault(x
=> string.Equals(x.Name.Replace("Commands", ""), groupName, StringComparison.InvariantCultureIgnoreCase));
await smc.DeferAsync();
await Group(mdl);
}
);
await Response().Embed(embed).Interaction(inter).SendAsync();
}
private async Task Group(ModuleInfo group)
{
var eb = _sender.CreateEmbed()
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
.WithOkColor();
var menu = new SelectMenuBuilder()
.WithCustomId("cmds:group_select")
.WithPlaceholder("Select a command to see its details");
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
{
string cmdName;
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
eb.AddField(cmdName, cmd.RealSummary(_strings, _medusae, Culture, prefix));
menu.AddOption(prefix + cmd.Aliases[0], cmd.Aliases[0]);
}
await Response().Embed(eb).SendAsync();
var inter = _inter.Create(ctx.User.Id,
menu,
async (smc) =>
{
await smc.DeferAsync();
await H(smc.Data.Values.FirstOrDefault());
});
await Response()
.Paginated()
.Items(group.Commands.DistinctBy(x => x.Aliases[0]).ToArray())
.PageSize(25)
.Interaction(inter)
.Page((items, _) =>
{
var eb = _sender.CreateEmbed()
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
.WithOkColor();
foreach (var cmd in items)
{
string cmdName;
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
eb.AddField(cmdName, cmd.RealSummary(_strings, _medusae, Culture, prefix));
}
return eb;
})
.SendAsync();
}
[Cmd]
@@ -364,12 +424,9 @@ public sealed partial class Help : NadekoModule<HelpService>
var group = _cmds.Modules
.SelectMany(x => x.Submodules)
.FirstOrDefault(x => string.Equals(x.Name?.Replace("Commands", string.Empty),
fail,
StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(x.Group,
fail,
StringComparison.InvariantCultureIgnoreCase));
.FirstOrDefault(x => string.Equals(x.Group,
fail,
StringComparison.InvariantCultureIgnoreCase));
if (group is not null)
{

View File

@@ -6,10 +6,10 @@ public sealed class NadekoButtonInteraction : NadekoInteraction
DiscordSocketClient client,
ulong authorId,
ButtonBuilder button,
Func<SocketMessageComponent, Task> onClick,
Func<SocketMessageComponent, Task> onAction,
bool onlyAuthor,
bool singleUse = true)
: base(client, authorId, button.CustomId, onClick, onlyAuthor, singleUse)
: base(client, authorId, button.CustomId, onAction, onlyAuthor, singleUse)
{
Button = button;
}

View File

@@ -6,10 +6,10 @@ public sealed class NadekoSelectInteraction : NadekoInteraction
DiscordSocketClient client,
ulong authorId,
SelectMenuBuilder menu,
Func<SocketMessageComponent, Task> onClick,
Func<SocketMessageComponent, Task> onAction,
bool onlyAuthor,
bool singleUse = true)
: base(client, authorId, menu.CustomId, onClick, onlyAuthor, singleUse)
: base(client, authorId, menu.CustomId, onAction, onlyAuthor, singleUse)
{
Menu = menu;
}

View File

@@ -3,7 +3,7 @@
public abstract class NadekoInteraction
{
private readonly ulong _authorId;
private readonly Func<SocketMessageComponent, Task> _onClick;
private readonly Func<SocketMessageComponent, Task> _onAction;
private readonly bool _onlyAuthor;
public DiscordSocketClient Client { get; }
@@ -17,13 +17,13 @@ public abstract class NadekoInteraction
DiscordSocketClient client,
ulong authorId,
string customId,
Func<SocketMessageComponent, Task> onClick,
Func<SocketMessageComponent, Task> onAction,
bool onlyAuthor,
bool singleUse = true)
{
_authorId = authorId;
_customId = customId;
_onClick = onClick;
_onAction = onAction;
_onlyAuthor = onlyAuthor;
_singleUse = singleUse;
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -61,12 +61,19 @@ public abstract class NadekoInteraction
_ = Task.Run(async () =>
{
_interactionCompletedSource.TrySetResult(true);
await ExecuteOnActionAsync(smc);
if (!smc.HasResponded)
try
{
await smc.DeferAsync();
_interactionCompletedSource.TrySetResult(true);
await ExecuteOnActionAsync(smc);
if (!smc.HasResponded)
{
await smc.DeferAsync();
}
}
catch (Exception ex)
{
Log.Warning(ex, "An exception occured while handling an interaction: {Message}", ex.Message);
}
});
@@ -77,5 +84,5 @@ public abstract class NadekoInteraction
public abstract void AddTo(ComponentBuilder cb);
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
=> _onClick(smc);
=> _onAction(smc);
}

View File

@@ -44,9 +44,8 @@ public partial class ResponseBuilder
var leftButton = new ButtonBuilder()
.WithStyle(ButtonStyle.Primary)
.WithCustomId(BUTTON_LEFT)
.WithDisabled(lastPage == 0)
.WithEmote(InteractionHelpers.ArrowLeft)
.WithDisabled(currentPage <= 0);
.WithDisabled(lastPage == 0 || currentPage <= 0);
var leftBtnInter = new NadekoButtonInteraction(_client,
model.User?.Id ?? 0,
@@ -78,9 +77,8 @@ public partial class ResponseBuilder
var rightButton = new ButtonBuilder()
.WithStyle(ButtonStyle.Primary)
.WithCustomId(BUTTON_RIGHT)
.WithDisabled(lastPage == 0)
.WithEmote(InteractionHelpers.ArrowRight)
.WithDisabled(lastPage == 0 || currentPage > lastPage);
.WithDisabled(lastPage == 0 || currentPage >= lastPage);
var rightBtnInter = new NadekoButtonInteraction(_client,
model.User?.Id ?? 0,
@@ -141,6 +139,7 @@ public partial class ResponseBuilder
.SendMessageAsync(model.Text,
embed: embed.Build(),
components: cb.Build(),
allowedMentions: model.SanitizeMentions,
messageReference: model.MessageReference);
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)