@@ -165,6 +165,14 @@ namespace Discord | |||
IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions { get; } | |||
/// <summary> | |||
/// Gets all stickers included in this message. | |||
/// </summary> | |||
/// <returns> | |||
/// A read-only collection of sticker objects. | |||
/// </returns> | |||
IReadOnlyCollection<ISticker> Stickers { get; } | |||
/// <summary> | |||
/// Gets the flags related to this message. | |||
/// </summary> | |||
/// <remarks> | |||
@@ -0,0 +1,67 @@ | |||
using System.Collections.Generic; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a discord sticker. | |||
/// </summary> | |||
public interface ISticker | |||
{ | |||
/// <summary> | |||
/// Gets the ID of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A snowflake ID associated with this sticker. | |||
/// </returns> | |||
ulong Id { get; } | |||
/// <summary> | |||
/// Gets the ID of the pack of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A snowflake ID associated with the pack of this sticker. | |||
/// </returns> | |||
ulong PackId { get; } | |||
/// <summary> | |||
/// Gets the name of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see langword="string"/> with the name of this sticker. | |||
/// </returns> | |||
string Name { get; } | |||
/// <summary> | |||
/// Gets the description of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see langword="string"/> with the description of this sticker. | |||
/// </returns> | |||
string Description { get; } | |||
/// <summary> | |||
/// Gets the list of tags of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A read-only list with the tags of this sticker. | |||
/// </returns> | |||
IReadOnlyCollection<string> Tags { get; } | |||
/// <summary> | |||
/// Gets the asset hash of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see langword="string"/> with the asset hash of this sticker. | |||
/// </returns> | |||
string Asset { get; } | |||
/// <summary> | |||
/// Gets the preview asset hash of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see langword="string"/> with the preview asset hash of this sticker. | |||
/// </returns> | |||
string PreviewAsset { get; } | |||
/// <summary> | |||
/// Gets the format type of this sticker. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see cref="StickerFormatType"/> with the format type of this sticker. | |||
/// </returns> | |||
StickerFormatType FormatType { get; } | |||
} | |||
} |
@@ -0,0 +1,15 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Defines the types of formats for stickers. </summary> | |||
public enum StickerFormatType | |||
{ | |||
/// <summary> Default value for a sticker format type. </summary> | |||
None = 0, | |||
/// <summary> The sticker format type is png. </summary> | |||
Png = 1, | |||
/// <summary> The sticker format type is apng. </summary> | |||
Apng = 2, | |||
/// <summary> The sticker format type is lottie. </summary> | |||
Lottie = 3, | |||
} | |||
} |
@@ -58,5 +58,7 @@ namespace Discord.API | |||
public Optional<AllowedMentions> AllowedMentions { get; set; } | |||
[JsonProperty("referenced_message")] | |||
public Optional<Message> ReferencedMessage { get; set; } | |||
[JsonProperty("stickers")] | |||
public Optional<Sticker[]> Stickers { get; set; } | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
#pragma warning disable CS1591 | |||
using Newtonsoft.Json; | |||
namespace Discord.API | |||
{ | |||
internal class Sticker | |||
{ | |||
[JsonProperty("id")] | |||
public ulong Id { get; set; } | |||
[JsonProperty("pack_id")] | |||
public ulong PackId { get; set; } | |||
[JsonProperty("name")] | |||
public string Name { get; set; } | |||
[JsonProperty("description")] | |||
public string Desription { get; set; } | |||
[JsonProperty("tags")] | |||
public Optional<string> Tags { get; set; } | |||
[JsonProperty("asset")] | |||
public string Asset { get; set; } | |||
[JsonProperty("preview_asset")] | |||
public string PreviewAsset { get; set; } | |||
[JsonProperty("format_type")] | |||
public StickerFormatType FormatType { get; set; } | |||
} | |||
} |
@@ -58,6 +58,8 @@ namespace Discord.Rest | |||
public virtual IReadOnlyCollection<RestUser> MentionedUsers => ImmutableArray.Create<RestUser>(); | |||
/// <inheritdoc /> | |||
public virtual IReadOnlyCollection<ITag> Tags => ImmutableArray.Create<ITag>(); | |||
/// <inheritdoc /> | |||
public virtual IReadOnlyCollection<Sticker> Stickers => ImmutableArray.Create<Sticker>(); | |||
/// <inheritdoc /> | |||
public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks); | |||
@@ -173,6 +175,8 @@ namespace Discord.Rest | |||
IReadOnlyCollection<IEmbed> IMessage.Embeds => Embeds; | |||
/// <inheritdoc /> | |||
IReadOnlyCollection<ulong> IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray(); | |||
/// <inheritdoc /> | |||
IReadOnlyCollection<ISticker> IMessage.Stickers => Stickers; | |||
/// <inheritdoc /> | |||
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me }); | |||
@@ -21,6 +21,7 @@ namespace Discord.Rest | |||
private ImmutableArray<ITag> _tags = ImmutableArray.Create<ITag>(); | |||
private ImmutableArray<ulong> _roleMentionIds = ImmutableArray.Create<ulong>(); | |||
private ImmutableArray<RestUser> _userMentions = ImmutableArray.Create<RestUser>(); | |||
private ImmutableArray<Sticker> _stickers = ImmutableArray.Create<Sticker>(); | |||
/// <inheritdoc /> | |||
public override bool IsTTS => _isTTS; | |||
@@ -45,6 +46,8 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
public override IReadOnlyCollection<ITag> Tags => _tags; | |||
/// <inheritdoc /> | |||
public override IReadOnlyCollection<Sticker> Stickers => _stickers; | |||
/// <inheritdoc /> | |||
public IUserMessage ReferencedMessage => _referencedMessage; | |||
internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) | |||
@@ -132,6 +135,20 @@ namespace Discord.Rest | |||
IUser refMsgAuthor = MessageHelper.GetAuthor(Discord, guild, refMsg.Author.Value, refMsg.WebhookId.ToNullable()); | |||
_referencedMessage = RestUserMessage.Create(Discord, Channel, refMsgAuthor, refMsg); | |||
} | |||
if (model.Stickers.IsSpecified) | |||
{ | |||
var value = model.Stickers.Value; | |||
if (value.Length > 0) | |||
{ | |||
var stickers = ImmutableArray.CreateBuilder<Sticker>(value.Length); | |||
for (int i = 0; i < value.Length; i++) | |||
stickers.Add(Sticker.Create(value[i])); | |||
_stickers = stickers.ToImmutable(); | |||
} | |||
else | |||
_stickers = ImmutableArray.Create<Sticker>(); | |||
} | |||
} | |||
/// <inheritdoc /> | |||
@@ -0,0 +1,48 @@ | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using Model = Discord.API.Sticker; | |||
namespace Discord | |||
{ | |||
/// <inheritdoc cref="ISticker"/> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class Sticker : ISticker | |||
{ | |||
/// <inheritdoc /> | |||
public ulong Id { get; } | |||
/// <inheritdoc /> | |||
public ulong PackId { get; } | |||
/// <inheritdoc /> | |||
public string Name { get; } | |||
/// <inheritdoc /> | |||
public string Description { get; } | |||
/// <inheritdoc /> | |||
public IReadOnlyCollection<string> Tags { get; } | |||
/// <inheritdoc /> | |||
public string Asset { get; } | |||
/// <inheritdoc /> | |||
public string PreviewAsset { get; } | |||
/// <inheritdoc /> | |||
public StickerFormatType FormatType { get; } | |||
internal Sticker(ulong id, ulong packId, string name, string description, string[] tags, string asset, string previewAsset, StickerFormatType formatType) | |||
{ | |||
Id = id; | |||
PackId = packId; | |||
Name = name; | |||
Description = description; | |||
Tags = tags.ToReadOnlyCollection(); | |||
Asset = asset; | |||
PreviewAsset = previewAsset; | |||
FormatType = formatType; | |||
} | |||
internal static Sticker Create(Model model) | |||
{ | |||
return new Sticker(model.Id, model.PackId, model.Name, model.Desription, | |||
model.Tags.IsSpecified ? model.Tags.Value.Split(',') : new string[0], | |||
model.Asset, model.PreviewAsset, model.FormatType); | |||
} | |||
private string DebuggerDisplay => $"{Name} ({Id})"; | |||
} | |||
} |
@@ -99,6 +99,8 @@ namespace Discord.WebSocket | |||
/// <inheritdoc /> | |||
public virtual IReadOnlyCollection<ITag> Tags => ImmutableArray.Create<ITag>(); | |||
/// <inheritdoc /> | |||
public virtual IReadOnlyCollection<Sticker> Stickers => ImmutableArray.Create<Sticker>(); | |||
/// <inheritdoc /> | |||
public IReadOnlyDictionary<IEmote, ReactionMetadata> 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) }); | |||
/// <inheritdoc /> | |||
@@ -194,6 +196,8 @@ namespace Discord.WebSocket | |||
IReadOnlyCollection<ulong> IMessage.MentionedRoleIds => MentionedRoles.Select(x => x.Id).ToImmutableArray(); | |||
/// <inheritdoc /> | |||
IReadOnlyCollection<ulong> IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray(); | |||
/// <inheritdoc /> | |||
IReadOnlyCollection<ISticker> IMessage.Stickers => Stickers; | |||
internal void AddReaction(SocketReaction reaction) | |||
{ | |||
@@ -23,6 +23,7 @@ namespace Discord.WebSocket | |||
private ImmutableArray<ITag> _tags = ImmutableArray.Create<ITag>(); | |||
private ImmutableArray<SocketRole> _roleMentions = ImmutableArray.Create<SocketRole>(); | |||
private ImmutableArray<SocketUser> _userMentions = ImmutableArray.Create<SocketUser>(); | |||
private ImmutableArray<Sticker> _stickers = ImmutableArray.Create<Sticker>(); | |||
/// <inheritdoc /> | |||
public override bool IsTTS => _isTTS; | |||
@@ -47,6 +48,8 @@ namespace Discord.WebSocket | |||
/// <inheritdoc /> | |||
public override IReadOnlyCollection<SocketUser> MentionedUsers => _userMentions; | |||
/// <inheritdoc /> | |||
public override IReadOnlyCollection<Sticker> Stickers => _stickers; | |||
/// <inheritdoc /> | |||
public IUserMessage ReferencedMessage => _referencedMessage; | |||
internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source) | |||
@@ -158,6 +161,20 @@ namespace Discord.WebSocket | |||
refMsgAuthor = new SocketUnknownUser(Discord, id: 0); | |||
_referencedMessage = SocketUserMessage.Create(Discord, state, refMsgAuthor, Channel, refMsg); | |||
} | |||
if (model.Stickers.IsSpecified) | |||
{ | |||
var value = model.Stickers.Value; | |||
if (value.Length > 0) | |||
{ | |||
var stickers = ImmutableArray.CreateBuilder<Sticker>(value.Length); | |||
for (int i = 0; i < value.Length; i++) | |||
stickers.Add(Sticker.Create(value[i])); | |||
_stickers = stickers.ToImmutable(); | |||
} | |||
else | |||
_stickers = ImmutableArray.Create<Sticker>(); | |||
} | |||
} | |||
/// <inheritdoc /> | |||