From 9fd5c6c27e6770f4892132bc1dabd26bb961b855 Mon Sep 17 00:00:00 2001
From: Mihail Gribkov <61027276+Misha-133@users.noreply.github.com>
Date: Sat, 18 Nov 2023 23:57:11 +0300
Subject: [PATCH] [Feature] Super reactions support (#2707)
* super reactions
* add type to `GetReactionUsers` methods
* add `MeBurst`
---
src/Discord.Net.Core/DiscordErrorCode.cs | 1 +
.../Entities/Messages/IMessage.cs | 4 +-
.../Entities/Messages/IReaction.cs | 27 +-
.../Entities/Messages/ReactionMetadata.cs | 54 ++--
.../Entities/Messages/ReactionType.cs | 14 ++
src/Discord.Net.Rest/API/Common/Reaction.cs | 30 ++-
.../API/Common/ReactionCountDetails.cs | 12 +
src/Discord.Net.Rest/DiscordRestApiClient.cs | 6 +-
.../Entities/Messages/MessageHelper.cs | 4 +-
.../Entities/Messages/RestMessage.cs | 13 +-
.../Entities/Messages/RestReaction.cs | 37 ++-
.../Net/Converters/ColorConverter.cs | 27 ++
.../Net/Converters/DiscordContractResolver.cs | 2 +
.../API/Gateway/Reaction.cs | 45 ++--
.../Entities/Messages/SocketMessage.cs | 4 +-
.../Entities/Messages/SocketReaction.cs | 236 ++++++++++--------
16 files changed, 347 insertions(+), 169 deletions(-)
create mode 100644 src/Discord.Net.Core/Entities/Messages/ReactionType.cs
create mode 100644 src/Discord.Net.Rest/API/Common/ReactionCountDetails.cs
create mode 100644 src/Discord.Net.Rest/Net/Converters/ColorConverter.cs
diff --git a/src/Discord.Net.Core/DiscordErrorCode.cs b/src/Discord.Net.Core/DiscordErrorCode.cs
index 5fc71f4b..37e469f5 100644
--- a/src/Discord.Net.Core/DiscordErrorCode.cs
+++ b/src/Discord.Net.Core/DiscordErrorCode.cs
@@ -202,6 +202,7 @@ namespace Discord
#region Reactions (90XXX)
ReactionBlocked = 90001,
+ CannotUseBurstReaction = 90002,
#endregion
#region API Status (130XXX)
diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
index 75cb98b5..034c0e27 100644
--- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
@@ -323,9 +323,11 @@ namespace Discord
/// The emoji that represents the reaction that you wish to get.
/// The number of users to request.
/// The options to be used when sending the request.
+ /// The type of the reaction you wish to get users for.
///
/// Paged collection of users.
///
- IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null);
+ IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null,
+ ReactionType type = ReactionType.Normal);
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/IReaction.cs b/src/Discord.Net.Core/Entities/Messages/IReaction.cs
index b7d7128c..de591648 100644
--- a/src/Discord.Net.Core/Entities/Messages/IReaction.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IReaction.cs
@@ -1,13 +1,22 @@
-namespace Discord
+using System.Collections.Generic;
+
+namespace Discord;
+
+///
+/// Represents a generic reaction object.
+///
+public interface IReaction
{
///
- /// Represents a generic reaction object.
+ /// The used in the reaction.
///
- public interface IReaction
- {
- ///
- /// The used in the reaction.
- ///
- IEmote Emote { get; }
- }
+ IEmote Emote { get; }
+
+ ///
+ /// Gets colors used for the super reaction.
+ ///
+ ///
+ /// The collection will be empty if the reaction is a normal reaction.
+ ///
+ public IReadOnlyCollection BurstColors { get; }
}
diff --git a/src/Discord.Net.Core/Entities/Messages/ReactionMetadata.cs b/src/Discord.Net.Core/Entities/Messages/ReactionMetadata.cs
index f6a11634..1fcea9fd 100644
--- a/src/Discord.Net.Core/Entities/Messages/ReactionMetadata.cs
+++ b/src/Discord.Net.Core/Entities/Messages/ReactionMetadata.cs
@@ -1,24 +1,40 @@
-namespace Discord
+using System.Collections.Generic;
+
+namespace Discord;
+
+///
+/// A metadata containing reaction information.
+///
+public struct ReactionMetadata
{
///
- /// A metadata containing reaction information.
+ /// Gets the number of reactions.
///
- public struct ReactionMetadata
- {
- ///
- /// Gets the number of reactions.
- ///
- ///
- /// An representing the number of this reactions that has been added to this message.
- ///
- public int ReactionCount { get; internal set; }
+ ///
+ /// An representing the number of this reactions that has been added to this message.
+ ///
+ public int ReactionCount { get; internal set; }
+
+ ///
+ /// Gets a value that indicates whether the current user has reacted to this.
+ ///
+ ///
+ /// if the user has reacted to the message; otherwise .
+ ///
+ public bool IsMe { get; internal set; }
- ///
- /// Gets a value that indicates whether the current user has reacted to this.
- ///
- ///
- /// if the user has reacted to the message; otherwise .
- ///
- public bool IsMe { get; internal set; }
- }
+ ///
+ /// Gets the number of burst reactions added to this message.
+ ///
+ public int BurstCount { get; internal set; }
+
+ ///
+ /// Gets the number of normal reactions added to this message.
+ ///
+ public int NormalCount { get; internal set; }
+
+ ///
+ /// Gets colors used for super reaction.
+ ///
+ public IReadOnlyCollection BurstColors { get; internal set; }
}
diff --git a/src/Discord.Net.Core/Entities/Messages/ReactionType.cs b/src/Discord.Net.Core/Entities/Messages/ReactionType.cs
new file mode 100644
index 00000000..d69e15c3
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Messages/ReactionType.cs
@@ -0,0 +1,14 @@
+namespace Discord;
+
+public enum ReactionType
+{
+ ///
+ /// The reaction is a normal reaction.
+ ///
+ Normal = 0,
+
+ ///
+ /// The reaction is a super reaction.
+ ///
+ Burst = 1,
+}
diff --git a/src/Discord.Net.Rest/API/Common/Reaction.cs b/src/Discord.Net.Rest/API/Common/Reaction.cs
index ffe7a478..b85d3b02 100644
--- a/src/Discord.Net.Rest/API/Common/Reaction.cs
+++ b/src/Discord.Net.Rest/API/Common/Reaction.cs
@@ -1,14 +1,24 @@
using Newtonsoft.Json;
-namespace Discord.API
+namespace Discord.API;
+
+internal class Reaction
{
- internal class Reaction
- {
- [JsonProperty("count")]
- public int Count { get; set; }
- [JsonProperty("me")]
- public bool Me { get; set; }
- [JsonProperty("emoji")]
- public Emoji Emoji { get; set; }
- }
+ [JsonProperty("count")]
+ public int Count { get; set; }
+
+ [JsonProperty("me")]
+ public bool Me { get; set; }
+
+ [JsonProperty("me_burst")]
+ public bool MeBurst { get; set; }
+
+ [JsonProperty("emoji")]
+ public Emoji Emoji { get; set; }
+
+ [JsonProperty("count_details")]
+ public ReactionCountDetails CountDetails { get; set; }
+
+ [JsonProperty("burst_colors")]
+ public Color[] Colors { get; set; }
}
diff --git a/src/Discord.Net.Rest/API/Common/ReactionCountDetails.cs b/src/Discord.Net.Rest/API/Common/ReactionCountDetails.cs
new file mode 100644
index 00000000..b8ab0487
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/ReactionCountDetails.cs
@@ -0,0 +1,12 @@
+using Newtonsoft.Json;
+
+namespace Discord.API;
+
+internal class ReactionCountDetails
+{
+ [JsonProperty("normal")]
+ public int NormalCount { get; set;}
+
+ [JsonProperty("burst")]
+ public int BurstCount { get; set;}
+}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index e4818fd3..d07d63c1 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1143,7 +1143,8 @@ namespace Discord.API
await SendAsync("DELETE", () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}", ids, options: options).ConfigureAwait(false);
}
- public async Task> GetReactionUsersAsync(ulong channelId, ulong messageId, string emoji, GetReactionUsersParams args, RequestOptions options = null)
+
+ public async Task> GetReactionUsersAsync(ulong channelId, ulong messageId, string emoji, GetReactionUsersParams args, ReactionType reactionType, RequestOptions options = null)
{
Preconditions.NotEqual(channelId, 0, nameof(channelId));
Preconditions.NotEqual(messageId, 0, nameof(messageId));
@@ -1158,9 +1159,10 @@ namespace Discord.API
ulong afterUserId = args.AfterUserId.GetValueOrDefault(0);
var ids = new BucketIds(channelId: channelId);
- Expression> endpoint = () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}?limit={limit}&after={afterUserId}";
+ Expression> endpoint = () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}?limit={limit}&after={afterUserId}&type={(int)reactionType}";
return await SendAsync>("GET", endpoint, ids, options: options).ConfigureAwait(false);
}
+
public async Task AckMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null)
{
Preconditions.NotEqual(channelId, 0, nameof(channelId));
diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
index a0aab863..8e7f9377 100644
--- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
@@ -164,7 +164,7 @@ namespace Discord.Rest
}
public static IAsyncEnumerable> GetReactionUsersAsync(IMessage msg, IEmote emote,
- int? limit, BaseDiscordClient client, RequestOptions options)
+ int? limit, BaseDiscordClient client, ReactionType reactionType, RequestOptions options)
{
Preconditions.NotNull(emote, nameof(emote));
var emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : UrlEncode(emote.Name));
@@ -181,7 +181,7 @@ namespace Discord.Rest
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 models = await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, reactionType, options).ConfigureAwait(false);
return models.Select(x => RestUser.Create(client, x)).ToImmutableArray();
},
nextPage: (info, lastPage) =>
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
index 0f4dd291..9dcbb496 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
@@ -316,7 +316,14 @@ namespace Discord.Rest
#endregion
///
- public IReadOnlyDictionary Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
+ public IReadOnlyDictionary Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata
+ {
+ ReactionCount = x.Count,
+ IsMe = x.Me,
+ BurstColors = x.BurstColors,
+ BurstCount = x.BurstCount,
+ NormalCount = x.NormalCount,
+ });
///
public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
@@ -334,7 +341,7 @@ namespace Discord.Rest
public Task RemoveAllReactionsForEmoteAsync(IEmote emote, RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsForEmoteAsync(this, emote, Discord, options);
///
- public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
- => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
+ public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null, ReactionType type = ReactionType.Normal)
+ => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, type, options);
}
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestReaction.cs b/src/Discord.Net.Rest/Entities/Messages/RestReaction.cs
index c38efe32..2be12f8e 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestReaction.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestReaction.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using Model = Discord.API.Reaction;
namespace Discord.Rest
@@ -9,20 +10,44 @@ namespace Discord.Rest
{
///
public IEmote Emote { get; }
+
///
/// Gets the number of reactions added.
///
public int Count { get; }
+
///
- /// Gets whether the reactions is added by the user.
+ /// Gets whether the reaction is added by the user.
///
public bool Me { get; }
- internal RestReaction(IEmote emote, int count, bool me)
+ ///
+ /// Gets whether the super-reaction is added by the user.
+ ///
+ public bool MeBurst { get; }
+
+ ///
+ /// Gets the number of burst reactions added.
+ ///
+ public int BurstCount { get; }
+
+ ///
+ /// Gets the number of normal reactions added.
+ ///
+ public int NormalCount { get; }
+
+ ///
+ public IReadOnlyCollection BurstColors { get; }
+
+ internal RestReaction(IEmote emote, int count, bool me, int burst, int normal, IReadOnlyCollection colors, bool meBurst)
{
Emote = emote;
Count = count;
Me = me;
+ BurstCount = burst;
+ NormalCount = normal;
+ BurstColors = colors;
+ MeBurst = meBurst;
}
internal static RestReaction Create(Model model)
{
@@ -31,7 +56,13 @@ namespace Discord.Rest
emote = new Emote(model.Emoji.Id.Value, model.Emoji.Name, model.Emoji.Animated.GetValueOrDefault());
else
emote = new Emoji(model.Emoji.Name);
- return new RestReaction(emote, model.Count, model.Me);
+ return new RestReaction(emote,
+ model.Count,
+ model.Me,
+ model.CountDetails.BurstCount,
+ model.CountDetails.NormalCount,
+ model.Colors.ToReadOnlyCollection(),
+ model.MeBurst);
}
}
}
diff --git a/src/Discord.Net.Rest/Net/Converters/ColorConverter.cs b/src/Discord.Net.Rest/Net/Converters/ColorConverter.cs
new file mode 100644
index 00000000..4c0ab529
--- /dev/null
+++ b/src/Discord.Net.Rest/Net/Converters/ColorConverter.cs
@@ -0,0 +1,27 @@
+using Newtonsoft.Json;
+
+using System.Globalization;
+using System;
+
+namespace Discord.Net.Converters;
+
+internal class ColorConverter : JsonConverter
+{
+ public static readonly ColorConverter Instance = new ();
+
+ public override bool CanConvert(Type objectType) => true;
+ public override bool CanRead => true;
+ public override bool CanWrite => true;
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ if (reader.Value is null)
+ return null;
+ return new Color(uint.Parse(reader.Value.ToString()!.TrimStart('#'), NumberStyles.HexNumber));
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ writer.WriteValue($"#{(uint)value:X}");
+ }
+}
diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
index 62c0e580..8de2c026 100644
--- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
+++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
@@ -93,6 +93,8 @@ namespace Discord.Net.Converters
return DiscordErrorConverter.Instance;
if (type == typeof(GuildFeatures))
return GuildFeaturesConverter.Instance;
+ if(type == typeof(Color))
+ return ColorConverter.Instance;
//Entities
var typeInfo = type.GetTypeInfo();
diff --git a/src/Discord.Net.WebSocket/API/Gateway/Reaction.cs b/src/Discord.Net.WebSocket/API/Gateway/Reaction.cs
index 0d17cbff..051da453 100644
--- a/src/Discord.Net.WebSocket/API/Gateway/Reaction.cs
+++ b/src/Discord.Net.WebSocket/API/Gateway/Reaction.cs
@@ -1,20 +1,33 @@
using Newtonsoft.Json;
-namespace Discord.API.Gateway
+namespace Discord.API.Gateway;
+
+internal class Reaction
{
- internal class Reaction
- {
- [JsonProperty("user_id")]
- public ulong UserId { get; set; }
- [JsonProperty("message_id")]
- public ulong MessageId { get; set; }
- [JsonProperty("channel_id")]
- public ulong ChannelId { get; set; }
- [JsonProperty("guild_id")]
- public Optional GuildId { get; set; }
- [JsonProperty("emoji")]
- public Emoji Emoji { get; set; }
- [JsonProperty("member")]
- public Optional Member { get; set; }
- }
+ [JsonProperty("user_id")]
+ public ulong UserId { get; set; }
+
+ [JsonProperty("message_id")]
+ public ulong MessageId { get; set; }
+
+ [JsonProperty("channel_id")]
+ public ulong ChannelId { get; set; }
+
+ [JsonProperty("guild_id")]
+ public Optional GuildId { get; set; }
+
+ [JsonProperty("emoji")]
+ public Emoji Emoji { get; set; }
+
+ [JsonProperty("member")]
+ public Optional Member { get; set; }
+
+ [JsonProperty("burst")]
+ public bool IsBurst { get; set; }
+
+ [JsonProperty("burst_colors")]
+ public Optional BurstColors { get; set; }
+
+ [JsonProperty("type")]
+ public ReactionType Type { get; set; }
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
index 24c9dce2..8d964726 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
@@ -374,8 +374,8 @@ namespace Discord.WebSocket
public Task RemoveAllReactionsForEmoteAsync(IEmote emote, RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsForEmoteAsync(this, emote, Discord, options);
///
- public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
- => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
+ public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null, ReactionType type = ReactionType.Normal)
+ => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, type, options);
#endregion
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs
index fe24057d..113093cc 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs
@@ -1,113 +1,145 @@
+using System;
+using System.Collections.Generic;
using Model = Discord.API.Gateway.Reaction;
-namespace Discord.WebSocket
+namespace Discord.WebSocket;
+
+///
+/// Represents a WebSocket-based reaction object.
+///
+public class SocketReaction : IReaction
{
///
- /// Represents a WebSocket-based reaction object.
+ /// Gets the ID of the user who added the reaction.
///
- public class SocketReaction : IReaction
+ ///
+ /// This property retrieves the snowflake identifier of the user responsible for this reaction. This
+ /// property will always contain the user identifier in event that
+ /// cannot be retrieved.
+ ///
+ ///
+ /// A user snowflake identifier associated with the user.
+ ///
+ public ulong UserId { get; }
+
+ ///
+ /// Gets the user who added the reaction if possible.
+ ///
+ ///
+ ///
+ /// This property attempts to retrieve a WebSocket-cached user that is responsible for this reaction from
+ /// the client. In other words, when the user is not in the WebSocket cache, this property may not
+ /// contain a value, leaving the only identifiable information to be
+ /// .
+ ///
+ ///
+ /// If you wish to obtain an identifiable user object, consider utilizing
+ /// which will attempt to retrieve the user from REST.
+ ///
+ ///
+ ///
+ /// A user object where possible; a value is not always returned.
+ ///
+ ///
+ public Optional User { get; }
+
+ ///
+ /// Gets the ID of the message that has been reacted to.
+ ///
+ ///
+ /// A message snowflake identifier associated with the message.
+ ///
+ public ulong MessageId { get; }
+
+ ///
+ /// Gets the message that has been reacted to if possible.
+ ///
+ ///
+ /// A WebSocket-based message where possible; a value is not always returned.
+ ///
+ ///
+ public Optional Message { get; }
+
+ ///
+ /// Gets the channel where the reaction takes place in.
+ ///
+ ///
+ /// A WebSocket-based message channel.
+ ///
+ public ISocketMessageChannel Channel { get; }
+
+ ///
+ public IEmote Emote { get; }
+
+ ///
+ /// Gets whether the reaction is a super reaction.
+ ///
+ public bool IsBurst { get; }
+
+ ///
+ public IReadOnlyCollection BurstColors { get; }
+
+ ///
+ /// Gets the type of the reaction.
+ ///
+ public ReactionType ReactionType { get; }
+
+ internal SocketReaction(ISocketMessageChannel channel, ulong messageId, Optional message, ulong userId, Optional user,
+ IEmote emoji, bool isBurst, IReadOnlyCollection colors, ReactionType reactionType)
{
- ///
- /// Gets the ID of the user who added the reaction.
- ///
- ///
- /// This property retrieves the snowflake identifier of the user responsible for this reaction. This
- /// property will always contain the user identifier in event that
- /// cannot be retrieved.
- ///
- ///
- /// A user snowflake identifier associated with the user.
- ///
- public ulong UserId { get; }
- ///
- /// Gets the user who added the reaction if possible.
- ///
- ///
- ///
- /// This property attempts to retrieve a WebSocket-cached user that is responsible for this reaction from
- /// the client. In other words, when the user is not in the WebSocket cache, this property may not
- /// contain a value, leaving the only identifiable information to be
- /// .
- ///
- ///
- /// If you wish to obtain an identifiable user object, consider utilizing
- /// which will attempt to retrieve the user from REST.
- ///
- ///
- ///
- /// A user object where possible; a value is not always returned.
- ///
- ///
- public Optional User { get; }
- ///
- /// Gets the ID of the message that has been reacted to.
- ///
- ///
- /// A message snowflake identifier associated with the message.
- ///
- public ulong MessageId { get; }
- ///
- /// Gets the message that has been reacted to if possible.
- ///
- ///
- /// A WebSocket-based message where possible; a value is not always returned.
- ///
- ///
- public Optional Message { get; }
- ///
- /// Gets the channel where the reaction takes place in.
- ///
- ///
- /// A WebSocket-based message channel.
- ///
- public ISocketMessageChannel Channel { get; }
- ///
- public IEmote Emote { get; }
+ Channel = channel;
+ MessageId = messageId;
+ Message = message;
+ UserId = userId;
+ User = user;
+ Emote = emoji;
+ IsBurst = isBurst;
+ BurstColors = colors;
+ ReactionType = reactionType;
+ }
- internal SocketReaction(ISocketMessageChannel channel, ulong messageId, Optional message, ulong userId, Optional user, IEmote emoji)
+ internal static SocketReaction Create(Model model, ISocketMessageChannel channel, Optional message, Optional user)
+ {
+ IEmote emote;
+ if (model.Emoji.Id.HasValue)
+ emote = new Emote(model.Emoji.Id.Value, model.Emoji.Name, model.Emoji.Animated.GetValueOrDefault());
+ else
+ emote = new Emoji(model.Emoji.Name);
+ return new SocketReaction(channel,
+ model.MessageId,
+ message,
+ model.UserId,
+ user,
+ emote,
+ model.IsBurst,
+ model.BurstColors.GetValueOrDefault(Array.Empty()).ToReadOnlyCollection(),
+ model.Type);
+ }
+
+ ///
+ public override bool Equals(object other)
+ {
+ if (other == null)
+ return false;
+ if (other == this)
+ return true;
+
+ var otherReaction = other as SocketReaction;
+ if (otherReaction == null)
+ return false;
+
+ return UserId == otherReaction.UserId && MessageId == otherReaction.MessageId && Emote.Equals(otherReaction.Emote);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
{
- Channel = channel;
- MessageId = messageId;
- Message = message;
- UserId = userId;
- User = user;
- Emote = emoji;
- }
- internal static SocketReaction Create(Model model, ISocketMessageChannel channel, Optional message, Optional user)
- {
- IEmote emote;
- if (model.Emoji.Id.HasValue)
- emote = new Emote(model.Emoji.Id.Value, model.Emoji.Name, model.Emoji.Animated.GetValueOrDefault());
- else
- emote = new Emoji(model.Emoji.Name);
- return new SocketReaction(channel, model.MessageId, message, model.UserId, user, emote);
- }
-
- ///
- public override bool Equals(object other)
- {
- if (other == null)
- return false;
- if (other == this)
- return true;
-
- var otherReaction = other as SocketReaction;
- if (otherReaction == null)
- return false;
-
- return UserId == otherReaction.UserId && MessageId == otherReaction.MessageId && Emote.Equals(otherReaction.Emote);
- }
-
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- var hashCode = UserId.GetHashCode();
- hashCode = (hashCode * 397) ^ MessageId.GetHashCode();
- hashCode = (hashCode * 397) ^ Emote.GetHashCode();
- return hashCode;
- }
+ var hashCode = UserId.GetHashCode();
+ hashCode = (hashCode * 397) ^ MessageId.GetHashCode();
+ hashCode = (hashCode * 397) ^ Emote.GetHashCode();
+ return hashCode;
}
}
}