From e355db139e1beca40415e145ef8eda5a88ca02a1 Mon Sep 17 00:00:00 2001 From: stepech <29132060+stepech@users.noreply.github.com> Date: Sun, 1 May 2022 15:51:40 +0200 Subject: [PATCH 1/6] polls: Remove reaction handler --- .../EventHandlers/PollReactionsHandler.cs | 55 ------------------- src/HonzaBotner/Startup.cs | 1 - 2 files changed, 56 deletions(-) delete mode 100644 src/HonzaBotner.Discord.Services/EventHandlers/PollReactionsHandler.cs diff --git a/src/HonzaBotner.Discord.Services/EventHandlers/PollReactionsHandler.cs b/src/HonzaBotner.Discord.Services/EventHandlers/PollReactionsHandler.cs deleted file mode 100644 index 27f141d3..00000000 --- a/src/HonzaBotner.Discord.Services/EventHandlers/PollReactionsHandler.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using DSharpPlus.Entities; -using DSharpPlus.EventArgs; -using HonzaBotner.Discord.EventHandler; -using Microsoft.Extensions.Logging; - -namespace HonzaBotner.Discord.Services.EventHandlers; - -public class PollReactionsHandler : IEventHandler -{ - - private readonly ILogger _logger; - - public PollReactionsHandler(ILogger logger) - { - _logger = logger; - } - - public Task Handle(MessageReactionAddEventArgs args) - { - if (args.User.IsBot) return Task.FromResult(EventHandlerResult.Continue); - _ = Task.Run(() => HandleAsync(args)); - return Task.FromResult(EventHandlerResult.Continue); - } - - private async Task HandleAsync(MessageReactionAddEventArgs args) - { - DiscordMessage message; - try - { - message = await args.Channel.GetMessageAsync(args.Message.Id); - } - catch (Exception e) - { - _logger.LogWarning(e, - "Failed while fetching message {MessageId} in channel {ChannelId} to check poll reactions", - args.Message.Id, args.Channel.Id - ); - return; - } - - if (!message.Author.IsCurrent - || (message.Embeds?.Count.Equals(0) ?? true) - || !(message.Embeds[0].Footer?.Text.EndsWith("Poll") ?? false)) - { - return; - } - - if (message.Reactions.FirstOrDefault(x => x.Emoji == args.Emoji)?.IsMe ?? false) return; - - await args.Message.DeleteReactionAsync(args.Emoji, args.User); - } -} diff --git a/src/HonzaBotner/Startup.cs b/src/HonzaBotner/Startup.cs index af093e84..fe7867ec 100644 --- a/src/HonzaBotner/Startup.cs +++ b/src/HonzaBotner/Startup.cs @@ -79,7 +79,6 @@ public void ConfigureServices(IServiceCollection services) .AddEventHandler() .AddEventHandler() .AddEventHandler() - .AddEventHandler(EventHandlerPriority.Low) .AddEventHandler(EventHandlerPriority.High) .AddEventHandler(EventHandlerPriority.Urgent) .AddEventHandler(EventHandlerPriority.Urgent) From c8ae9ba9ab20f0c84cc938a4341a8cf33ef5a45f Mon Sep 17 00:00:00 2001 From: stepech <29132060+stepech@users.noreply.github.com> Date: Mon, 2 May 2022 00:45:30 +0200 Subject: [PATCH 2/6] poll: Rough fix for reaction's disappearing --- .../Commands/PollCommands.cs | 24 ++++++-- .../Commands/Polls/AbcPoll.cs | 60 ++++++++++++++++++- .../Commands/Polls/Poll.cs | 52 ++++++---------- .../Commands/Polls/YesNoPoll.cs | 11 ++-- 4 files changed, 100 insertions(+), 47 deletions(-) diff --git a/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs b/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs index 2faf5838..d4c5f158 100644 --- a/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs +++ b/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs @@ -22,11 +22,14 @@ public class PollCommands : BaseCommandModule private readonly CommonCommandOptions _options; private readonly ILogger _logger; + private readonly IGuildProvider _guildProvider; - public PollCommands(IOptions options, ILogger logger) + public PollCommands(IOptions options, ILogger logger, + IGuildProvider guildProvider) { _options = options.Value; _logger = logger; + _guildProvider = guildProvider; } [GroupCommand] @@ -95,6 +98,7 @@ private async Task CreateDefaultPollAsync(CommandContext ctx, string question, L catch (ArgumentException e) { await ctx.RespondAsync(e.Message); + _logger.LogError(e, ""); } catch (Exception e) { @@ -146,10 +150,20 @@ public async Task AddPollOptionAsync( return; } - DiscordRole modRole = (await ctx.Client.GetGuildAsync(ctx.Guild.Id)).GetRole(_options.ModRoleId); - AbcPoll poll = new(originalMessage); + DiscordRole modRole = (await _guildProvider.GetCurrentGuildAsync()).GetRole(_options.ModRoleId); + AbcPoll poll; + try + { + poll = new AbcPoll(await (await ctx.Client.GetChannelAsync(ctx.Channel.Id)).GetMessageAsync(ctx.Message.ReferencedMessage.Id)); + } + catch (Exception e) + { + await PollHelpAsync(ctx); + _logger.LogError(e, ""); + return; + } - if (poll.AuthorMention != ctx.Member.Mention && !ctx.Member.Roles.Contains(modRole)) + if (poll.AuthorMention != ctx.Member?.Mention && !(ctx.Member?.Roles.Contains(modRole) ?? false)) { await ctx.RespondAsync("You are not authorized to edit this poll"); return; @@ -157,7 +171,7 @@ public async Task AddPollOptionAsync( try { - await new AbcPoll(originalMessage).AddOptionsAsync(ctx.Client, options.ToList()); + await poll.AddOptionsAsync(ctx.Client, options); await ctx.Message.CreateReactionAsync(DiscordEmoji.FromName(ctx.Client, ":+1:")); } catch (ArgumentException e) diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs index 46b6e132..faa08059 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs @@ -1,5 +1,10 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DSharpPlus; using DSharpPlus.Entities; +using HonzaBotner.Discord.Services.Extensions; namespace HonzaBotner.Discord.Services.Commands.Polls; @@ -7,7 +12,7 @@ public class AbcPoll : Poll { public override string PollType => "AbcPoll"; - public override List OptionsEmoji => new() + protected override List OptionsEmoji => new() { ":regional_indicator_a:", ":regional_indicator_b:", @@ -35,4 +40,55 @@ public AbcPoll(string authorMention, string question, List options) public AbcPoll(DiscordMessage message) : base(message) { } + + public async Task AddOptionsAsync(DiscordClient client, IEnumerable newOptions) + { + if (ExistingPollMessage == null) + { + throw new InvalidOperationException("You can edit only poll constructed from sent message."); + } + + NewChoices = newOptions.ToList(); + + List emojisToAdd = OptionsEmoji; + emojisToAdd.RemoveAll(emoji => + ExistingPollMessage.Reactions.Select(rect => rect.Emoji).Contains(DiscordEmoji.FromName(client, emoji))); + + emojisToAdd = emojisToAdd.GetRange( + 0, Math.Min( + Math.Min( + emojisToAdd.Count, + 20 - (ExistingPollMessage.Reactions.Count <= 20 ? ExistingPollMessage.Reactions.Count : 20)), + NewChoices.Count)); + NewChoices = NewChoices.GetRange(0, Math.Min(emojisToAdd.Count, NewChoices.Count)); + + + + await ExistingPollMessage + .ModifyAsync(Modify(client, ExistingPollMessage.Channel.Guild, ExistingPollMessage.Embeds[0], emojisToAdd)); + + Task _ = Task.Run(async () => { await AddReactionsAsync(client, ExistingPollMessage, emojisToAdd); }); + } + + private DiscordEmbed Modify(DiscordClient client, DiscordGuild guild, DiscordEmbed original, List emojisToAdd) + { + if (NewChoices.Count + original.Fields.Count > OptionsEmoji.Count) + { + throw new ArgumentException($"Too many options. Maximum options is {OptionsEmoji.Count}."); + } + + DiscordEmbedBuilder builder = new (original); + + NewChoices.Zip(emojisToAdd).ToList().ForEach(pair => + { + (string? answer, string? emojiName) = pair; + + builder.AddField( + DiscordEmoji.FromName(client, emojiName).ToString(), + answer.RemoveDiscordMentions(guild), + true); + }); + + return builder.WithFooter(PollType).Build(); + } } diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs index d5a7e6e0..3891224f 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs @@ -10,41 +10,37 @@ namespace HonzaBotner.Discord.Services.Commands.Polls; public abstract class Poll { - public abstract List OptionsEmoji { get; } + protected abstract List OptionsEmoji { get; } public abstract string PollType { get; } - - public virtual List ActiveEmojis + protected virtual List UsedEmojis { - get => OptionsEmoji.GetRange(0, _choices.Count); + get => OptionsEmoji.GetRange(0, NewChoices.Count); } + protected List NewChoices; + public readonly string AuthorMention; - private readonly List _choices; - private readonly DiscordMessage? _existingPollMessage; - private readonly string _question; + protected readonly DiscordMessage? ExistingPollMessage; + protected readonly string Question; protected Poll(string authorMention, string question, List? options = null) { AuthorMention = authorMention; - _question = question; - _choices = options ?? new List(); + Question = question; + NewChoices = options ?? new List(); } protected Poll(DiscordMessage originalMessage) { - _existingPollMessage = originalMessage; - DiscordEmbed originalPoll = _existingPollMessage.Embeds[0]; + ExistingPollMessage = originalMessage; + DiscordEmbed originalPoll = ExistingPollMessage.Embeds[0]; // Extract original author Mention via discord's mention format <@!123456789>. AuthorMention = originalPoll.Description.Substring( originalPoll.Description.LastIndexOf("<", StringComparison.Ordinal) ); - _choices = originalPoll.Fields? - .Select(ef => ef.Value) - .ToList() ?? new List(); - - _question = originalPoll.Title; + Question = originalPoll.Title; } public async Task PostAsync(DiscordClient client, DiscordChannel channel) @@ -54,23 +50,9 @@ public async Task PostAsync(DiscordClient client, DiscordChannel channel) Task _ = Task.Run(async () => { await AddReactionsAsync(client, pollMessage); }); } - public virtual async Task AddOptionsAsync(DiscordClient client, IEnumerable newOptions) - { - if (_existingPollMessage == null) - { - throw new InvalidOperationException("You can edit only poll constructed from sent message."); - } - - _choices.AddRange(newOptions); - - await _existingPollMessage.ModifyAsync(Build(client, _existingPollMessage.Channel.Guild)); - - Task _ = Task.Run(async () => { await AddReactionsAsync(client, _existingPollMessage); }); - } - - protected async Task AddReactionsAsync(DiscordClient client, DiscordMessage message) + protected async Task AddReactionsAsync(DiscordClient client, DiscordMessage message, List? reactions = null) { - foreach (string reaction in ActiveEmojis) + foreach (string reaction in reactions ?? UsedEmojis) { await message.CreateReactionAsync(DiscordEmoji.FromName(client, reaction)); } @@ -78,18 +60,18 @@ protected async Task AddReactionsAsync(DiscordClient client, DiscordMessage mess private DiscordEmbed Build(DiscordClient client, DiscordGuild guild) { - if (_choices.Count > OptionsEmoji.Count) + if (NewChoices.Count > OptionsEmoji.Count) { throw new ArgumentException($"Too many options. Maximum options is {OptionsEmoji.Count}."); } DiscordEmbedBuilder builder = new() { - Title = _question.RemoveDiscordMentions(guild), + Title = Question.RemoveDiscordMentions(guild), Description = "By: " + AuthorMention // Author needs to stay as the last argument }; - _choices.Zip(ActiveEmojis).ToList().ForEach(pair => + NewChoices.Zip(UsedEmojis).ToList().ForEach(pair => { (string? answer, string? emojiName) = pair; diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs index 42a36b47..a78a28c9 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs @@ -9,8 +9,12 @@ namespace HonzaBotner.Discord.Services.Commands.Polls; public class YesNoPoll : Poll { public override string PollType => "YesNoPoll"; - public override List OptionsEmoji => new() { ":+1:", ":-1:" }; - public override List ActiveEmojis => OptionsEmoji; + protected override List OptionsEmoji => new() { ":+1:", ":-1:" }; + + protected override List UsedEmojis + { + get => OptionsEmoji; + } public YesNoPoll(string authorMention, string question) : base(authorMention, question) { @@ -19,7 +23,4 @@ public YesNoPoll(string authorMention, string question) : base(authorMention, qu public YesNoPoll(DiscordMessage message) : base(message) { } - - public override Task AddOptionsAsync(DiscordClient client, IEnumerable newOptions) => - throw new ArgumentException($"Adding options is disabled for {PollType}"); } From 59f2002be8698e11111e823f64800e6ce5f8aa70 Mon Sep 17 00:00:00 2001 From: stepech <29132060+stepech@users.noreply.github.com> Date: Mon, 2 May 2022 01:16:01 +0200 Subject: [PATCH 3/6] Polls: Clean up code --- .../Commands/PollCommands.cs | 43 ++++++++----------- .../Commands/Polls/AbcPoll.cs | 14 +++--- .../Commands/Polls/Poll.cs | 17 +++++++- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs b/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs index d4c5f158..a6f15ac4 100644 --- a/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs +++ b/src/HonzaBotner.Discord.Services/Commands/PollCommands.cs @@ -86,28 +86,27 @@ public async Task AbcPollCommandAsync( private async Task CreateDefaultPollAsync(CommandContext ctx, string question, List? answers = null) { - Poll poll = answers is null - ? new YesNoPoll(ctx.Member.Mention, question) - : new AbcPoll(ctx.Member.Mention, question, answers); - try { + Poll poll = answers is null + ? new YesNoPoll(ctx.Member.Mention, question) + : new AbcPoll(ctx.Member.Mention, question, answers); + await poll.PostAsync(ctx.Client, ctx.Channel); await ctx.Message.DeleteAsync(); } - catch (ArgumentException e) + catch (PollException e) { await ctx.RespondAsync(e.Message); - _logger.LogError(e, ""); } catch (Exception e) { await ctx.RespondAsync(PollErrorMessage); - _logger.LogWarning(e, "Failed to create new {PollType}", poll.PollType); + _logger.LogWarning(e, "Failed to create new Poll"); } } - private async Task PollHelpAsync(CommandContext ctx) + private static async Task PollHelpAsync(CommandContext ctx) { DiscordEmbed embed = new DiscordEmbedBuilder() .WithTitle("Polls") @@ -150,31 +149,23 @@ public async Task AddPollOptionAsync( return; } - DiscordRole modRole = (await _guildProvider.GetCurrentGuildAsync()).GetRole(_options.ModRoleId); - AbcPoll poll; try { - poll = new AbcPoll(await (await ctx.Client.GetChannelAsync(ctx.Channel.Id)).GetMessageAsync(ctx.Message.ReferencedMessage.Id)); - } - catch (Exception e) - { - await PollHelpAsync(ctx); - _logger.LogError(e, ""); - return; - } + DiscordRole modRole = (await _guildProvider.GetCurrentGuildAsync()).GetRole(_options.ModRoleId); - if (poll.AuthorMention != ctx.Member?.Mention && !(ctx.Member?.Roles.Contains(modRole) ?? false)) - { - await ctx.RespondAsync("You are not authorized to edit this poll"); - return; - } + // I am sorry, due to DSharpPlus' caching logic, this mess is necessary + AbcPoll poll = new (await (await ctx.Client.GetChannelAsync(ctx.Channel.Id)).GetMessageAsync(ctx.Message.ReferencedMessage.Id)); + + if (poll.AuthorMention != ctx.Member?.Mention && !(ctx.Member?.Roles.Contains(modRole) ?? false)) + { + await ctx.RespondAsync("You are not authorized to edit this poll"); + return; + } - try - { await poll.AddOptionsAsync(ctx.Client, options); await ctx.Message.CreateReactionAsync(DiscordEmoji.FromName(ctx.Client, ":+1:")); } - catch (ArgumentException e) + catch (PollException e) { await ctx.RespondAsync(e.Message); } diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs index faa08059..c95ca610 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs @@ -43,13 +43,18 @@ public AbcPoll(DiscordMessage message) : base(message) public async Task AddOptionsAsync(DiscordClient client, IEnumerable newOptions) { - if (ExistingPollMessage == null) + if (ExistingPollMessage is null) { throw new InvalidOperationException("You can edit only poll constructed from sent message."); } NewChoices = newOptions.ToList(); + if (NewChoices.Count + ExistingPollMessage.Embeds[0].Fields.Count > OptionsEmoji.Count) + { + throw new PollException($"Too many options. Maximum options is {OptionsEmoji.Count}."); + } + List emojisToAdd = OptionsEmoji; emojisToAdd.RemoveAll(emoji => ExistingPollMessage.Reactions.Select(rect => rect.Emoji).Contains(DiscordEmoji.FromName(client, emoji))); @@ -60,7 +65,7 @@ public async Task AddOptionsAsync(DiscordClient client, IEnumerable newO emojisToAdd.Count, 20 - (ExistingPollMessage.Reactions.Count <= 20 ? ExistingPollMessage.Reactions.Count : 20)), NewChoices.Count)); - NewChoices = NewChoices.GetRange(0, Math.Min(emojisToAdd.Count, NewChoices.Count)); + NewChoices = NewChoices.GetRange(0, emojisToAdd.Count); @@ -72,11 +77,6 @@ await ExistingPollMessage private DiscordEmbed Modify(DiscordClient client, DiscordGuild guild, DiscordEmbed original, List emojisToAdd) { - if (NewChoices.Count + original.Fields.Count > OptionsEmoji.Count) - { - throw new ArgumentException($"Too many options. Maximum options is {OptionsEmoji.Count}."); - } - DiscordEmbedBuilder builder = new (original); NewChoices.Zip(emojisToAdd).ToList().ForEach(pair => diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs index 3891224f..ea972de0 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs @@ -62,7 +62,7 @@ private DiscordEmbed Build(DiscordClient client, DiscordGuild guild) { if (NewChoices.Count > OptionsEmoji.Count) { - throw new ArgumentException($"Too many options. Maximum options is {OptionsEmoji.Count}."); + throw new PollException($"Too many options. Maximum options is {OptionsEmoji.Count}."); } DiscordEmbedBuilder builder = new() @@ -84,3 +84,18 @@ private DiscordEmbed Build(DiscordClient client, DiscordGuild guild) return builder.WithFooter(PollType).Build(); } } + +[Serializable] +public class PollException : Exception +{ + public PollException () + {} + + public PollException (string message) + : base(message) + {} + + public PollException (string message, Exception innerException) + : base (message, innerException) + {} +} From 460cce32d0749dfcaa1b80219889f7d1caaf217d Mon Sep 17 00:00:00 2001 From: stepech <29132060+stepech@users.noreply.github.com> Date: Mon, 2 May 2022 01:51:49 +0200 Subject: [PATCH 4/6] polls: Cleanup imports --- src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs index a78a28c9..c2d4e902 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/YesNoPoll.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using DSharpPlus; +using System.Collections.Generic; using DSharpPlus.Entities; namespace HonzaBotner.Discord.Services.Commands.Polls; From c09b81dd92649161d6f3a6352e74d410fa1ba5c3 Mon Sep 17 00:00:00 2001 From: stepech <29132060+stepech@users.noreply.github.com> Date: Thu, 5 May 2022 20:54:16 +0200 Subject: [PATCH 5/6] polls: Separate PollException, clarify code --- .../Commands/Polls/AbcPoll.cs | 26 ++++++++++++------- .../Commands/Polls/Poll.cs | 15 ----------- .../Commands/Polls/PollException.cs | 17 ++++++++++++ 3 files changed, 33 insertions(+), 25 deletions(-) create mode 100644 src/HonzaBotner.Discord.Services/Commands/Polls/PollException.cs diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs index c95ca610..5befc37c 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs @@ -43,6 +43,7 @@ public AbcPoll(DiscordMessage message) : base(message) public async Task AddOptionsAsync(DiscordClient client, IEnumerable newOptions) { + const int reactionCap = 20; // Max amount of reactions present on a message, lower than Discord provided, in case some trolls block bot's reactions if (ExistingPollMessage is null) { throw new InvalidOperationException("You can edit only poll constructed from sent message."); @@ -50,23 +51,28 @@ public async Task AddOptionsAsync(DiscordClient client, IEnumerable newO NewChoices = newOptions.ToList(); - if (NewChoices.Count + ExistingPollMessage.Embeds[0].Fields.Count > OptionsEmoji.Count) - { - throw new PollException($"Too many options. Maximum options is {OptionsEmoji.Count}."); - } - List emojisToAdd = OptionsEmoji; + + // Look at existing message and allow only emojis which are not yet present on that message. emojisToAdd.RemoveAll(emoji => ExistingPollMessage.Reactions.Select(rect => rect.Emoji).Contains(DiscordEmoji.FromName(client, emoji))); emojisToAdd = emojisToAdd.GetRange( - 0, Math.Min( - Math.Min( - emojisToAdd.Count, - 20 - (ExistingPollMessage.Reactions.Count <= 20 ? ExistingPollMessage.Reactions.Count : 20)), + 0, + // Allow only so many reactions, that we don't cross 20 reactions on existing message + Math.Min(Math.Min(reactionCap - Math.Min(ExistingPollMessage.Reactions.Count, reactionCap), + // Take above reaction capacity, and lower it optionally to number of emojis which we are able to react with + emojisToAdd.Count), + // Take the above number and cap it at total new choices we want to add (can be lower or equal to real choices number) NewChoices.Count)); + + // The new options count will be equal or lower than total options added, based on available emojis NewChoices = NewChoices.GetRange(0, emojisToAdd.Count); + if (NewChoices.Count == 0) + { + throw new PollException($"Total number of reactions on a message can't be greater than {reactionCap}"); + } await ExistingPollMessage @@ -75,7 +81,7 @@ await ExistingPollMessage Task _ = Task.Run(async () => { await AddReactionsAsync(client, ExistingPollMessage, emojisToAdd); }); } - private DiscordEmbed Modify(DiscordClient client, DiscordGuild guild, DiscordEmbed original, List emojisToAdd) + private DiscordEmbed Modify(DiscordClient client, DiscordGuild guild, DiscordEmbed original, IEnumerable emojisToAdd) { DiscordEmbedBuilder builder = new (original); diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs index ea972de0..28403812 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/Poll.cs @@ -84,18 +84,3 @@ private DiscordEmbed Build(DiscordClient client, DiscordGuild guild) return builder.WithFooter(PollType).Build(); } } - -[Serializable] -public class PollException : Exception -{ - public PollException () - {} - - public PollException (string message) - : base(message) - {} - - public PollException (string message, Exception innerException) - : base (message, innerException) - {} -} diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/PollException.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/PollException.cs new file mode 100644 index 00000000..835256cb --- /dev/null +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/PollException.cs @@ -0,0 +1,17 @@ +using System; + +namespace HonzaBotner.Discord.Services.Commands.Polls; + +public class PollException : Exception +{ + public PollException () + {} + + public PollException (string message) + : base(message) + {} + + public PollException (string message, Exception innerException) + : base (message, innerException) + {} +} From 82b976cee6889659a640d9a864a6dc38403b98a3 Mon Sep 17 00:00:00 2001 From: Honza Bittner Date: Fri, 6 May 2022 20:16:06 +0200 Subject: [PATCH 6/6] Update src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs --- src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs index 5befc37c..a6cf6231 100644 --- a/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs +++ b/src/HonzaBotner.Discord.Services/Commands/Polls/AbcPoll.cs @@ -73,8 +73,6 @@ public async Task AddOptionsAsync(DiscordClient client, IEnumerable newO { throw new PollException($"Total number of reactions on a message can't be greater than {reactionCap}"); } - - await ExistingPollMessage .ModifyAsync(Modify(client, ExistingPollMessage.Channel.Guild, ExistingPollMessage.Embeds[0], emojisToAdd));