diff --git a/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs b/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs new file mode 100644 index 0000000..266fed9 --- /dev/null +++ b/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs @@ -0,0 +1,89 @@ +using System.ComponentModel; +using Catalogger.Backend.Cache.InMemoryCache; +using Catalogger.Backend.Database; +using Catalogger.Backend.Database.Queries; +using Catalogger.Backend.Extensions; +using Remora.Commands.Attributes; +using Remora.Commands.Groups; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Objects; +using Remora.Discord.Commands.Attributes; +using Remora.Discord.Commands.Feedback.Services; +using Remora.Discord.Commands.Services; +using Remora.Rest.Core; +using IResult = Remora.Results.IResult; + +namespace Catalogger.Backend.Bot.Commands; + +[Group("key-roles")] +[DiscordDefaultMemberPermissions(DiscordPermission.ManageGuild)] +public class KeyRoleCommands( + DatabaseContext db, + ContextInjectionService contextInjection, + IFeedbackService feedbackService, + GuildCache guildCache, + RoleCache roleCache) : CommandGroup +{ + [Command("list")] + [Description("List this server's key roles.")] + public async Task ListKeyRolesAsync() + { + var (_, guildId) = contextInjection.GetUserAndGuild(); + if (!guildCache.TryGet(guildId, out var guild)) throw new CataloggerError("Guild not in cache"); + var guildRoles = roleCache.GuildRoles(guildId).ToList(); + var guildConfig = await db.GetGuildAsync(guildId); + + if (guildConfig.KeyRoles.Count == 0) + return await feedbackService.SendContextualAsync( + "There are no key roles to list. Add some with `/key-roles add`."); + + var description = string.Join("\n", guildConfig.KeyRoles.Select(id => + { + var role = guildRoles.FirstOrDefault(r => r.ID.Value == id); + return role != null ? $"- {role.Name} <@&{role.ID}>" : $"- unknown role {id}"; + })); + + return await feedbackService.SendContextualEmbedAsync(new Embed( + Title: $"Key roles for {guild.Name}", + Description: description, + Colour: DiscordUtils.Purple)); + } + + [Command("add")] + [Description("Add a new key role.")] + public async Task AddKeyRoleAsync([DiscordTypeHint(TypeHint.Role)] Snowflake roleId) + { + var (_, guildId) = contextInjection.GetUserAndGuild(); + var role = roleCache.GuildRoles(guildId).FirstOrDefault(r => r.ID == roleId); + if (role == null) throw new CataloggerError("Role is not cached"); + + var guildConfig = await db.GetGuildAsync(guildId); + if (guildConfig.KeyRoles.Any(id => role.ID == id)) + return await feedbackService.SendContextualAsync($"{role.Name} is already a key role."); + + guildConfig.KeyRoles.Add(role.ID.Value); + db.Update(guildConfig); + await db.SaveChangesAsync(); + + return await feedbackService.SendContextualAsync($"Added {role.Name} to this server's key roles!"); + } + + [Command("remove")] + [Description("Remove a key role.")] + public async Task RemoveKeyRoleAsync([DiscordTypeHint(TypeHint.Role)] Snowflake roleId) + { + var (_, guildId) = contextInjection.GetUserAndGuild(); + var role = roleCache.GuildRoles(guildId).FirstOrDefault(r => r.ID == roleId); + if (role == null) throw new CataloggerError("Role is not cached"); + + var guildConfig = await db.GetGuildAsync(guildId); + if (guildConfig.KeyRoles.All(id => role.ID != id)) + return await feedbackService.SendContextualAsync($"{role.Name} is already not a key role."); + + guildConfig.KeyRoles.Remove(role.ID.Value); + db.Update(guildConfig); + await db.SaveChangesAsync(); + + return await feedbackService.SendContextualAsync($"Removed {role.Name} from this server's key roles!"); + } +} \ No newline at end of file diff --git a/Catalogger.Backend/Program.cs b/Catalogger.Backend/Program.cs index 0ff4dba..ecbdcce 100644 --- a/Catalogger.Backend/Program.cs +++ b/Catalogger.Backend/Program.cs @@ -45,6 +45,7 @@ builder.Host // Start command tree .WithCommandGroup() .WithCommandGroup() + .WithCommandGroup() // End command tree .Finish() .AddPagination()