feat: replace buttons in /configure-channels with select menu

This commit is contained in:
sam 2024-11-05 16:20:24 +01:00
parent e7eaa9f13a
commit f0fcfd7bd3
Signed by: sam
GPG key ID: 5F3C3C1B3166639D
4 changed files with 186 additions and 267 deletions

View file

@ -222,6 +222,93 @@ public class ChannelCommands(
return Result.Success;
}
public static IStringSelectComponent LogTypeSelect =>
new StringSelectComponent(
CustomID: CustomIDHelpers.CreateSelectMenuID("select-log-type"),
MinValues: 1,
MaxValues: 1,
Options:
[
new SelectOption(
Label: "Server changes",
Value: nameof(LogChannelType.GuildUpdate)
),
new SelectOption(
Label: "Emoji changes",
Value: nameof(LogChannelType.GuildEmojisUpdate)
),
new SelectOption(Label: "New roles", Value: nameof(LogChannelType.GuildRoleCreate)),
new SelectOption(
Label: "Edited roles",
Value: nameof(LogChannelType.GuildRoleUpdate)
),
new SelectOption(
Label: "Deleted roles",
Value: nameof(LogChannelType.GuildRoleDelete)
),
new SelectOption(
Label: "New channels",
Value: nameof(LogChannelType.ChannelCreate)
),
new SelectOption(
Label: "Edited channels",
Value: nameof(LogChannelType.ChannelUpdate)
),
new SelectOption(
Label: "Deleted channels",
Value: nameof(LogChannelType.ChannelDelete)
),
new SelectOption(
Label: "Members joining",
Value: nameof(LogChannelType.GuildMemberAdd)
),
new SelectOption(
Label: "Members leaving",
Value: nameof(LogChannelType.GuildMemberRemove)
),
new SelectOption(
Label: "Member role changes",
Value: nameof(LogChannelType.GuildMemberUpdate)
),
new SelectOption(
Label: "Key role changes",
Value: nameof(LogChannelType.GuildKeyRoleUpdate)
),
new SelectOption(
Label: "Member name changes",
Value: nameof(LogChannelType.GuildMemberNickUpdate)
),
new SelectOption(
Label: "Member avatar changes",
Value: nameof(LogChannelType.GuildMemberAvatarUpdate)
),
new SelectOption(
Label: "Timeouts",
Value: nameof(LogChannelType.GuildMemberTimeout)
),
new SelectOption(Label: "Kicks", Value: nameof(LogChannelType.GuildMemberKick)),
new SelectOption(Label: "Bans", Value: nameof(LogChannelType.GuildBanAdd)),
new SelectOption(Label: "Unbans", Value: nameof(LogChannelType.GuildBanRemove)),
new SelectOption(Label: "New invites", Value: nameof(LogChannelType.InviteCreate)),
new SelectOption(
Label: "Deleted invites",
Value: nameof(LogChannelType.InviteDelete)
),
new SelectOption(
Label: "Edited messages",
Value: nameof(LogChannelType.MessageUpdate)
),
new SelectOption(
Label: "Deleted messages",
Value: nameof(LogChannelType.MessageDelete)
),
new SelectOption(
Label: "Bulk deleted messages",
Value: nameof(LogChannelType.MessageDeleteBulk)
),
]
);
public static (List<IEmbed>, List<IMessageComponent>) BuildRootMenu(
List<IChannel> guildChannels,
IGuild guild,
@ -357,208 +444,9 @@ public class ChannelCommands(
List<IMessageComponent> components =
[
new ActionRowComponent([LogTypeSelect]),
new ActionRowComponent(
[
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Server changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Emoji changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildEmojisUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "New roles",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildRoleCreate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Edited roles",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildRoleUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Deleted roles",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildRoleDelete)
)
),
]
),
new ActionRowComponent(
[
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "New channels",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.ChannelCreate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Edited channels",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.ChannelUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Deleted channels",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.ChannelDelete)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Members joining",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberAdd)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Members leaving",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberRemove)
)
),
]
),
new ActionRowComponent(
[
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Member role changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Key role changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildKeyRoleUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Member name changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberNickUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Member avatar changes",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberAvatarUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Timeouts",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberTimeout)
)
),
]
),
new ActionRowComponent(
[
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Kicks",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildMemberKick)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Bans",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildBanAdd)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Unbans",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.GuildBanRemove)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "New invites",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.InviteCreate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Deleted invites",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.InviteDelete)
)
),
]
),
new ActionRowComponent(
[
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Edited messages",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.MessageUpdate)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Deleted messages",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.MessageDelete)
)
),
new ButtonComponent(
ButtonComponentStyle.Primary,
Label: "Bulk deleted messages",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
nameof(LogChannelType.MessageDeleteBulk)
)
),
new ButtonComponent(
ButtonComponentStyle.Secondary,
Label: "Close",

View file

@ -45,6 +45,103 @@ public class ChannelCommandsComponents(
{
private readonly ILogger _logger = logger.ForContext<ChannelCommandsComponents>();
[SelectMenu("select-log-type")]
[SuppressInteractionResponse(true)]
public async Task<Result> OnMenuSelectionAsync(IReadOnlyList<string> values)
{
if (contextInjection.Context is not IInteractionCommandContext ctx)
throw new CataloggerError("No context");
if (!ctx.TryGetUserID(out var userId))
throw new CataloggerError("No user ID in context");
if (!ctx.Interaction.Message.TryGet(out var msg))
throw new CataloggerError("No message ID in context");
if (!ctx.TryGetGuildID(out var guildId))
throw new CataloggerError("No guild ID in context");
if (!guildCache.TryGet(guildId, out var guild))
throw new CataloggerError("Guild not in cache");
var guildChannels = channelCache.GuildChannels(guildId).ToList();
var guildConfig = await guildRepository.GetAsync(guildId);
var result = await dataService.LeaseDataAsync(msg.ID);
await using var lease = result.GetOrThrow();
if (lease.Data.UserId != userId)
{
return (Result)
await feedbackService.ReplyAsync(
"This is not your configuration menu.",
isEphemeral: true
);
}
var state = values[0];
if (!Enum.TryParse<LogChannelType>(state, out var logChannelType))
throw new CataloggerError($"Invalid config-channels state {state}");
var channelId = WebhookExecutorService.GetDefaultLogChannel(guildConfig, logChannelType);
string? channelMention;
if (channelId is 0)
channelMention = null;
else if (guildChannels.All(c => c.ID != channelId))
channelMention = $"unknown channel {channelId}";
else
channelMention = $"<#{channelId}>";
List<IEmbed> embeds =
[
new Embed(
Title: ChannelCommands.PrettyLogTypeName(logChannelType),
Description: channelMention == null
? "This event is not currently logged.\nTo start logging it somewhere, select a channel below."
: $"This event is currently set to log to {channelMention}."
+ "\nTo change where it is logged, select a channel below."
+ "\nTo disable logging this event entirely, select \"Stop logging\" below.",
Colour: DiscordUtils.Purple
),
];
List<IMessageComponent> components =
[
new ActionRowComponent(
new[]
{
new ChannelSelectComponent(
CustomID: CustomIDHelpers.CreateSelectMenuID("config-channels"),
ChannelTypes: new[] { ChannelType.GuildText }
),
}
),
new ActionRowComponent(
new[]
{
new ButtonComponent(
ButtonComponentStyle.Danger,
Label: "Stop logging",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
"reset"
),
IsDisabled: channelMention == null
),
new ButtonComponent(
ButtonComponentStyle.Secondary,
Label: "Return to menu",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
"return"
)
),
}
),
];
lease.Data = new ChannelCommandData(userId, CurrentPage: state);
return await interactionApi.UpdateMessageAsync(
ctx.Interaction,
new InteractionMessageCallbackData(Embeds: embeds, Components: components)
);
}
[Button("config-channels")]
[SuppressInteractionResponse(true)]
public async Task<Result> OnButtonPressedAsync(string state)
@ -176,71 +273,7 @@ public class ChannelCommandsComponents(
return Result.Success;
}
if (!Enum.TryParse<LogChannelType>(state, out var logChannelType))
throw new CataloggerError($"Invalid config-channels state {state}");
var channelId = WebhookExecutorService.GetDefaultLogChannel(guildConfig, logChannelType);
string? channelMention;
if (channelId is 0)
channelMention = null;
else if (guildChannels.All(c => c.ID != channelId))
channelMention = $"unknown channel {channelId}";
else
channelMention = $"<#{channelId}>";
List<IEmbed> embeds =
[
new Embed(
Title: ChannelCommands.PrettyLogTypeName(logChannelType),
Description: channelMention == null
? "This event is not currently logged.\nTo start logging it somewhere, select a channel below."
: $"This event is currently set to log to {channelMention}."
+ "\nTo change where it is logged, select a channel below."
+ "\nTo disable logging this event entirely, select \"Stop logging\" below.",
Colour: DiscordUtils.Purple
),
];
List<IMessageComponent> components =
[
new ActionRowComponent(
new[]
{
new ChannelSelectComponent(
CustomID: CustomIDHelpers.CreateSelectMenuID("config-channels"),
ChannelTypes: new[] { ChannelType.GuildText }
),
}
),
new ActionRowComponent(
new[]
{
new ButtonComponent(
ButtonComponentStyle.Danger,
Label: "Stop logging",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
"reset"
),
IsDisabled: channelMention == null
),
new ButtonComponent(
ButtonComponentStyle.Secondary,
Label: "Return to menu",
CustomID: CustomIDHelpers.CreateButtonIDWithState(
"config-channels",
"return"
)
),
}
),
];
lease.Data = new ChannelCommandData(userId, CurrentPage: state);
return await interactionApi.UpdateMessageAsync(
ctx.Interaction,
new InteractionMessageCallbackData(Embeds: embeds, Components: components)
);
return Result.Success;
}
[SelectMenu("config-channels")]

View file

@ -13,7 +13,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System.Diagnostics.CodeAnalysis;
using Catalogger.Backend.Extensions;
using LazyCache;
using Remora.Discord.API.Abstractions.Objects;

View file

@ -15,7 +15,6 @@
using Catalogger.Backend.Database.Models;
using Dapper;
using Npgsql.Replication;
using Remora.Discord.API;
using Remora.Rest.Core;