Skip to content

Commit

Permalink
Paginate reactions - solved discord-net#1007 (discord-net#1022)
Browse files Browse the repository at this point in the history
* Cleaned up and refactored slightly

* Resolves discord-net#971

* Adds support for default avatars and resolves discord-net#971

* Amendment

* Final amendment

* Paginating reactions

* Amendments based on feedback

* Further amendment based on review

* Final(?) amendment

* Removes default limit and after user id

* Removes fromUserId; cleans up model creation; replaces function with individual parameters
  • Loading branch information
HelpfulStranger999 authored and foxbot committed May 24, 2018
1 parent e764daf commit 79811d0
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/Discord.Net.Core/DiscordConfig.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Reflection;
using System.Reflection;

namespace Discord
{
Expand All @@ -20,6 +20,7 @@ public class DiscordConfig
public const int MaxMessagesPerBatch = 100;
public const int MaxUsersPerBatch = 1000;
public const int MaxGuildsPerBatch = 100;
public const int MaxUserReactionsPerBatch = 100;
public const int MaxAuditLogEntriesPerBatch = 100;

/// <summary> Gets or sets how a request should act in the case of an error, by default. </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand All @@ -23,7 +23,7 @@ public interface IUserMessage : IMessage
/// <summary> Removes all reactions from this message. </summary>
Task RemoveAllReactionsAsync(RequestOptions options = null);
/// <summary> Gets all users that reacted to a message with a given emote </summary>
Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null);
IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null);

/// <summary> Transforms this message's text into a human readable form by resolving its tags. </summary>
string Resolve(
Expand Down
2 changes: 1 addition & 1 deletion src/Discord.Net.Rest/API/Rest/GetReactionUsersParams.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Discord.API.Rest
namespace Discord.API.Rest
{
internal class GetReactionUsersParams
{
Expand Down
4 changes: 2 additions & 2 deletions src/Discord.Net.Rest/DiscordRestApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -618,11 +618,11 @@ public async Task<IReadOnlyCollection<User>> GetReactionUsersAsync(ulong channel
Preconditions.NotNullOrWhitespace(emoji, nameof(emoji));
Preconditions.NotNull(args, nameof(args));
Preconditions.GreaterThan(args.Limit, 0, nameof(args.Limit));
Preconditions.AtMost(args.Limit, DiscordConfig.MaxUsersPerBatch, nameof(args.Limit));
Preconditions.AtMost(args.Limit, DiscordConfig.MaxUserReactionsPerBatch, nameof(args.Limit));
Preconditions.GreaterThan(args.AfterUserId, 0, nameof(args.AfterUserId));
options = RequestOptions.CreateOrClone(options);

int limit = args.Limit.GetValueOrDefault(int.MaxValue);
int limit = args.Limit.GetValueOrDefault(DiscordConfig.MaxUserReactionsPerBatch);
ulong afterUserId = args.AfterUserId.GetValueOrDefault(0);

var ids = new BucketIds(channelId: channelId);
Expand Down
37 changes: 31 additions & 6 deletions src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,38 @@ public static async Task RemoveAllReactionsAsync(IMessage msg, BaseDiscordClient
await client.ApiClient.RemoveAllReactionsAsync(msg.Channel.Id, msg.Id, options);
}

public static async Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IMessage msg, IEmote emote,
Action<GetReactionUsersParams> func, BaseDiscordClient client, RequestOptions options)
public static IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IMessage msg, IEmote emote,
int? limit, 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();
Preconditions.NotNull(emote, nameof(emote));
var emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name);

return new PagedAsyncEnumerable<IUser>(
DiscordConfig.MaxUserReactionsPerBatch,
async (info, ct) =>
{
var args = new GetReactionUsersParams
{
Limit = info.PageSize
};
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);
return models.Select(x => RestUser.Create(client, x)).ToImmutableArray();
},
nextPage: (info, lastPage) =>
{
if (lastPage.Count != DiscordConfig.MaxUsersPerBatch)
return false;
info.Position = lastPage.Max(x => x.Id);
return true;
},
count: limit
);

}

public static async Task PinAsync(IMessage msg, BaseDiscordClient client,
Expand Down
4 changes: 2 additions & 2 deletions src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options
=> MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options);
public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
public Task<IReadOnlyCollection<IUser>> 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<ulong>(); }, Discord, options);
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
=> MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);


public Task PinAsync(RequestOptions options = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options
=> MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options);
public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
public Task<IReadOnlyCollection<IUser>> 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<ulong>(); }, Discord, options);
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
=> MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);

public Task PinAsync(RequestOptions options = null)
=> MessageHelper.PinAsync(this, Discord, options);
Expand Down

0 comments on commit 79811d0

Please sign in to comment.