mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
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:
@@ -4,7 +4,6 @@ using NadekoBot.Modules.Help.Services;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Nadeko.Common.Medusa;
|
using Nadeko.Common.Medusa;
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Help;
|
namespace NadekoBot.Modules.Help;
|
||||||
|
|
||||||
@@ -89,7 +88,7 @@ public sealed partial class Help : NadekoModule<HelpService>
|
|||||||
|
|
||||||
var menu = new SelectMenuBuilder()
|
var menu = new SelectMenuBuilder()
|
||||||
.WithPlaceholder("Select a module to see its commands")
|
.WithPlaceholder("Select a module to see its commands")
|
||||||
.WithCustomId("modules");
|
.WithCustomId("cmds:modules_select");
|
||||||
|
|
||||||
foreach (var m in topLevelModules)
|
foreach (var m in topLevelModules)
|
||||||
menu.AddOption(m.Name, m.Name, GetModuleEmoji(m.Name));
|
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();
|
var val = smc.Data.Values.FirstOrDefault();
|
||||||
if (val is null)
|
if (val is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await Commands(val);
|
await Commands(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -242,10 +241,28 @@ public sealed partial class Help : NadekoModule<HelpService>
|
|||||||
// order by name
|
// order by name
|
||||||
var allowed = new List<CommandInfo>();
|
var allowed = new List<CommandInfo>();
|
||||||
|
|
||||||
foreach (var cmd in _cmds.Commands
|
var mdls = _cmds.Commands
|
||||||
.Where(c => c.Module.GetTopLevelModule()
|
.Where(c => c.Module.GetTopLevelModule()
|
||||||
.Name
|
.Name
|
||||||
.StartsWith(module, StringComparison.InvariantCultureIgnoreCase)))
|
.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,
|
var result = await _perms.CheckPermsAsync(ctx.Guild,
|
||||||
ctx.Channel,
|
ctx.Channel,
|
||||||
@@ -257,6 +274,7 @@ public sealed partial class Help : NadekoModule<HelpService>
|
|||||||
allowed.Add(cmd);
|
allowed.Add(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var cmds = allowed.OrderBy(c => c.Aliases[0])
|
var cmds = allowed.OrderBy(c => c.Aliases[0])
|
||||||
.DistinctBy(x => x.Aliases[0])
|
.DistinctBy(x => x.Aliases[0])
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -296,55 +314,97 @@ public sealed partial class Help : NadekoModule<HelpService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cnt = 0;
|
var sb = new SelectMenuBuilder()
|
||||||
var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray();
|
.WithCustomId("cmds:submodule_select")
|
||||||
|
.WithPlaceholder("Select a submodule to see detailed commands");
|
||||||
|
|
||||||
|
var groups = cmdsWithGroup.ToArray();
|
||||||
var embed = _sender.CreateEmbed().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
foreach (var g in groups)
|
foreach (var g in groups)
|
||||||
{
|
{
|
||||||
var last = g.Count();
|
sb.AddOption(g.Key, g.Key);
|
||||||
for (var i = 0; i < last; i++)
|
var transformed = g
|
||||||
{
|
.Select(x =>
|
||||||
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)
|
||||||
//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]}";
|
||||||
{
|
}
|
||||||
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)));
|
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)
|
private async Task Group(ModuleInfo group)
|
||||||
{
|
{
|
||||||
var eb = _sender.CreateEmbed()
|
var menu = new SelectMenuBuilder()
|
||||||
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
|
.WithCustomId("cmds:group_select")
|
||||||
.WithOkColor();
|
.WithPlaceholder("Select a command to see its details");
|
||||||
|
|
||||||
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
|
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
|
||||||
{
|
{
|
||||||
string cmdName;
|
menu.AddOption(prefix + cmd.Aliases[0], cmd.Aliases[0]);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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]
|
[Cmd]
|
||||||
@@ -364,12 +424,9 @@ public sealed partial class Help : NadekoModule<HelpService>
|
|||||||
|
|
||||||
var group = _cmds.Modules
|
var group = _cmds.Modules
|
||||||
.SelectMany(x => x.Submodules)
|
.SelectMany(x => x.Submodules)
|
||||||
.FirstOrDefault(x => string.Equals(x.Name?.Replace("Commands", string.Empty),
|
.FirstOrDefault(x => string.Equals(x.Group,
|
||||||
fail,
|
fail,
|
||||||
StringComparison.InvariantCultureIgnoreCase)
|
StringComparison.InvariantCultureIgnoreCase));
|
||||||
|| string.Equals(x.Group,
|
|
||||||
fail,
|
|
||||||
StringComparison.InvariantCultureIgnoreCase));
|
|
||||||
|
|
||||||
if (group is not null)
|
if (group is not null)
|
||||||
{
|
{
|
||||||
|
@@ -6,10 +6,10 @@ public sealed class NadekoButtonInteraction : NadekoInteraction
|
|||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
ulong authorId,
|
ulong authorId,
|
||||||
ButtonBuilder button,
|
ButtonBuilder button,
|
||||||
Func<SocketMessageComponent, Task> onClick,
|
Func<SocketMessageComponent, Task> onAction,
|
||||||
bool onlyAuthor,
|
bool onlyAuthor,
|
||||||
bool singleUse = true)
|
bool singleUse = true)
|
||||||
: base(client, authorId, button.CustomId, onClick, onlyAuthor, singleUse)
|
: base(client, authorId, button.CustomId, onAction, onlyAuthor, singleUse)
|
||||||
{
|
{
|
||||||
Button = button;
|
Button = button;
|
||||||
}
|
}
|
||||||
|
@@ -6,10 +6,10 @@ public sealed class NadekoSelectInteraction : NadekoInteraction
|
|||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
ulong authorId,
|
ulong authorId,
|
||||||
SelectMenuBuilder menu,
|
SelectMenuBuilder menu,
|
||||||
Func<SocketMessageComponent, Task> onClick,
|
Func<SocketMessageComponent, Task> onAction,
|
||||||
bool onlyAuthor,
|
bool onlyAuthor,
|
||||||
bool singleUse = true)
|
bool singleUse = true)
|
||||||
: base(client, authorId, menu.CustomId, onClick, onlyAuthor, singleUse)
|
: base(client, authorId, menu.CustomId, onAction, onlyAuthor, singleUse)
|
||||||
{
|
{
|
||||||
Menu = menu;
|
Menu = menu;
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
public abstract class NadekoInteraction
|
public abstract class NadekoInteraction
|
||||||
{
|
{
|
||||||
private readonly ulong _authorId;
|
private readonly ulong _authorId;
|
||||||
private readonly Func<SocketMessageComponent, Task> _onClick;
|
private readonly Func<SocketMessageComponent, Task> _onAction;
|
||||||
private readonly bool _onlyAuthor;
|
private readonly bool _onlyAuthor;
|
||||||
public DiscordSocketClient Client { get; }
|
public DiscordSocketClient Client { get; }
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@ public abstract class NadekoInteraction
|
|||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
ulong authorId,
|
ulong authorId,
|
||||||
string customId,
|
string customId,
|
||||||
Func<SocketMessageComponent, Task> onClick,
|
Func<SocketMessageComponent, Task> onAction,
|
||||||
bool onlyAuthor,
|
bool onlyAuthor,
|
||||||
bool singleUse = true)
|
bool singleUse = true)
|
||||||
{
|
{
|
||||||
_authorId = authorId;
|
_authorId = authorId;
|
||||||
_customId = customId;
|
_customId = customId;
|
||||||
_onClick = onClick;
|
_onAction = onAction;
|
||||||
_onlyAuthor = onlyAuthor;
|
_onlyAuthor = onlyAuthor;
|
||||||
_singleUse = singleUse;
|
_singleUse = singleUse;
|
||||||
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
_interactionCompletedSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
@@ -61,12 +61,19 @@ public abstract class NadekoInteraction
|
|||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
_interactionCompletedSource.TrySetResult(true);
|
try
|
||||||
await ExecuteOnActionAsync(smc);
|
|
||||||
|
|
||||||
if (!smc.HasResponded)
|
|
||||||
{
|
{
|
||||||
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 abstract void AddTo(ComponentBuilder cb);
|
||||||
|
|
||||||
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
public Task ExecuteOnActionAsync(SocketMessageComponent smc)
|
||||||
=> _onClick(smc);
|
=> _onAction(smc);
|
||||||
}
|
}
|
@@ -44,9 +44,8 @@ public partial class ResponseBuilder
|
|||||||
var leftButton = new ButtonBuilder()
|
var leftButton = new ButtonBuilder()
|
||||||
.WithStyle(ButtonStyle.Primary)
|
.WithStyle(ButtonStyle.Primary)
|
||||||
.WithCustomId(BUTTON_LEFT)
|
.WithCustomId(BUTTON_LEFT)
|
||||||
.WithDisabled(lastPage == 0)
|
|
||||||
.WithEmote(InteractionHelpers.ArrowLeft)
|
.WithEmote(InteractionHelpers.ArrowLeft)
|
||||||
.WithDisabled(currentPage <= 0);
|
.WithDisabled(lastPage == 0 || currentPage <= 0);
|
||||||
|
|
||||||
var leftBtnInter = new NadekoButtonInteraction(_client,
|
var leftBtnInter = new NadekoButtonInteraction(_client,
|
||||||
model.User?.Id ?? 0,
|
model.User?.Id ?? 0,
|
||||||
@@ -78,9 +77,8 @@ public partial class ResponseBuilder
|
|||||||
var rightButton = new ButtonBuilder()
|
var rightButton = new ButtonBuilder()
|
||||||
.WithStyle(ButtonStyle.Primary)
|
.WithStyle(ButtonStyle.Primary)
|
||||||
.WithCustomId(BUTTON_RIGHT)
|
.WithCustomId(BUTTON_RIGHT)
|
||||||
.WithDisabled(lastPage == 0)
|
|
||||||
.WithEmote(InteractionHelpers.ArrowRight)
|
.WithEmote(InteractionHelpers.ArrowRight)
|
||||||
.WithDisabled(lastPage == 0 || currentPage > lastPage);
|
.WithDisabled(lastPage == 0 || currentPage >= lastPage);
|
||||||
|
|
||||||
var rightBtnInter = new NadekoButtonInteraction(_client,
|
var rightBtnInter = new NadekoButtonInteraction(_client,
|
||||||
model.User?.Id ?? 0,
|
model.User?.Id ?? 0,
|
||||||
@@ -141,6 +139,7 @@ public partial class ResponseBuilder
|
|||||||
.SendMessageAsync(model.Text,
|
.SendMessageAsync(model.Text,
|
||||||
embed: embed.Build(),
|
embed: embed.Build(),
|
||||||
components: cb.Build(),
|
components: cb.Build(),
|
||||||
|
allowedMentions: model.SanitizeMentions,
|
||||||
messageReference: model.MessageReference);
|
messageReference: model.MessageReference);
|
||||||
|
|
||||||
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)
|
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)
|
||||||
|
Reference in New Issue
Block a user