diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
index 36fa602a7..1eba1e076 100644
--- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
namespace Discord
{
@@ -138,5 +139,89 @@ namespace Discord
/// A message's application, if any is associated.
///
MessageApplication Application { get; }
+
+ ///
+ /// Gets all reactions included in this message.
+ ///
+ IReadOnlyDictionary Reactions { get; }
+
+ ///
+ /// Adds a reaction to this message.
+ ///
+ ///
+ /// The following example adds the reaction, 💕, to the message.
+ ///
+ /// await msg.AddReactionAsync(new Emoji("\U0001f495"));
+ ///
+ ///
+ /// The emoji used to react to this message.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous operation for adding a reaction to this message.
+ ///
+ ///
+ Task AddReactionAsync(IEmote emote, RequestOptions options = null);
+ ///
+ /// Removes a reaction from message.
+ ///
+ ///
+ /// The following example removes the reaction, 💕, added by the message author from the message.
+ ///
+ /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), msg.Author);
+ ///
+ ///
+ /// The emoji used to react to this message.
+ /// The user that added the emoji.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous operation for removing a reaction to this message.
+ ///
+ ///
+ Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null);
+ ///
+ /// Removes a reaction from message.
+ ///
+ ///
+ /// The following example removes the reaction, 💕, added by the user with ID 84291986575613952 from the message.
+ ///
+ /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), 84291986575613952);
+ ///
+ ///
+ /// The emoji used to react to this message.
+ /// The ID of the user that added the emoji.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous operation for removing a reaction to this message.
+ ///
+ ///
+ Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null);
+ ///
+ /// Removes all reactions from this message.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous removal operation.
+ ///
+ Task RemoveAllReactionsAsync(RequestOptions options = null);
+
+ ///
+ /// Gets all users that reacted to a message with a given emote.
+ ///
+ ///
+ /// The following example gets the users that have reacted with the emoji 💕 to the message.
+ ///
+ /// var emoji = new Emoji("\U0001f495");
+ /// var reactedUsers = await message.GetReactionUsersAsync(emoji, 100).FlattenAsync();
+ ///
+ ///
+ /// 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.
+ ///
+ /// A paged collection containing a read-only collection of users that has reacted to this message.
+ /// Flattening the paginated response into a collection of users with
+ /// is required if you wish to access the users.
+ ///
+ IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/IReactionMessage.cs b/src/Discord.Net.Core/Entities/Messages/IReactionMessage.cs
deleted file mode 100644
index 2919b80d1..000000000
--- a/src/Discord.Net.Core/Entities/Messages/IReactionMessage.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Discord
-{
- ///
- /// Represents a message where reactions can be added or removed.
- ///
- public interface IReactionMessage : IMessage
- {
- ///
- /// Gets all reactions included in this message.
- ///
- IReadOnlyDictionary Reactions { get; }
-
- ///
- /// Adds a reaction to this message.
- ///
- ///
- /// The following example adds the reaction, 💕, to the message.
- ///
- /// await msg.AddReactionAsync(new Emoji("\U0001f495"));
- ///
- ///
- /// The emoji used to react to this message.
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous operation for adding a reaction to this message.
- ///
- ///
- Task AddReactionAsync(IEmote emote, RequestOptions options = null);
- ///
- /// Removes a reaction from message.
- ///
- ///
- /// The following example removes the reaction, 💕, added by the message author from the message.
- ///
- /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), msg.Author);
- ///
- ///
- /// The emoji used to react to this message.
- /// The user that added the emoji.
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous operation for removing a reaction to this message.
- ///
- ///
- Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null);
- ///
- /// Removes a reaction from message.
- ///
- ///
- /// The following example removes the reaction, 💕, added by the user with ID 84291986575613952 from the message.
- ///
- /// await msg.RemoveReactionAsync(new Emoji("\U0001f495"), 84291986575613952);
- ///
- ///
- /// The emoji used to react to this message.
- /// The ID of the user that added the emoji.
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous operation for removing a reaction to this message.
- ///
- ///
- Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null);
- ///
- /// Removes all reactions from this message.
- ///
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous removal operation.
- ///
- Task RemoveAllReactionsAsync(RequestOptions options = null);
-
- ///
- /// Gets all users that reacted to a message with a given emote.
- ///
- ///
- /// The following example gets the users that have reacted with the emoji 💕 to the message.
- ///
- /// var emoji = new Emoji("\U0001f495");
- /// var reactedUsers = await message.GetReactionUsersAsync(emoji, 100).FlattenAsync();
- ///
- ///
- /// 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.
- ///
- /// A paged collection containing a read-only collection of users that has reacted to this message.
- /// Flattening the paginated response into a collection of users with
- /// is required if you wish to access the users.
- ///
- IAsyncEnumerable> GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null);
- }
-}
diff --git a/src/Discord.Net.Core/Entities/Messages/ISystemMessage.cs b/src/Discord.Net.Core/Entities/Messages/ISystemMessage.cs
index fc65139b1..89cd17a35 100644
--- a/src/Discord.Net.Core/Entities/Messages/ISystemMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/ISystemMessage.cs
@@ -3,7 +3,7 @@ namespace Discord
///
/// Represents a generic message sent by the system.
///
- public interface ISystemMessage : IReactionMessage
+ public interface ISystemMessage : IMessage
{
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
index c8941e961..be2523b21 100644
--- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
@@ -7,7 +7,7 @@ namespace Discord
///
/// Represents a generic message sent by a user.
///
- public interface IUserMessage : IReactionMessage
+ public interface IUserMessage : IMessage
{
///
/// Modifies this message.
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
index fa1c91376..29a9c9bd2 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
@@ -13,6 +13,7 @@ namespace Discord.Rest
public abstract class RestMessage : RestEntity, IMessage, IUpdateable
{
private long _timestampTicks;
+ private ImmutableArray _reactions = ImmutableArray.Create();
///
public IMessageChannel Channel { get; }
@@ -106,6 +107,22 @@ namespace Discord.Rest
PartyId = model.Activity.Value.PartyId.GetValueOrDefault()
};
}
+
+ if (model.Reactions.IsSpecified)
+ {
+ var value = model.Reactions.Value;
+ if (value.Length > 0)
+ {
+ var reactions = ImmutableArray.CreateBuilder(value.Length);
+ for (int i = 0; i < value.Length; i++)
+ reactions.Add(RestReaction.Create(value[i]));
+ _reactions = reactions.ToImmutable();
+ }
+ else
+ _reactions = ImmutableArray.Create();
+ }
+ else
+ _reactions = ImmutableArray.Create();
}
///
@@ -135,5 +152,24 @@ namespace Discord.Rest
IReadOnlyCollection IMessage.Embeds => Embeds;
///
IReadOnlyCollection IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray();
+
+ ///
+ public IReadOnlyDictionary Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
+
+ ///
+ public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
+ => MessageHelper.AddReactionAsync(this, emote, Discord, options);
+ ///
+ public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
+ => MessageHelper.RemoveReactionAsync(this, user.Id, emote, Discord, options);
+ ///
+ public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null)
+ => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
+ ///
+ public Task RemoveAllReactionsAsync(RequestOptions options = null)
+ => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
+ ///
+ public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
+ => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
}
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestReactionMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestReactionMessage.cs
deleted file mode 100644
index 203ef17c5..000000000
--- a/src/Discord.Net.Rest/Entities/Messages/RestReactionMessage.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading.Tasks;
-using Model = Discord.API.Message;
-
-namespace Discord.Rest
-{
- ///
- /// Represents a REST-based mesage where reactions can be added or removed.
- ///
- [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public abstract class RestReactionMessage : RestMessage, IReactionMessage
- {
- private ImmutableArray _reactions = ImmutableArray.Create();
-
- ///
- public IReadOnlyDictionary Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
-
- internal RestReactionMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
- : base(discord, id, channel, author, source)
- {
- }
-
- internal override void Update(Model model)
- {
- base.Update(model);
-
- if (model.Reactions.IsSpecified)
- {
- var value = model.Reactions.Value;
- if (value.Length > 0)
- {
- var reactions = ImmutableArray.CreateBuilder(value.Length);
- for (int i = 0; i < value.Length; i++)
- reactions.Add(RestReaction.Create(value[i]));
- _reactions = reactions.ToImmutable();
- }
- else
- _reactions = ImmutableArray.Create();
- }
- else
- _reactions = ImmutableArray.Create();
- }
-
- ///
- public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
- => MessageHelper.AddReactionAsync(this, emote, Discord, options);
- ///
- public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
- => MessageHelper.RemoveReactionAsync(this, user.Id, emote, Discord, options);
- ///
- public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null)
- => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
- ///
- public Task RemoveAllReactionsAsync(RequestOptions options = null)
- => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
- ///
- public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
- => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
- }
-}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestSystemMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestSystemMessage.cs
index bfd620698..89a651eb7 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestSystemMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestSystemMessage.cs
@@ -7,7 +7,7 @@ namespace Discord.Rest
/// Represents a REST-based system message.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class RestSystemMessage : RestReactionMessage, ISystemMessage
+ public class RestSystemMessage : RestMessage, ISystemMessage
{
///
public MessageType Type { get; private set; }
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
index ed58e7bfd..7d652687a 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
@@ -11,7 +11,7 @@ namespace Discord.Rest
/// Represents a REST-based message sent by a user.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class RestUserMessage : RestReactionMessage, IUserMessage
+ public class RestUserMessage : RestMessage, IUserMessage
{
private bool _isMentioningEveryone, _isTTS, _isPinned, _isSuppressed;
private long? _editedTimestampTicks;
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
index 4d3efa656..ae42d9d61 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
@@ -14,6 +14,7 @@ namespace Discord.WebSocket
public abstract class SocketMessage : SocketEntity, IMessage
{
private long _timestampTicks;
+ private readonly List _reactions = new List();
///
/// Gets the author of this message.
@@ -89,6 +90,8 @@ namespace Discord.WebSocket
public virtual IReadOnlyCollection MentionedUsers => ImmutableArray.Create();
///
public virtual IReadOnlyCollection Tags => ImmutableArray.Create();
+ ///
+ public IReadOnlyDictionary Reactions => _reactions.GroupBy(r => r.Emote).ToDictionary(x => x.Key, x => new ReactionMetadata { ReactionCount = x.Count(), IsMe = x.Any(y => y.UserId == Discord.CurrentUser.Id) });
///
public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks);
@@ -169,5 +172,35 @@ namespace Discord.WebSocket
IReadOnlyCollection IMessage.MentionedRoleIds => MentionedRoles.Select(x => x.Id).ToImmutableArray();
///
IReadOnlyCollection IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray();
+
+ internal void AddReaction(SocketReaction reaction)
+ {
+ _reactions.Add(reaction);
+ }
+ internal void RemoveReaction(SocketReaction reaction)
+ {
+ if (_reactions.Contains(reaction))
+ _reactions.Remove(reaction);
+ }
+ internal void ClearReactions()
+ {
+ _reactions.Clear();
+ }
+
+ ///
+ public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
+ => MessageHelper.AddReactionAsync(this, emote, Discord, options);
+ ///
+ public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
+ => MessageHelper.RemoveReactionAsync(this, user.Id, emote, Discord, options);
+ ///
+ public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null)
+ => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
+ ///
+ public Task RemoveAllReactionsAsync(RequestOptions options = null)
+ => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
+ ///
+ public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
+ => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketReactionMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketReactionMessage.cs
deleted file mode 100644
index 43ebaa420..000000000
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketReactionMessage.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using Discord.Rest;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Discord.WebSocket
-{
- ///
- /// Represents a WebSocket-based message where reactions can be added or removed.
- ///
- [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public abstract class SocketReactionMessage : SocketMessage, IReactionMessage
- {
- private readonly List _reactions = new List();
-
- internal SocketReactionMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source)
- : base(discord, id, channel, author, source)
- {
- }
-
- ///
- public IReadOnlyDictionary Reactions => _reactions.GroupBy(r => r.Emote).ToDictionary(x => x.Key, x => new ReactionMetadata { ReactionCount = x.Count(), IsMe = x.Any(y => y.UserId == Discord.CurrentUser.Id) });
-
- internal void AddReaction(SocketReaction reaction)
- {
- _reactions.Add(reaction);
- }
- internal void RemoveReaction(SocketReaction reaction)
- {
- if (_reactions.Contains(reaction))
- _reactions.Remove(reaction);
- }
- internal void ClearReactions()
- {
- _reactions.Clear();
- }
-
- ///
- public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
- => MessageHelper.AddReactionAsync(this, emote, Discord, options);
- ///
- public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
- => MessageHelper.RemoveReactionAsync(this, user.Id, emote, Discord, options);
- ///
- public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null)
- => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
- ///
- public Task RemoveAllReactionsAsync(RequestOptions options = null)
- => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
- ///
- public IAsyncEnumerable> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
- => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
- }
-}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketSystemMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketSystemMessage.cs
index a2bcec3b8..d0ce5025b 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketSystemMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketSystemMessage.cs
@@ -7,7 +7,7 @@ namespace Discord.WebSocket
/// Represents a WebSocket-based message sent by the system.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class SocketSystemMessage : SocketReactionMessage, ISystemMessage
+ public class SocketSystemMessage : SocketMessage, ISystemMessage
{
///
public MessageType Type { get; private set; }
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
index 544cebbf4..b26dfe5fb 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
@@ -13,7 +13,7 @@ namespace Discord.WebSocket
/// Represents a WebSocket-based message sent by a user.
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class SocketUserMessage : SocketReactionMessage, IUserMessage
+ public class SocketUserMessage : SocketMessage, IUserMessage
{
private bool _isMentioningEveryone, _isTTS, _isPinned, _isSuppressed;
private long? _editedTimestampTicks;