// Copyright (C) 2021-present sam (starshines.gay) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . using System.ComponentModel; using Catalogger.Backend.Cache; using Catalogger.Backend.Cache.InMemoryCache; using Catalogger.Backend.Database.Repositories; using Catalogger.Backend.Extensions; using Remora.Commands.Attributes; using Remora.Commands.Groups; using Remora.Discord.API; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.Commands.Feedback.Services; using Remora.Discord.Commands.Services; using Remora.Discord.Pagination.Extensions; using Remora.Rest.Core; using IResult = Remora.Results.IResult; namespace Catalogger.Backend.Bot.Commands; [Group("ignored-users")] [Description("Manage users ignored for logging.")] public class IgnoreUserCommands( GuildRepository guildRepository, GuildCache guildCache, IMemberCache memberCache, UserCache userCache, ContextInjectionService contextInjection, FeedbackService feedbackService ) : CommandGroup { [Command("add")] [Description("Add a user to the list of ignored users.")] public async Task AddIgnoredUserAsync([Description("The user to ignore")] IUser user) { var (_, guildId) = contextInjection.GetUserAndGuild(); var guildConfig = await guildRepository.GetAsync(guildId); if (guildConfig.Channels.IgnoredUsers.Contains(user.ID.Value)) return await feedbackService.ReplyAsync( "That user is already being ignored.", isEphemeral: true ); guildConfig.Channels.IgnoredUsers.Add(user.ID.Value); await guildRepository.UpdateChannelConfigAsync(guildId, guildConfig.Channels); return await feedbackService.ReplyAsync( $"Successfully added {user.PrettyFormat()} to the list of ignored users." ); } [Command("remove")] [Description("Remove a user from the list of ignored users.")] public async Task RemoveIgnoredUserAsync( [Description("The user to stop ignoring")] IUser user ) { var (_, guildId) = contextInjection.GetUserAndGuild(); var guildConfig = await guildRepository.GetAsync(guildId); if (!guildConfig.Channels.IgnoredUsers.Contains(user.ID.Value)) return await feedbackService.ReplyAsync( "That user is already not ignored.", isEphemeral: true ); guildConfig.Channels.IgnoredUsers.Remove(user.ID.Value); await guildRepository.UpdateChannelConfigAsync(guildId, guildConfig.Channels); return await feedbackService.ReplyAsync( $"Successfully removed {user.PrettyFormat()} from the list of ignored users." ); } [Command("list")] [Description("List currently ignored users.")] public async Task ListIgnoredUsersAsync() { var (userId, guildId) = contextInjection.GetUserAndGuild(); if (!guildCache.TryGet(guildId, out var guild)) throw new CataloggerError("Guild was not cached"); var guildConfig = await guildRepository.GetAsync(guildId); if (guildConfig.Channels.IgnoredUsers.Count == 0) return await feedbackService.ReplyAsync("No users are being ignored right now."); var users = new List(); foreach (var id in guildConfig.Channels.IgnoredUsers) { var user = await TryGetUserAsync(guildId, DiscordSnowflake.New(id)); users.Add(user?.PrettyFormat() ?? $"*(unknown user {id})* <@{id}>"); } return await feedbackService.SendContextualPaginatedMessageAsync( userId, DiscordUtils.PaginateStrings(users, $"Ignored users for {guild.Name} ({users.Count})") ); } private async Task TryGetUserAsync(Snowflake guildId, Snowflake userId) => (await memberCache.TryGetAsync(guildId, userId))?.User.Value ?? await userCache.GetUserAsync(userId); }