From 118217387e20d1f4e9704db47c91eeafdc2ed39a Mon Sep 17 00:00:00 2001 From: Chris Johnston Date: Mon, 2 Sep 2019 16:52:02 -0700 Subject: [PATCH] Remove ReactionMessage types, move reaction impl to IMessage Removes the IReactionMessage and derived types, which was unnecessary since all classes derived from IReactionMessage were IMessage. Moves the reaction implementation to IMessage and derived types. --- .../Entities/Messages/IMessage.cs | 85 ++++++++++++++++ .../Entities/Messages/IReactionMessage.cs | 98 ------------------- .../Entities/Messages/ISystemMessage.cs | 2 +- .../Entities/Messages/IUserMessage.cs | 2 +- .../Entities/Messages/RestMessage.cs | 36 +++++++ .../Entities/Messages/RestReactionMessage.cs | 63 ------------ .../Entities/Messages/RestSystemMessage.cs | 2 +- .../Entities/Messages/RestUserMessage.cs | 2 +- .../Entities/Messages/SocketMessage.cs | 33 +++++++ .../Messages/SocketReactionMessage.cs | 55 ----------- .../Entities/Messages/SocketSystemMessage.cs | 2 +- .../Entities/Messages/SocketUserMessage.cs | 2 +- 12 files changed, 160 insertions(+), 222 deletions(-) delete mode 100644 src/Discord.Net.Core/Entities/Messages/IReactionMessage.cs delete mode 100644 src/Discord.Net.Rest/Entities/Messages/RestReactionMessage.cs delete mode 100644 src/Discord.Net.WebSocket/Entities/Messages/SocketReactionMessage.cs 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;