diff --git a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs index 62834ebf3..04f4f6884 100644 --- a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs +++ b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs @@ -231,7 +231,6 @@ namespace Discord { private string _name; private string _value; - private EmbedField _field; public const int MaxFieldNameLength = 256; public const int MaxFieldValueLength = 1024; diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs index 52df187f8..931bacab2 100644 --- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs +++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -23,7 +23,7 @@ namespace Discord /// Removes all reactions from this message. Task RemoveAllReactionsAsync(RequestOptions options = null); /// Gets all users that reacted to a message with a given emote - Task> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null); + IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null); /// Transforms this message's text into a human readable form by resolving its tags. string Resolve( diff --git a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs index d70da5632..a0967bb75 100644 --- a/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs +++ b/src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs @@ -1,4 +1,4 @@ -namespace Discord.API.Rest +namespace Discord.API.Rest { internal class GetReactionUsersParams { diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs index 8ae41cc37..08fd2b638 100644 --- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs +++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs @@ -46,13 +46,39 @@ namespace Discord.Rest await client.ApiClient.RemoveAllReactionsAsync(msg.Channel.Id, msg.Id, options); } - public static async Task> GetReactionUsersAsync(IMessage msg, IEmote emote, + public static IAsyncEnumerable> GetReactionUsersAsync(IMessage msg, IEmote emote, Action func, BaseDiscordClient client, RequestOptions options) { var args = new GetReactionUsersParams(); func(args); - string emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name); - return (await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false)).Select(u => RestUser.Create(client, u)).ToImmutableArray(); + + var emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name); + return new PagedAsyncEnumerable( + DiscordConfig.MaxUsersPerBatch, + async (info, ct) => + { + if (info.Position != null) + args.AfterUserId = info.Position.Value; + + var models = await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false); + var builder = ImmutableArray.CreateBuilder(); + + foreach (var model in models) + builder.Add(RestUser.Create(client, model)); + + return builder.ToImmutable(); + }, + nextPage: (info, lastPage) => + { + if (lastPage.Count != DiscordConfig.MaxUsersPerBatch) + return false; + + info.Position = lastPage.OrderBy(u => u.Id).First().Id; + return true; + }, + count: args.Limit.Value + ); + } public static async Task PinAsync(IMessage msg, BaseDiscordClient client, diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs index 0d1f3be2b..a8cb5af00 100644 --- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs +++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs @@ -136,7 +136,7 @@ namespace Discord.Rest => MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options); public Task RemoveAllReactionsAsync(RequestOptions options = null) => MessageHelper.RemoveAllReactionsAsync(this, Discord, options); - public Task> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) + public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create(); }, Discord, options); diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs index 5489ad2bb..29784bc5e 100644 --- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs +++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs @@ -130,7 +130,7 @@ namespace Discord.WebSocket => MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options); public Task RemoveAllReactionsAsync(RequestOptions options = null) => MessageHelper.RemoveAllReactionsAsync(this, Discord, options); - public Task> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) + public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create(); }, Discord, options); public Task PinAsync(RequestOptions options = null)