| @@ -3,7 +3,7 @@ using System.Diagnostics; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// A user's game activity. | |||
| /// A user's game status. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class Game : IActivity | |||
| @@ -1,7 +1,7 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// An asset for a <see cref="RichGame" /> object. | |||
| /// An asset for a <see cref="RichGame" /> object containing the text and image. | |||
| /// </summary> | |||
| public class GameAsset | |||
| { | |||
| @@ -1,11 +1,14 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Party information for a <see cref="RichGame" /> object. | |||
| /// </summary> | |||
| public class GameParty | |||
| { | |||
| internal GameParty() { } | |||
| /// <summary> | |||
| /// Gets the id of the party. | |||
| /// Gets the ID of the party. | |||
| /// </summary> | |||
| public string Id { get; internal set; } | |||
| public long Members { get; internal set; } | |||
| @@ -1,5 +1,8 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Party secret for a <see cref="RichGame" /> object. | |||
| /// </summary> | |||
| public class GameSecrets | |||
| { | |||
| /// <summary> | |||
| @@ -1,7 +1,7 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// A Discord activity, typically a game. | |||
| /// A user's activity status, typically a <see cref="Game"/>. | |||
| /// </summary> | |||
| public interface IActivity | |||
| { | |||
| @@ -2,6 +2,9 @@ using System.Diagnostics; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// A user's Rich Presence status. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RichGame : Game | |||
| { | |||
| @@ -1,13 +1,21 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Specifies the direction of where message(s) should be gotten from. </summary> | |||
| /// <summary> | |||
| /// Specifies the direction of where message(s) should be gotten from. | |||
| /// </summary> | |||
| public enum Direction | |||
| { | |||
| /// <summary> The message(s) should be retrieved before a message. </summary> | |||
| /// <summary> | |||
| /// The message(s) should be retrieved before a message. | |||
| /// </summary> | |||
| Before, | |||
| /// <summary> The message(s) should be retrieved after a message. </summary> | |||
| /// <summary> | |||
| /// The message(s) should be retrieved after a message. | |||
| /// </summary> | |||
| After, | |||
| /// <summary> The message(s) should be retrieved around a message. </summary> | |||
| /// <summary> | |||
| /// The message(s) should be retrieved around a message. | |||
| /// </summary> | |||
| Around | |||
| } | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Represents a generic category channel. | |||
| /// Represents a generic category channel. | |||
| /// </summary> | |||
| public interface ICategoryChannel : IGuildChannel | |||
| { | |||
| @@ -3,7 +3,7 @@ using System.Threading.Tasks; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Represents a generic group channel. | |||
| /// Represents a private generic group channel. | |||
| /// </summary> | |||
| public interface IGroupChannel : IMessageChannel, IPrivateChannel, IAudioChannel | |||
| { | |||
| @@ -16,12 +16,12 @@ namespace Discord | |||
| Task<IUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| #if FILESYSTEM | |||
| /// <summary> | |||
| /// Sends a file to this <paramref name="text"/> channel, with an optional caption. | |||
| /// Sends a file to this message channel, with an optional caption. | |||
| /// </summary> | |||
| Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| #endif | |||
| /// <summary> | |||
| /// Sends a file to this <paramref name="text"/> channel, with an optional caption. | |||
| /// Sends a file to this message channel, with an optional caption. | |||
| /// </summary> | |||
| Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| @@ -1,10 +1,19 @@ | |||
| using System.Collections.Generic; | |||
| using System.Collections.Generic; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Properties that are used to modify an <see cref="Emote" /> with the specified changes. | |||
| /// </summary> | |||
| public class EmoteProperties | |||
| { | |||
| /// <summary> | |||
| /// Gets or sets the name of the <see cref="Emote" /> . | |||
| /// </summary> | |||
| public Optional<string> Name { get; set; } | |||
| /// <summary> | |||
| /// Gets or sets the roles that can access this <see cref="Emote" /> . | |||
| /// </summary> | |||
| public Optional<IEnumerable<IRole>> Roles { get; set; } | |||
| } | |||
| } | |||
| @@ -9,8 +9,17 @@ namespace Discord | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class GuildEmote : Emote | |||
| { | |||
| /// <summary> | |||
| /// Gets whether this emoji is managed. | |||
| /// </summary> | |||
| public bool IsManaged { get; } | |||
| /// <summary> | |||
| /// Gets whether this emoji must be wrapped in colons. | |||
| /// </summary> | |||
| public bool RequireColons { get; } | |||
| /// <summary> | |||
| /// Gets the roles this emoji is whitelisted to. | |||
| /// </summary> | |||
| public IReadOnlyList<ulong> RoleIds { get; } | |||
| internal GuildEmote(ulong id, string name, bool animated, bool isManaged, bool requireColons, IReadOnlyList<ulong> roleIds) : base(id, name, animated) | |||
| @@ -21,6 +30,9 @@ namespace Discord | |||
| } | |||
| private string DebuggerDisplay => $"{Name} ({Id})"; | |||
| /// <summary> | |||
| /// Gets the raw representation of the emoji. | |||
| /// </summary> | |||
| public override string ToString() => $"<{(Animated ? "a" : "")}:{Name}:{Id}>"; | |||
| } | |||
| } | |||
| @@ -1,13 +1,31 @@ | |||
| namespace Discord | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Represents a Discord application created via the developer portal. | |||
| /// </summary> | |||
| public interface IApplication : ISnowflakeEntity | |||
| { | |||
| /// <summary> | |||
| /// Gets the name of the application. | |||
| /// </summary> | |||
| string Name { get; } | |||
| /// <summary> | |||
| /// Gets the description of the application. | |||
| /// </summary> | |||
| string Description { get; } | |||
| /// <summary> | |||
| /// Gets the RPC origins of the application. | |||
| /// </summary> | |||
| string[] RPCOrigins { get; } | |||
| ulong Flags { get; } | |||
| /// <summary> | |||
| /// Gets the icon URL of the application. | |||
| /// </summary> | |||
| string IconUrl { get; } | |||
| /// <summary> | |||
| /// Gets the partial user object containing info on the owner of the application. | |||
| /// </summary> | |||
| IUser Owner { get; } | |||
| } | |||
| } | |||
| @@ -2,7 +2,7 @@ using System; | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents additional information regarding the invite object. </summary> | |||
| /// <summary> Represents additional information regarding the generic invite object. </summary> | |||
| public interface IInviteMetadata : IInvite | |||
| { | |||
| /// <summary> | |||
| @@ -1,4 +1,3 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| @@ -1,4 +1,3 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| @@ -1,4 +1,3 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| @@ -1,4 +1,3 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| @@ -1,4 +1,3 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| @@ -1,25 +1,45 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Specifies the type of embed. </summary> | |||
| /// <summary> | |||
| /// Specifies the type of embed. | |||
| /// </summary> | |||
| public enum EmbedType | |||
| { | |||
| /// <summary> An unknown embed type. </summary> | |||
| /// <summary> | |||
| /// An unknown embed type. | |||
| /// </summary> | |||
| Unknown = -1, | |||
| /// <summary> A rich embed type. </summary> | |||
| /// <summary> | |||
| /// A rich embed type. | |||
| /// </summary> | |||
| Rich, | |||
| /// <summary> A link embed type. </summary> | |||
| /// <summary> | |||
| /// A link embed type. | |||
| /// </summary> | |||
| Link, | |||
| /// <summary> A video embed type. </summary> | |||
| /// <summary> | |||
| /// A video embed type. | |||
| /// </summary> | |||
| Video, | |||
| /// <summary> An image embed type. </summary> | |||
| /// <summary> | |||
| /// An image embed type. | |||
| /// </summary> | |||
| Image, | |||
| /// <summary> A GIFV embed type. </summary> | |||
| /// <summary> | |||
| /// A GIFV embed type. | |||
| /// </summary> | |||
| Gifv, | |||
| /// <summary> An article embed type. </summary> | |||
| /// <summary> | |||
| /// An article embed type. | |||
| /// </summary> | |||
| Article, | |||
| /// <summary> A tweet embed type. </summary> | |||
| /// <summary> | |||
| /// A tweet embed type. | |||
| /// </summary> | |||
| Tweet, | |||
| /// <summary> A HTML embed type. </summary> | |||
| /// <summary> | |||
| /// A HTML embed type. | |||
| /// </summary> | |||
| Html, | |||
| } | |||
| } | |||
| @@ -1,17 +1,24 @@ | |||
| using System; | |||
| using System.Diagnostics; | |||
| namespace Discord | |||
| { | |||
| /// <summary> A video featured in an <see cref="Embed"/>. </summary> | |||
| /// <summary> | |||
| /// A video featured in an <see cref="Embed" /> . | |||
| /// </summary> | |||
| [DebuggerDisplay("{DebuggerDisplay,nq}")] | |||
| public struct EmbedVideo | |||
| { | |||
| /// <summary> Gets the URL of the video. </summary> | |||
| /// <summary> | |||
| /// Gets the URL of the video. | |||
| /// </summary> | |||
| public string Url { get; } | |||
| /// <summary> Gets the height of the video if there is any. </summary> | |||
| /// <summary> | |||
| /// Gets the height of the video, or <see langword="null"/> if none. | |||
| /// </summary> | |||
| public int? Height { get; } | |||
| /// <summary> Gets the weight of the video if there is any. </summary> | |||
| /// <summary> | |||
| /// Gets the weight of the video, or <see langword="null"/> if none. | |||
| /// </summary> | |||
| public int? Width { get; } | |||
| internal EmbedVideo(string url, int? height, int? width) | |||
| @@ -22,6 +29,9 @@ namespace Discord | |||
| } | |||
| private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | |||
| public override string ToString() => Url.ToString(); | |||
| /// <summary> | |||
| /// Gets the URL of the video. | |||
| /// </summary> | |||
| public override string ToString() => Url; | |||
| } | |||
| } | |||
| @@ -1,22 +1,38 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a Discord attachment. </summary> | |||
| /// <summary> | |||
| /// Represents a Discord attachment. | |||
| /// </summary> | |||
| public interface IAttachment | |||
| { | |||
| /// <summary> Gets the snowflake ID of the attachment. </summary> | |||
| /// <summary> | |||
| /// Gets the snowflake ID of the attachment. | |||
| /// </summary> | |||
| ulong Id { get; } | |||
| /// <summary> Gets the filename of the attachment. </summary> | |||
| /// <summary> | |||
| /// Gets the filename of the attachment. | |||
| /// </summary> | |||
| string Filename { get; } | |||
| /// <summary> Gets the URL of the attachment. </summary> | |||
| /// <summary> | |||
| /// Gets the URL of the attachment. | |||
| /// </summary> | |||
| string Url { get; } | |||
| /// <summary> Gets the proxied URL of the attachment. </summary> | |||
| /// <summary> | |||
| /// Gets the proxied URL of the attachment. | |||
| /// </summary> | |||
| string ProxyUrl { get; } | |||
| /// <summary> Gets the file size of the attachment. </summary> | |||
| /// <summary> | |||
| /// Gets the file size of the attachment. | |||
| /// </summary> | |||
| int Size { get; } | |||
| /// <summary> Gets the height of the attachment if it is an image, or return <see langword="null"/> when it is not. </summary> | |||
| /// <summary> | |||
| /// Gets the height of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
| /// </summary> | |||
| int? Height { get; } | |||
| /// <summary> Gets the width of the attachment if it is an image, or return <see langword="null"/> when it is not. </summary> | |||
| /// <summary> | |||
| /// Gets the width of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
| /// </summary> | |||
| int? Width { get; } | |||
| } | |||
| } | |||
| @@ -3,34 +3,62 @@ using System.Collections.Immutable; | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a Discord embed object. </summary> | |||
| /// <summary> | |||
| /// Represents a Discord embed object. | |||
| /// </summary> | |||
| public interface IEmbed | |||
| { | |||
| /// <summary> Gets the title URL of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the title URL of the embed. | |||
| /// </summary> | |||
| string Url { get; } | |||
| /// <summary> Gets the title of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the title of the embed. | |||
| /// </summary> | |||
| string Title { get; } | |||
| /// <summary> Gets the description of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the description of the embed. | |||
| /// </summary> | |||
| string Description { get; } | |||
| /// <summary> Gets the type of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the type of the embed. | |||
| /// </summary> | |||
| EmbedType Type { get; } | |||
| /// <summary> Gets the timestamp of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the timestamp of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| DateTimeOffset? Timestamp { get; } | |||
| /// <summary> Gets the sidebar color of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the sidebar color of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| Color? Color { get; } | |||
| /// <summary> Gets the image of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the image of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedImage? Image { get; } | |||
| /// <summary> Gets the video of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the video of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedVideo? Video { get; } | |||
| /// <summary> Gets the author field of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the author field of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedAuthor? Author { get; } | |||
| /// <summary> Gets the footer field of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the footer field of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedFooter? Footer { get; } | |||
| /// <summary> Gets the provider of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the provider of the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedProvider? Provider { get; } | |||
| /// <summary> Gets the thumbnail featured in the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the thumbnail featured in the embed, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| EmbedThumbnail? Thumbnail { get; } | |||
| /// <summary> Gets the fields of the embed. </summary> | |||
| /// <summary> | |||
| /// Gets the fields of the embed. | |||
| /// </summary> | |||
| ImmutableArray<EmbedField> Fields { get; } | |||
| } | |||
| } | |||
| @@ -3,40 +3,72 @@ using System.Collections.Generic; | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a Discord message object. </summary> | |||
| /// <summary> | |||
| /// Represents a Discord message object. | |||
| /// </summary> | |||
| public interface IMessage : ISnowflakeEntity, IDeletable | |||
| { | |||
| /// <summary> Gets the type of this system message. </summary> | |||
| /// <summary> | |||
| /// Gets the type of this system message. | |||
| /// </summary> | |||
| MessageType Type { get; } | |||
| /// <summary> Gets the source of this message. </summary> | |||
| /// <summary> | |||
| /// Gets the source type of this message. | |||
| /// </summary> | |||
| MessageSource Source { get; } | |||
| /// <summary> Returns true if this message was sent as a text-to-speech message. </summary> | |||
| /// <summary> | |||
| /// Returns <see langword="true"/> if this message was sent as a text-to-speech message. | |||
| /// </summary> | |||
| bool IsTTS { get; } | |||
| /// <summary> Returns true if this message was added to its channel's pinned messages. </summary> | |||
| /// <summary> | |||
| /// Returns <see langword="true"/> if this message was added to its channel's pinned messages. | |||
| /// </summary> | |||
| bool IsPinned { get; } | |||
| /// <summary> Returns the content for this message. </summary> | |||
| /// <summary> | |||
| /// Returns the content for this message. | |||
| /// </summary> | |||
| string Content { get; } | |||
| /// <summary> Gets the time this message was sent. </summary> | |||
| /// <summary> | |||
| /// Gets the time this message was sent. | |||
| /// </summary> | |||
| DateTimeOffset Timestamp { get; } | |||
| /// <summary> Gets the time of this message's last edit, if any. </summary> | |||
| /// <summary> | |||
| /// Gets the time of this message's last edit, or <see langword="null" /> if none is set. | |||
| /// </summary> | |||
| DateTimeOffset? EditedTimestamp { get; } | |||
| /// <summary> Gets the channel this message was sent to. </summary> | |||
| /// <summary> | |||
| /// Gets the channel this message was sent to. | |||
| /// </summary> | |||
| IMessageChannel Channel { get; } | |||
| /// <summary> Gets the author of this message. </summary> | |||
| /// <summary> | |||
| /// Gets the author of this message. | |||
| /// </summary> | |||
| IUser Author { get; } | |||
| /// <summary> Returns all attachments included in this message. </summary> | |||
| /// <summary> | |||
| /// Returns all attachments included in this message. | |||
| /// </summary> | |||
| IReadOnlyCollection<IAttachment> Attachments { get; } | |||
| /// <summary> Returns all embeds included in this message. </summary> | |||
| /// <summary> | |||
| /// Returns all embeds included in this message. | |||
| /// </summary> | |||
| IReadOnlyCollection<IEmbed> Embeds { get; } | |||
| /// <summary> Returns all tags included in this message's content. </summary> | |||
| /// <summary> | |||
| /// Returns all tags included in this message's content. | |||
| /// </summary> | |||
| IReadOnlyCollection<ITag> Tags { get; } | |||
| /// <summary> Returns the ids of channels mentioned in this message. </summary> | |||
| /// <summary> | |||
| /// Returns the IDs of channels mentioned in this message. | |||
| /// </summary> | |||
| IReadOnlyCollection<ulong> MentionedChannelIds { get; } | |||
| /// <summary> Returns the ids of roles mentioned in this message. </summary> | |||
| /// <summary> | |||
| /// Returns the IDs of roles mentioned in this message. | |||
| /// </summary> | |||
| IReadOnlyCollection<ulong> MentionedRoleIds { get; } | |||
| /// <summary> Returns the ids of users mentioned in this message. </summary> | |||
| /// <summary> | |||
| /// Returns the IDs of users mentioned in this message. | |||
| /// </summary> | |||
| IReadOnlyCollection<ulong> MentionedUserIds { get; } | |||
| } | |||
| } | |||
| @@ -1,9 +1,13 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a Discord reaction object. </summary> | |||
| /// <summary> | |||
| /// Represents a generic reaction object. | |||
| /// </summary> | |||
| public interface IReaction | |||
| { | |||
| /// <summary> The <see cref="IEmote"/> used in the reaction. </summary> | |||
| /// <summary> | |||
| /// The <see cref="IEmote" /> used in the reaction. | |||
| /// </summary> | |||
| IEmote Emote { get; } | |||
| } | |||
| } | |||
| @@ -1,6 +1,8 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a message sent by the system. </summary> | |||
| /// <summary> | |||
| /// Represents a message sent by the system. | |||
| /// </summary> | |||
| public interface ISystemMessage : IMessage | |||
| { | |||
| } | |||
| @@ -4,29 +4,49 @@ using System.Threading.Tasks; | |||
| namespace Discord | |||
| { | |||
| /// <summary> Represents a Discord message object. </summary> | |||
| /// <summary> | |||
| /// Represents a Discord message object. | |||
| /// </summary> | |||
| public interface IUserMessage : IMessage | |||
| { | |||
| /// <summary> Modifies this message. </summary> | |||
| /// <summary> | |||
| /// Modifies this message. | |||
| /// </summary> | |||
| Task ModifyAsync(Action<MessageProperties> func, RequestOptions options = null); | |||
| /// <summary> Adds this message to its channel's pinned messages. </summary> | |||
| /// <summary> | |||
| /// Adds this message to its channel's pinned messages. | |||
| /// </summary> | |||
| Task PinAsync(RequestOptions options = null); | |||
| /// <summary> Removes this message from its channel's pinned messages. </summary> | |||
| /// <summary> | |||
| /// Removes this message from its channel's pinned messages. | |||
| /// </summary> | |||
| Task UnpinAsync(RequestOptions options = null); | |||
| /// <summary> Returns all reactions included in this message. </summary> | |||
| /// <summary> | |||
| /// Returns all reactions included in this message. | |||
| /// </summary> | |||
| IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions { get; } | |||
| /// <summary> Adds a reaction to this message. </summary> | |||
| /// <summary> | |||
| /// Adds a reaction to this message. | |||
| /// </summary> | |||
| Task AddReactionAsync(IEmote emote, RequestOptions options = null); | |||
| /// <summary> Removes a reaction from message. </summary> | |||
| /// <summary> | |||
| /// Removes a reaction from message. | |||
| /// </summary> | |||
| Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null); | |||
| /// <summary> Removes all reactions from this message. </summary> | |||
| /// <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> | |||
| /// <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); | |||
| /// <summary> Transforms this message's text into a human-readable form by resolving its tags. </summary> | |||
| /// <summary> | |||
| /// Transforms this message's text into a human-readable form by resolving its tags. | |||
| /// </summary> | |||
| string Resolve( | |||
| TagHandling userHandling = TagHandling.Name, | |||
| TagHandling channelHandling = TagHandling.Name, | |||
| @@ -1,36 +1,36 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Properties that are used to modify an <see cref="IUserMessage"/> with the specified changes. | |||
| /// Properties that are used to modify an <see cref="IUserMessage" /> with the specified changes. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// The content of a message can be cleared with String.Empty; if and only if an Embed is present. | |||
| /// The content of a message can be cleared with String.Empty; if and only if an Embed is present. | |||
| /// </remarks> | |||
| /// <example> | |||
| /// <code language="c#"> | |||
| /// var message = await ReplyAsync("abc"); | |||
| /// await message.ModifyAsync(x => | |||
| /// { | |||
| /// x.Content = ""; | |||
| /// x.Embed = new EmbedBuilder() | |||
| /// .WithColor(new Color(40, 40, 120)) | |||
| /// .WithAuthor(a => a.Name = "foxbot") | |||
| /// .WithTitle("Embed!") | |||
| /// .WithDescription("This is an embed."); | |||
| /// }); | |||
| /// </code> | |||
| /// <code lang="c#"> | |||
| /// var message = await ReplyAsync("abc"); | |||
| /// await message.ModifyAsync(x => | |||
| /// { | |||
| /// x.Content = ""; | |||
| /// x.Embed = new EmbedBuilder() | |||
| /// .WithColor(new Color(40, 40, 120)) | |||
| /// .WithAuthor(a => a.Name = "foxbot") | |||
| /// .WithTitle("Embed!") | |||
| /// .WithDescription("This is an embed."); | |||
| /// }); | |||
| /// </code> | |||
| /// </example> | |||
| public class MessageProperties | |||
| { | |||
| /// <summary> | |||
| /// The content of the message. | |||
| /// Gets or sets the content of the message. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// This must be less than 2000 characters. | |||
| /// This must be less than 2000 characters. | |||
| /// </remarks> | |||
| public Optional<string> Content { get; set; } | |||
| /// <summary> | |||
| /// The embed the message should display. | |||
| /// Gets or sets the embed the message should display. | |||
| /// </summary> | |||
| public Optional<Embed> Embed { get; set; } | |||
| } | |||
| @@ -1,15 +1,25 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Specifies the source of the Discord message. </summary> | |||
| /// <summary> | |||
| /// Specifies the source of the Discord message. | |||
| /// </summary> | |||
| public enum MessageSource | |||
| { | |||
| /// <summary> The message is sent by the system. </summary> | |||
| /// <summary> | |||
| /// The message is sent by the system. | |||
| /// </summary> | |||
| System, | |||
| /// <summary> The message is sent by a user. </summary> | |||
| /// <summary> | |||
| /// The message is sent by a user. | |||
| /// </summary> | |||
| User, | |||
| /// <summary> The message is sent by a bot. </summary> | |||
| /// <summary> | |||
| /// The message is sent by a bot. | |||
| /// </summary> | |||
| Bot, | |||
| /// <summary> The message is sent by a webhook. </summary> | |||
| /// <summary> | |||
| /// The message is sent by a webhook. | |||
| /// </summary> | |||
| Webhook | |||
| } | |||
| } | |||
| @@ -1,21 +1,37 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> Specifies the type of message. </summary> | |||
| /// <summary> | |||
| /// Specifies the type of message. | |||
| /// </summary> | |||
| public enum MessageType | |||
| { | |||
| /// <summary> The default message type. </summary> | |||
| /// <summary> | |||
| /// The default message type. | |||
| /// </summary> | |||
| Default = 0, | |||
| /// <summary> The message when a recipient is added. </summary> | |||
| /// <summary> | |||
| /// The message when a recipient is added. | |||
| /// </summary> | |||
| RecipientAdd = 1, | |||
| /// <summary> The message when a recipient is removed. </summary> | |||
| /// <summary> | |||
| /// The message when a recipient is removed. | |||
| /// </summary> | |||
| RecipientRemove = 2, | |||
| /// <summary> The message when a user is called. </summary> | |||
| /// <summary> | |||
| /// The message when a user is called. | |||
| /// </summary> | |||
| Call = 3, | |||
| /// <summary> The message when a channel name is changed. </summary> | |||
| /// <summary> | |||
| /// The message when a channel name is changed. | |||
| /// </summary> | |||
| ChannelNameChange = 4, | |||
| /// <summary> The message when a channel icon is changed. </summary> | |||
| /// <summary> | |||
| /// The message when a channel icon is changed. | |||
| /// </summary> | |||
| ChannelIconChange = 5, | |||
| /// <summary> The message when another message is pinned. </summary> | |||
| /// <summary> | |||
| /// The message when another message is pinned. | |||
| /// </summary> | |||
| ChannelPinnedMessage = 6 | |||
| } | |||
| } | |||
| @@ -1,12 +1,18 @@ | |||
| namespace Discord | |||
| { | |||
| /// <summary> A metadata containing reaction information. </summary> | |||
| /// <summary> | |||
| /// A metadata containing reaction information. | |||
| /// </summary> | |||
| public struct ReactionMetadata | |||
| { | |||
| /// <summary> Gets the number of reactions. </summary> | |||
| /// <summary> | |||
| /// Gets the number of reactions. | |||
| /// </summary> | |||
| public int ReactionCount { get; internal set; } | |||
| /// <summary> Returns true if the current user has used this reaction. </summary> | |||
| /// <summary> | |||
| /// Returns <see langword="true"/> if the current user has used this reaction. | |||
| /// </summary> | |||
| public bool IsMe { get; internal set; } | |||
| } | |||
| } | |||
| @@ -17,21 +17,21 @@ namespace Discord | |||
| public class GuildUserProperties | |||
| { | |||
| /// <summary> | |||
| /// Sets whether the user should be muted in a voice channel. | |||
| /// Gets or sets whether the user should be muted in a voice channel. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If this value is set to <see langword="true"/>, no user will be able to hear this user speak in the guild. | |||
| /// </remarks> | |||
| public Optional<bool> Mute { get; set; } | |||
| /// <summary> | |||
| /// Sets whether the user should be deafened in a voice channel. | |||
| /// Gets or sets whether the user should be deafened in a voice channel. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// If this value is set to <see langword="true"/>, this user will not be able to hear anyone speak in the guild. | |||
| /// </remarks> | |||
| public Optional<bool> Deaf { get; set; } | |||
| /// <summary> | |||
| /// Sets the user's nickname. | |||
| /// Gets or sets the user's nickname. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// To clear the user's nickname, this value can be set to <see langword="null" /> or | |||
| @@ -39,7 +39,7 @@ namespace Discord | |||
| /// </remarks> | |||
| public Optional<string> Nickname { get; set; } | |||
| /// <summary> | |||
| /// Sets the roles the user should have. | |||
| /// Gets or sets the roles the user should have. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// <para> | |||
| @@ -53,7 +53,7 @@ namespace Discord | |||
| /// </remarks> | |||
| public Optional<IEnumerable<IRole>> Roles { get; set; } | |||
| /// <summary> | |||
| /// Sets the roles the user should have. | |||
| /// Gets or sets the roles the user should have. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// <para> | |||
| @@ -15,11 +15,11 @@ namespace Discord | |||
| public class SelfUserProperties | |||
| { | |||
| /// <summary> | |||
| /// Sets the username. | |||
| /// Gets or sets the username. | |||
| /// </summary> | |||
| public Optional<string> Username { get; set; } | |||
| /// <summary> | |||
| /// Sets the avatar. | |||
| /// Gets or sets the avatar. | |||
| /// </summary> | |||
| public Optional<Image?> Avatar { get; set; } | |||
| } | |||
| @@ -4,7 +4,7 @@ namespace Discord | |||
| public static class Format | |||
| { | |||
| // Characters which need escaping | |||
| private static string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||
| private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||
| /// <summary> Returns a markdown-formatted string with bold formatting. </summary> | |||
| public static string Bold(string text) => $"**{text}**"; | |||
| @@ -2,6 +2,9 @@ using System.Threading; | |||
| namespace Discord | |||
| { | |||
| /// <summary> | |||
| /// Represents options that should be used when sending a request. | |||
| /// </summary> | |||
| public class RequestOptions | |||
| { | |||
| /// <summary> | |||
| @@ -7,8 +7,17 @@ namespace Discord | |||
| { | |||
| [Obsolete("User logins are deprecated and may result in a ToS strike against your account - please see https://github.com/RogueException/Discord.Net/issues/827", error: true)] | |||
| User, | |||
| /// <summary> | |||
| /// An OAuth2 token type. | |||
| /// </summary> | |||
| Bearer, | |||
| /// <summary> | |||
| /// A bot token type. | |||
| /// </summary> | |||
| Bot, | |||
| /// <summary> | |||
| /// A webhook token type. | |||
| /// </summary> | |||
| Webhook | |||
| } | |||
| } | |||
| @@ -4,26 +4,45 @@ using System.Threading.Tasks; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST channel that can send and receive messages. | |||
| /// </summary> | |||
| public interface IRestMessageChannel : IMessageChannel | |||
| { | |||
| /// <summary> Sends a message to this message channel. </summary> | |||
| /// <summary> | |||
| /// Sends a message to this message channel. | |||
| /// </summary> | |||
| new Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| #if FILESYSTEM | |||
| /// <summary> Sends a file to this text channel, with an optional caption. </summary> | |||
| /// <summary> | |||
| /// Sends a file to this message channel, with an optional caption. | |||
| /// </summary> | |||
| new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| #endif | |||
| /// <summary> Sends a file to this text channel, with an optional caption. </summary> | |||
| /// <summary> | |||
| /// Sends a file to this message channel, with an optional caption. | |||
| /// </summary> | |||
| new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
| /// <summary> Gets a message from this message channel with the given id, or null if not found. </summary> | |||
| /// <summary> | |||
| /// Gets a message from this message channel with the given ID, or <see langword="null"/> if not found. | |||
| /// </summary> | |||
| Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null); | |||
| /// <summary> Gets the last N messages from this message channel. </summary> | |||
| /// <summary> | |||
| /// Gets the last N messages from this message channel. | |||
| /// </summary> | |||
| IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null); | |||
| /// <summary> Gets a collection of messages in this channel. </summary> | |||
| /// <summary> | |||
| /// Gets a collection of messages in this channel. | |||
| /// </summary> | |||
| IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null); | |||
| /// <summary> Gets a collection of messages in this channel. </summary> | |||
| /// <summary> | |||
| /// Gets a collection of messages in this channel. | |||
| /// </summary> | |||
| IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null); | |||
| /// <summary> Gets a collection of pinned messages in this channel. </summary> | |||
| /// <summary> | |||
| /// Gets a collection of pinned messages in this channel. | |||
| /// </summary> | |||
| new Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null); | |||
| } | |||
| } | |||
| @@ -1,9 +1,15 @@ | |||
| using System.Collections.Generic; | |||
| using System.Collections.Generic; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST channel that is private to select recipients. | |||
| /// </summary> | |||
| public interface IRestPrivateChannel : IPrivateChannel | |||
| { | |||
| /// <summary> | |||
| /// Users that can access this channel. | |||
| /// </summary> | |||
| new IReadOnlyCollection<RestUser> Recipients { get; } | |||
| } | |||
| } | |||
| @@ -1,13 +1,14 @@ | |||
| using System; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Model = Discord.API.Channel; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST category channel. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RestCategoryChannel : RestGuildChannel, ICategoryChannel | |||
| { | |||
| @@ -9,11 +9,14 @@ using Model = Discord.API.Channel; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST DM channel. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel, IUpdateable | |||
| public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel | |||
| { | |||
| public RestUser CurrentUser { get; private set; } | |||
| public RestUser Recipient { get; private set; } | |||
| public RestUser CurrentUser { get; } | |||
| public RestUser Recipient { get; } | |||
| public IReadOnlyCollection<RestUser> Users => ImmutableArray.Create(CurrentUser, Recipient); | |||
| @@ -39,6 +42,7 @@ namespace Discord.Rest | |||
| var model = await Discord.ApiClient.GetChannelAsync(Id, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task CloseAsync(RequestOptions options = null) | |||
| => ChannelHelper.DeleteAsync(this, Discord, options); | |||
| @@ -52,26 +56,35 @@ namespace Discord.Rest | |||
| return null; | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null) | |||
| => ChannelHelper.GetMessageAsync(this, Discord, id, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options); | |||
| /// <inheritdoc /> | |||
| public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null) | |||
| => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); | |||
| #if FILESYSTEM | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); | |||
| #endif | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); | |||
| /// <inheritdoc /> | |||
| public Task TriggerTypingAsync(RequestOptions options = null) | |||
| => ChannelHelper.TriggerTypingAsync(this, Discord, options); | |||
| public IDisposable EnterTypingState(RequestOptions options = null) | |||
| @@ -11,11 +11,12 @@ using Model = Discord.API.Channel; | |||
| namespace Discord.Rest | |||
| { | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel, IUpdateable | |||
| public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel | |||
| { | |||
| private string _iconId; | |||
| private ImmutableDictionary<ulong, RestGroupUser> _users; | |||
| /// <inheritdoc /> | |||
| public string Name { get; private set; } | |||
| public IReadOnlyCollection<RestGroupUser> Users => _users.ToReadOnlyCollection(); | |||
| @@ -49,12 +50,13 @@ namespace Discord.Rest | |||
| users[models[i].Id] = RestGroupUser.Create(Discord, models[i]); | |||
| _users = users.ToImmutable(); | |||
| } | |||
| /// <inheritdoc /> | |||
| public override async Task UpdateAsync(RequestOptions options = null) | |||
| { | |||
| var model = await Discord.ApiClient.GetChannelAsync(Id, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task LeaveAsync(RequestOptions options = null) | |||
| => ChannelHelper.DeleteAsync(this, Discord, options); | |||
| @@ -65,26 +67,35 @@ namespace Discord.Rest | |||
| return null; | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null) | |||
| => ChannelHelper.GetMessageAsync(this, Discord, id, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options); | |||
| /// <inheritdoc /> | |||
| public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null) | |||
| => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options); | |||
| /// <inheritdoc /> | |||
| public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null) | |||
| => ChannelHelper.GetPinnedMessagesAsync(this, Discord, options); | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options); | |||
| #if FILESYSTEM | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options); | |||
| #endif | |||
| /// <inheritdoc /> | |||
| public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null) | |||
| => ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options); | |||
| /// <inheritdoc /> | |||
| public Task TriggerTypingAsync(RequestOptions options = null) | |||
| => ChannelHelper.TriggerTypingAsync(this, Discord, options); | |||
| public IDisposable EnterTypingState(RequestOptions options = null) | |||
| @@ -1,4 +1,4 @@ | |||
| using System; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.Immutable; | |||
| using System.Linq; | |||
| @@ -7,16 +7,24 @@ using Model = Discord.API.Channel; | |||
| namespace Discord.Rest | |||
| { | |||
| public class RestGuildChannel : RestChannel, IGuildChannel, IUpdateable | |||
| /// <summary> | |||
| /// Represents a private REST group channel. | |||
| /// </summary> | |||
| public class RestGuildChannel : RestChannel, IGuildChannel | |||
| { | |||
| private ImmutableArray<Overwrite> _overwrites; | |||
| /// <inheritdoc /> | |||
| public IReadOnlyCollection<Overwrite> PermissionOverwrites => _overwrites; | |||
| internal IGuild Guild { get; } | |||
| /// <inheritdoc /> | |||
| public string Name { get; private set; } | |||
| /// <inheritdoc /> | |||
| public int Position { get; private set; } | |||
| /// <inheritdoc /> | |||
| public ulong? CategoryId { get; private set; } | |||
| /// <inheritdoc /> | |||
| public ulong GuildId => Guild.Id; | |||
| internal RestGuildChannel(BaseDiscordClient discord, IGuild guild, ulong id) | |||
| @@ -51,19 +59,23 @@ namespace Discord.Rest | |||
| _overwrites = newOverwrites.ToImmutable(); | |||
| } | |||
| /// <inheritdoc /> | |||
| public override async Task UpdateAsync(RequestOptions options = null) | |||
| { | |||
| var model = await Discord.ApiClient.GetChannelAsync(GuildId, Id, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public async Task ModifyAsync(Action<GuildChannelProperties> func, RequestOptions options = null) | |||
| { | |||
| var model = await ChannelHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task DeleteAsync(RequestOptions options = null) | |||
| => ChannelHelper.DeleteAsync(this, Discord, options); | |||
| /// <inheritdoc /> | |||
| public async Task<ICategoryChannel> GetCategoryAsync() | |||
| { | |||
| if (CategoryId.HasValue) | |||
| @@ -1,4 +1,4 @@ | |||
| using System; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using System.Threading.Tasks; | |||
| using Model = Discord.API.Invite; | |||
| @@ -8,14 +8,20 @@ namespace Discord.Rest | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RestInvite : RestEntity<string>, IInvite, IUpdateable | |||
| { | |||
| /// <inheritdoc /> | |||
| public string ChannelName { get; private set; } | |||
| /// <inheritdoc /> | |||
| public string GuildName { get; private set; } | |||
| /// <inheritdoc /> | |||
| public ulong ChannelId { get; private set; } | |||
| /// <inheritdoc /> | |||
| public ulong GuildId { get; private set; } | |||
| internal IChannel Channel { get; private set; } | |||
| internal IGuild Guild { get; private set; } | |||
| internal IChannel Channel { get; } | |||
| internal IGuild Guild { get; } | |||
| /// <inheritdoc /> | |||
| public string Code => Id; | |||
| /// <inheritdoc /> | |||
| public string Url => $"{DiscordConfig.InviteUrl}{Code}"; | |||
| internal RestInvite(BaseDiscordClient discord, IGuild guild, IChannel channel, string id) | |||
| @@ -37,15 +43,17 @@ namespace Discord.Rest | |||
| GuildName = model.Guild.Name; | |||
| ChannelName = model.Channel.Name; | |||
| } | |||
| /// <inheritdoc /> | |||
| public async Task UpdateAsync(RequestOptions options = null) | |||
| { | |||
| var model = await Discord.ApiClient.GetInviteAsync(Code, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task DeleteAsync(RequestOptions options = null) | |||
| => InviteHelper.DeleteAsync(this, Discord, options); | |||
| /// <inheritdoc /> | |||
| public Task AcceptAsync(RequestOptions options = null) | |||
| => InviteHelper.AcceptAsync(this, Discord, options); | |||
| @@ -1,19 +1,29 @@ | |||
| using System; | |||
| using System; | |||
| using Model = Discord.API.InviteMetadata; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> Represents additional information regarding the REST invite object. </summary> | |||
| public class RestInviteMetadata : RestInvite, IInviteMetadata | |||
| { | |||
| private long _createdAtTicks; | |||
| /// <inheritdoc /> | |||
| public bool IsRevoked { get; private set; } | |||
| /// <inheritdoc /> | |||
| public bool IsTemporary { get; private set; } | |||
| /// <inheritdoc /> | |||
| public int? MaxAge { get; private set; } | |||
| /// <inheritdoc /> | |||
| public int? MaxUses { get; private set; } | |||
| /// <inheritdoc /> | |||
| public int Uses { get; private set; } | |||
| /// <summary> | |||
| /// Gets the user that created this invite. | |||
| /// </summary> | |||
| public RestUser Inviter { get; private set; } | |||
| /// <inheritdoc /> | |||
| public DateTimeOffset CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks); | |||
| internal RestInviteMetadata(BaseDiscordClient discord, IGuild guild, IChannel channel, string id) | |||
| @@ -1,4 +1,4 @@ | |||
| using System; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.Immutable; | |||
| using System.Linq; | |||
| @@ -11,23 +11,33 @@ namespace Discord.Rest | |||
| { | |||
| private long _timestampTicks; | |||
| /// <inheritdoc /> | |||
| public IMessageChannel Channel { get; } | |||
| public IUser Author { get; } | |||
| /// <inheritdoc /> | |||
| public MessageSource Source { get; } | |||
| /// <inheritdoc /> | |||
| public string Content { get; private set; } | |||
| /// <inheritdoc /> | |||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | |||
| /// <inheritdoc /> | |||
| public virtual bool IsTTS => false; | |||
| /// <inheritdoc /> | |||
| public virtual bool IsPinned => false; | |||
| /// <inheritdoc /> | |||
| public virtual DateTimeOffset? EditedTimestamp => null; | |||
| public virtual IReadOnlyCollection<Attachment> Attachments => ImmutableArray.Create<Attachment>(); | |||
| public virtual IReadOnlyCollection<Embed> Embeds => ImmutableArray.Create<Embed>(); | |||
| /// <inheritdoc /> | |||
| public virtual IReadOnlyCollection<ulong> MentionedChannelIds => ImmutableArray.Create<ulong>(); | |||
| /// <inheritdoc /> | |||
| public virtual IReadOnlyCollection<ulong> MentionedRoleIds => ImmutableArray.Create<ulong>(); | |||
| public virtual IReadOnlyCollection<RestUser> MentionedUsers => ImmutableArray.Create<RestUser>(); | |||
| public virtual IReadOnlyCollection<ITag> Tags => ImmutableArray.Create<ITag>(); | |||
| /// <inheritdoc /> | |||
| public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks); | |||
| internal RestMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) | |||
| @@ -53,11 +63,13 @@ namespace Discord.Rest | |||
| Content = model.Content.Value; | |||
| } | |||
| /// <inheritdoc /> | |||
| public async Task UpdateAsync(RequestOptions options = null) | |||
| { | |||
| var model = await Discord.ApiClient.GetChannelMessageAsync(Channel.Id, Id, options).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task DeleteAsync(RequestOptions options = null) | |||
| => MessageHelper.DeleteAsync(this, Discord, options); | |||
| @@ -1,11 +1,21 @@ | |||
| using Model = Discord.API.Reaction; | |||
| using Model = Discord.API.Reaction; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST reaction object. | |||
| /// </summary> | |||
| public class RestReaction : IReaction | |||
| { | |||
| /// <inheritdoc /> | |||
| public IEmote Emote { get; } | |||
| /// <summary> | |||
| /// Gets the number of reactions added. | |||
| /// </summary> | |||
| public int Count { get; } | |||
| /// <summary> | |||
| /// Gets whether the reactions is added by the user. | |||
| /// </summary> | |||
| public bool Me { get; } | |||
| internal RestReaction(IEmote emote, int count, bool me) | |||
| @@ -1,23 +1,32 @@ | |||
| using System; | |||
| using System; | |||
| using System.Diagnostics; | |||
| using System.Threading.Tasks; | |||
| using Model = Discord.API.Application; | |||
| namespace Discord.Rest | |||
| { | |||
| /// <summary> | |||
| /// Represents a REST entity that contains information about a Discord application created via the developer portal. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class RestApplication : RestEntity<ulong>, IApplication | |||
| { | |||
| protected string _iconId; | |||
| /// <inheritdoc /> | |||
| public string Name { get; private set; } | |||
| /// <inheritdoc /> | |||
| public string Description { get; private set; } | |||
| /// <inheritdoc /> | |||
| public string[] RPCOrigins { get; private set; } | |||
| public ulong Flags { get; private set; } | |||
| /// <inheritdoc /> | |||
| public IUser Owner { get; private set; } | |||
| /// <inheritdoc /> | |||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | |||
| /// <inheritdoc /> | |||
| public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId); | |||
| internal RestApplication(BaseDiscordClient discord, ulong id) | |||
| @@ -14,6 +14,9 @@ using VoiceStateModel = Discord.API.VoiceState; | |||
| namespace Discord.WebSocket | |||
| { | |||
| /// <summary> | |||
| /// Represents a private WebSocket group channel. | |||
| /// </summary> | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel | |||
| { | |||