| @@ -46,6 +46,24 @@ namespace Discord | |||||
| string extension = FormatToExtension(format, avatarId); | string extension = FormatToExtension(format, avatarId); | ||||
| return $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.{extension}?size={size}"; | return $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.{extension}?size={size}"; | ||||
| } | } | ||||
| /// <summary> | |||||
| /// Returns a user banner URL. | |||||
| /// </summary> | |||||
| /// <param name="userId">The user snowflake identifier.</param> | |||||
| /// <param name="bannerId">The banner identifier.</param> | |||||
| /// <param name="size">The size of the image to return in horizontal pixels. This can be any power of two between 16 and 2048.</param> | |||||
| /// <param name="format">The format to return.</param> | |||||
| /// <returns> | |||||
| /// A URL pointing to the user's banner in the specified size. | |||||
| /// </returns> | |||||
| public static string GetUserBannerUrl(ulong userId, string bannerId, ushort size, ImageFormat format) | |||||
| { | |||||
| if (bannerId == null) | |||||
| return null; | |||||
| string extension = FormatToExtension(format, bannerId); | |||||
| return $"{DiscordConfig.CDNUrl}banners/{userId}/{bannerId}.{extension}?size={size}"; | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Returns the default user avatar URL. | /// Returns the default user avatar URL. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -10144,6 +10144,11 @@ | |||||
| Gets the user that created this webhook. | Gets the user that created this webhook. | ||||
| </summary> | </summary> | ||||
| </member> | </member> | ||||
| <member name="P:Discord.IWebhook.ApplicationId"> | |||||
| <summary> | |||||
| Gets the ID of the application owning this webhook. | |||||
| </summary> | |||||
| </member> | |||||
| <member name="M:Discord.IWebhook.ModifyAsync(System.Action{Discord.WebhookProperties},Discord.RequestOptions)"> | <member name="M:Discord.IWebhook.ModifyAsync(System.Action{Discord.WebhookProperties},Discord.RequestOptions)"> | ||||
| <summary> | <summary> | ||||
| Modifies this webhook. | Modifies this webhook. | ||||
| @@ -10,11 +10,6 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| public class ComponentBuilder | public class ComponentBuilder | ||||
| { | { | ||||
| /// <summary> | |||||
| /// The max length of a <see cref="ButtonComponent.Label"/>. | |||||
| /// </summary> | |||||
| public const int MaxLabelLength = 80; | |||||
| /// <summary> | /// <summary> | ||||
| /// The max length of a <see cref="ButtonComponent.CustomId"/>. | /// The max length of a <see cref="ButtonComponent.CustomId"/>. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -307,17 +302,22 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| public class ButtonBuilder | public class ButtonBuilder | ||||
| { | { | ||||
| /// <summary> | |||||
| /// The max length of a <see cref="ButtonComponent.Label"/>. | |||||
| /// </summary> | |||||
| public const int MaxLabelLength = 80; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the label of the current button. | /// Gets or sets the label of the current button. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="ComponentBuilder.MaxLabelLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxLabelLength"/>.</exception> | |||||
| public string Label | public string Label | ||||
| { | { | ||||
| get => _label; | get => _label; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > ComponentBuilder.MaxLabelLength) | |||||
| throw new ArgumentException(message: $"Button label must be {ComponentBuilder.MaxLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value != null && value.Length > MaxLabelLength) | |||||
| throw new ArgumentException(message: $"Button label must be {MaxLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| _label = value; | _label = value; | ||||
| } | } | ||||
| @@ -539,8 +539,8 @@ namespace Discord | |||||
| if (string.IsNullOrEmpty(this.Url)) | if (string.IsNullOrEmpty(this.Url)) | ||||
| throw new InvalidOperationException("Link buttons must have a link associated with them"); | throw new InvalidOperationException("Link buttons must have a link associated with them"); | ||||
| else | else | ||||
| UrlValidation.Validate(this.Url); | |||||
| } | |||||
| UrlValidation.Validate(this.Url); | |||||
| } | |||||
| else if (string.IsNullOrEmpty(this.CustomId)) | else if (string.IsNullOrEmpty(this.CustomId)) | ||||
| throw new InvalidOperationException("Non-link buttons must have a custom id associated with them"); | throw new InvalidOperationException("Non-link buttons must have a custom id associated with them"); | ||||
| @@ -831,23 +831,28 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| public class SelectMenuOptionBuilder | public class SelectMenuOptionBuilder | ||||
| { | { | ||||
| /// <summary> | |||||
| /// The maximum length of a <see cref="SelectMenuOption.Label"/>. | |||||
| /// </summary> | |||||
| public const int MaxLabelLength = 100; | |||||
| /// <summary> | /// <summary> | ||||
| /// The maximum length of a <see cref="SelectMenuOption.Description"/>. | /// The maximum length of a <see cref="SelectMenuOption.Description"/>. | ||||
| /// </summary> | /// </summary> | ||||
| public const int MaxDescriptionLength = 50; | |||||
| public const int MaxDescriptionLength = 100; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the label of the current select menu. | /// Gets or sets the label of the current select menu. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="ComponentBuilder.MaxLabelLength"/></exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxLabelLength"/></exception> | |||||
| public string Label | public string Label | ||||
| { | { | ||||
| get => _label; | get => _label; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null) | if (value != null) | ||||
| if (value.Length > ComponentBuilder.MaxLabelLength) | |||||
| throw new ArgumentException(message: $"Button label must be {ComponentBuilder.MaxLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value.Length > MaxLabelLength) | |||||
| throw new ArgumentException(message: $"Button label must be {MaxLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| _label = value; | _label = value; | ||||
| } | } | ||||
| @@ -10,68 +10,70 @@ namespace Discord | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public struct Color | public struct Color | ||||
| { | { | ||||
| /// <summary> Gets the max decimal value of color. </summary> | |||||
| public const uint MaxDecimalValue = 0xFFFFFF; | |||||
| /// <summary> Gets the default user color value. </summary> | /// <summary> Gets the default user color value. </summary> | ||||
| public static readonly Color Default = new Color(0); | |||||
| public static readonly Color Default = new(0); | |||||
| /// <summary> Gets the teal color value. </summary> | /// <summary> Gets the teal color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/1ABC9C">1ABC9C</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/1ABC9C">1ABC9C</see>.</returns> | ||||
| public static readonly Color Teal = new Color(0x1ABC9C); | |||||
| public static readonly Color Teal = new(0x1ABC9C); | |||||
| /// <summary> Gets the dark teal color value. </summary> | /// <summary> Gets the dark teal color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/11806A">11806A</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/11806A">11806A</see>.</returns> | ||||
| public static readonly Color DarkTeal = new Color(0x11806A); | |||||
| public static readonly Color DarkTeal = new(0x11806A); | |||||
| /// <summary> Gets the green color value. </summary> | /// <summary> Gets the green color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/2ECC71">2ECC71</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/2ECC71">2ECC71</see>.</returns> | ||||
| public static readonly Color Green = new Color(0x2ECC71); | |||||
| public static readonly Color Green = new(0x2ECC71); | |||||
| /// <summary> Gets the dark green color value. </summary> | /// <summary> Gets the dark green color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/1F8B4C">1F8B4C</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/1F8B4C">1F8B4C</see>.</returns> | ||||
| public static readonly Color DarkGreen = new Color(0x1F8B4C); | |||||
| public static readonly Color DarkGreen = new(0x1F8B4C); | |||||
| /// <summary> Gets the blue color value. </summary> | /// <summary> Gets the blue color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/3498DB">3498DB</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/3498DB">3498DB</see>.</returns> | ||||
| public static readonly Color Blue = new Color(0x3498DB); | |||||
| public static readonly Color Blue = new(0x3498DB); | |||||
| /// <summary> Gets the dark blue color value. </summary> | /// <summary> Gets the dark blue color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/206694">206694</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/206694">206694</see>.</returns> | ||||
| public static readonly Color DarkBlue = new Color(0x206694); | |||||
| public static readonly Color DarkBlue = new(0x206694); | |||||
| /// <summary> Gets the purple color value. </summary> | /// <summary> Gets the purple color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/9B59B6">9B59B6</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/9B59B6">9B59B6</see>.</returns> | ||||
| public static readonly Color Purple = new Color(0x9B59B6); | |||||
| public static readonly Color Purple = new(0x9B59B6); | |||||
| /// <summary> Gets the dark purple color value. </summary> | /// <summary> Gets the dark purple color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/71368A">71368A</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/71368A">71368A</see>.</returns> | ||||
| public static readonly Color DarkPurple = new Color(0x71368A); | |||||
| public static readonly Color DarkPurple = new(0x71368A); | |||||
| /// <summary> Gets the magenta color value. </summary> | /// <summary> Gets the magenta color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E91E63">E91E63</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E91E63">E91E63</see>.</returns> | ||||
| public static readonly Color Magenta = new Color(0xE91E63); | |||||
| public static readonly Color Magenta = new(0xE91E63); | |||||
| /// <summary> Gets the dark magenta color value. </summary> | /// <summary> Gets the dark magenta color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/AD1457">AD1457</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/AD1457">AD1457</see>.</returns> | ||||
| public static readonly Color DarkMagenta = new Color(0xAD1457); | |||||
| public static readonly Color DarkMagenta = new(0xAD1457); | |||||
| /// <summary> Gets the gold color value. </summary> | /// <summary> Gets the gold color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/F1C40F">F1C40F</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/F1C40F">F1C40F</see>.</returns> | ||||
| public static readonly Color Gold = new Color(0xF1C40F); | |||||
| public static readonly Color Gold = new(0xF1C40F); | |||||
| /// <summary> Gets the light orange color value. </summary> | /// <summary> Gets the light orange color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/C27C0E">C27C0E</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/C27C0E">C27C0E</see>.</returns> | ||||
| public static readonly Color LightOrange = new Color(0xC27C0E); | |||||
| public static readonly Color LightOrange = new(0xC27C0E); | |||||
| /// <summary> Gets the orange color value. </summary> | /// <summary> Gets the orange color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E67E22">E67E22</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E67E22">E67E22</see>.</returns> | ||||
| public static readonly Color Orange = new Color(0xE67E22); | |||||
| public static readonly Color Orange = new(0xE67E22); | |||||
| /// <summary> Gets the dark orange color value. </summary> | /// <summary> Gets the dark orange color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/A84300">A84300</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/A84300">A84300</see>.</returns> | ||||
| public static readonly Color DarkOrange = new Color(0xA84300); | |||||
| public static readonly Color DarkOrange = new(0xA84300); | |||||
| /// <summary> Gets the red color value. </summary> | /// <summary> Gets the red color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E74C3C">E74C3C</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/E74C3C">E74C3C</see>.</returns> | ||||
| public static readonly Color Red = new Color(0xE74C3C); | |||||
| public static readonly Color Red = new(0xE74C3C); | |||||
| /// <summary> Gets the dark red color value. </summary> | /// <summary> Gets the dark red color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/992D22">992D22</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/992D22">992D22</see>.</returns> | ||||
| public static readonly Color DarkRed = new Color(0x992D22); | |||||
| public static readonly Color DarkRed = new(0x992D22); | |||||
| /// <summary> Gets the light grey color value. </summary> | /// <summary> Gets the light grey color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/979C9F">979C9F</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/979C9F">979C9F</see>.</returns> | ||||
| public static readonly Color LightGrey = new Color(0x979C9F); | |||||
| public static readonly Color LightGrey = new(0x979C9F); | |||||
| /// <summary> Gets the lighter grey color value. </summary> | /// <summary> Gets the lighter grey color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/95A5A6">95A5A6</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/95A5A6">95A5A6</see>.</returns> | ||||
| public static readonly Color LighterGrey = new Color(0x95A5A6); | |||||
| public static readonly Color LighterGrey = new(0x95A5A6); | |||||
| /// <summary> Gets the dark grey color value. </summary> | /// <summary> Gets the dark grey color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/607D8B">607D8B</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/607D8B">607D8B</see>.</returns> | ||||
| public static readonly Color DarkGrey = new Color(0x607D8B); | |||||
| public static readonly Color DarkGrey = new(0x607D8B); | |||||
| /// <summary> Gets the darker grey color value. </summary> | /// <summary> Gets the darker grey color value. </summary> | ||||
| /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/546E7A">546E7A</see>.</returns> | /// <returns> A color struct with the hex value of <see href="http://www.color-hex.com/color/546E7A">546E7A</see>.</returns> | ||||
| public static readonly Color DarkerGrey = new Color(0x546E7A); | |||||
| public static readonly Color DarkerGrey = new(0x546E7A); | |||||
| /// <summary> Gets the encoded value for this color. </summary> | /// <summary> Gets the encoded value for this color. </summary> | ||||
| /// <remarks> | /// <remarks> | ||||
| @@ -91,22 +93,27 @@ namespace Discord | |||||
| /// Initializes a <see cref="Color"/> struct with the given raw value. | /// Initializes a <see cref="Color"/> struct with the given raw value. | ||||
| /// </summary> | /// </summary> | ||||
| /// <example> | /// <example> | ||||
| /// The following will create a color that has a hex value of | |||||
| /// The following will create a color that has a hex value of | |||||
| /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | ||||
| /// <code language="cs"> | /// <code language="cs"> | ||||
| /// Color darkGrey = new Color(0x607D8B); | /// Color darkGrey = new Color(0x607D8B); | ||||
| /// </code> | /// </code> | ||||
| /// </example> | /// </example> | ||||
| /// <param name="rawValue">The raw value of the color (e.g. <c>0x607D8B</c>).</param> | /// <param name="rawValue">The raw value of the color (e.g. <c>0x607D8B</c>).</param> | ||||
| /// <exception cref="ArgumentException">Value exceeds <see cref="MaxDecimalValue"/>.</exception> | |||||
| public Color(uint rawValue) | public Color(uint rawValue) | ||||
| { | { | ||||
| if (rawValue > MaxDecimalValue) | |||||
| throw new ArgumentException($"{nameof(RawValue)} of color cannot be greater than {MaxDecimalValue}!", nameof(rawValue)); | |||||
| RawValue = rawValue; | RawValue = rawValue; | ||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Initializes a <see cref="Color" /> struct with the given RGB bytes. | /// Initializes a <see cref="Color" /> struct with the given RGB bytes. | ||||
| /// </summary> | /// </summary> | ||||
| /// <example> | /// <example> | ||||
| /// The following will create a color that has a value of | |||||
| /// The following will create a color that has a value of | |||||
| /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | ||||
| /// <code language="cs"> | /// <code language="cs"> | ||||
| /// Color darkGrey = new Color((byte)0b_01100000, (byte)0b_01111101, (byte)0b_10001011); | /// Color darkGrey = new Color((byte)0b_01100000, (byte)0b_01111101, (byte)0b_10001011); | ||||
| @@ -115,19 +122,24 @@ namespace Discord | |||||
| /// <param name="r">The byte that represents the red color.</param> | /// <param name="r">The byte that represents the red color.</param> | ||||
| /// <param name="g">The byte that represents the green color.</param> | /// <param name="g">The byte that represents the green color.</param> | ||||
| /// <param name="b">The byte that represents the blue color.</param> | /// <param name="b">The byte that represents the blue color.</param> | ||||
| /// <exception cref="ArgumentException">Value exceeds <see cref="MaxDecimalValue"/>.</exception> | |||||
| public Color(byte r, byte g, byte b) | public Color(byte r, byte g, byte b) | ||||
| { | { | ||||
| RawValue = | |||||
| ((uint)r << 16) | | |||||
| ((uint)g << 8) | | |||||
| (uint)b; | |||||
| uint value = ((uint)r << 16) | |||||
| | ((uint)g << 8) | |||||
| | (uint)b; | |||||
| if (value > MaxDecimalValue) | |||||
| throw new ArgumentException($"{nameof(RawValue)} of color cannot be greater than {MaxDecimalValue}!"); | |||||
| RawValue = value; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Initializes a <see cref="Color"/> struct with the given RGB value. | /// Initializes a <see cref="Color"/> struct with the given RGB value. | ||||
| /// </summary> | /// </summary> | ||||
| /// <example> | /// <example> | ||||
| /// The following will create a color that has a value of | |||||
| /// The following will create a color that has a value of | |||||
| /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | /// <see href="http://www.color-hex.com/color/607d8b">#607D8B</see>. | ||||
| /// <code language="cs"> | /// <code language="cs"> | ||||
| /// Color darkGrey = new Color(96, 125, 139); | /// Color darkGrey = new Color(96, 125, 139); | ||||
| @@ -145,16 +157,15 @@ namespace Discord | |||||
| throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,255]."); | throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,255]."); | ||||
| if (b < 0 || b > 255) | if (b < 0 || b > 255) | ||||
| throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,255]."); | throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,255]."); | ||||
| RawValue = | |||||
| ((uint)r << 16) | | |||||
| ((uint)g << 8) | | |||||
| (uint)b; | |||||
| RawValue = ((uint)r << 16) | |||||
| | ((uint)g << 8) | |||||
| | (uint)b; | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Initializes a <see cref="Color"/> struct with the given RGB float value. | /// Initializes a <see cref="Color"/> struct with the given RGB float value. | ||||
| /// </summary> | /// </summary> | ||||
| /// <example> | /// <example> | ||||
| /// The following will create a color that has a value of | |||||
| /// The following will create a color that has a value of | |||||
| /// <see href="http://www.color-hex.com/color/607c8c">#607c8c</see>. | /// <see href="http://www.color-hex.com/color/607c8c">#607c8c</see>. | ||||
| /// <code language="cs"> | /// <code language="cs"> | ||||
| /// Color darkGrey = new Color(0.38f, 0.49f, 0.55f); | /// Color darkGrey = new Color(0.38f, 0.49f, 0.55f); | ||||
| @@ -172,10 +183,9 @@ namespace Discord | |||||
| throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,1]."); | throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,1]."); | ||||
| if (b < 0.0f || b > 1.0f) | if (b < 0.0f || b > 1.0f) | ||||
| throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,1]."); | throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,1]."); | ||||
| RawValue = | |||||
| ((uint)(r * 255.0f) << 16) | | |||||
| ((uint)(g * 255.0f) << 8) | | |||||
| (uint)(b * 255.0f); | |||||
| RawValue = ((uint)(r * 255.0f) << 16) | |||||
| | ((uint)(g * 255.0f) << 8) | |||||
| | (uint)(b * 255.0f); | |||||
| } | } | ||||
| public static bool operator ==(Color lhs, Color rhs) | public static bool operator ==(Color lhs, Color rhs) | ||||
| @@ -184,15 +194,22 @@ namespace Discord | |||||
| public static bool operator !=(Color lhs, Color rhs) | public static bool operator !=(Color lhs, Color rhs) | ||||
| => lhs.RawValue != rhs.RawValue; | => lhs.RawValue != rhs.RawValue; | ||||
| public static implicit operator Color(uint rawValue) | |||||
| => new(rawValue); | |||||
| public static implicit operator uint(Color color) | |||||
| => color.RawValue; | |||||
| public override bool Equals(object obj) | public override bool Equals(object obj) | ||||
| => (obj is Color c && RawValue == c.RawValue); | |||||
| => obj is Color c && RawValue == c.RawValue; | |||||
| public override int GetHashCode() => RawValue.GetHashCode(); | public override int GetHashCode() => RawValue.GetHashCode(); | ||||
| public static implicit operator StandardColor(Color color) => | |||||
| StandardColor.FromArgb((int)color.RawValue); | |||||
| public static explicit operator Color(StandardColor color) => | |||||
| new Color((uint)color.ToArgb() << 8 >> 8); | |||||
| public static implicit operator StandardColor(Color color) | |||||
| => StandardColor.FromArgb((int)color.RawValue); | |||||
| public static explicit operator Color(StandardColor color) | |||||
| => new((uint)color.ToArgb() << 8 >> 8); | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>). | /// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>). | ||||
| @@ -12,17 +12,29 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| string AvatarId { get; } | string AvatarId { get; } | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the identifier of this user's banner. | |||||
| /// </summary> | |||||
| string BannerId { get; } | |||||
| /// <summary> | |||||
| /// Gets the user's banner color. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A <see cref="Color"/> struct representing the accent color of this user's banner. | |||||
| /// </returns> | |||||
| Color? AccentColor { get; } | |||||
| /// <summary> | |||||
| /// Gets the avatar URL for this user. | /// Gets the avatar URL for this user. | ||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | /// <remarks> | ||||
| /// This property retrieves a URL for this user's avatar. In event that the user does not have a valid avatar | /// This property retrieves a URL for this user's avatar. In event that the user does not have a valid avatar | ||||
| /// (i.e. their avatar identifier is not set), this property will return <c>null</c>. If you wish to | |||||
| /// (i.e. their avatar identifier is not set), this method will return <c>null</c>. If you wish to | |||||
| /// retrieve the default avatar for this user, consider using <see cref="IUser.GetDefaultAvatarUrl"/> (see | /// retrieve the default avatar for this user, consider using <see cref="IUser.GetDefaultAvatarUrl"/> (see | ||||
| /// example). | /// example). | ||||
| /// </remarks> | /// </remarks> | ||||
| /// <example> | /// <example> | ||||
| /// <para>The following example attempts to retrieve the user's current avatar and send it to a channel; if one is | |||||
| /// not set, a default avatar for this user will be returned instead.</para> | |||||
| /// <para | |||||
| /// >The following example attempts to retrieve the user's current avatar and send it to a channel; if one is | |||||
| /// not set, a default avatar for this user will be returned instead.</para> | |||||
| /// <code language="cs" region="GetAvatarUrl" | /// <code language="cs" region="GetAvatarUrl" | ||||
| /// source="..\..\..\Discord.Net.Examples\Core\Entities\Users\IUser.Examples.cs"/> | /// source="..\..\..\Discord.Net.Examples\Core\Entities\Users\IUser.Examples.cs"/> | ||||
| /// </example> | /// </example> | ||||
| @@ -34,6 +46,16 @@ namespace Discord | |||||
| /// </returns> | /// </returns> | ||||
| string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); | string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the banner URL for this user. | |||||
| /// </summary> | |||||
| /// <param name="format">The format to return.</param> | |||||
| /// <param name="size">The size of the image to return in. This can be any power of two between 16 and 2048. | |||||
| /// </param> | |||||
| /// <returns> | |||||
| /// A string representing the user's avatar URL; <c>null</c> if the user does not have an banner in place. | |||||
| /// </returns> | |||||
| string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256); | |||||
| /// <summary> | |||||
| /// Gets the default avatar URL for this user. | /// Gets the default avatar URL for this user. | ||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | /// <remarks> | ||||
| @@ -93,8 +115,8 @@ namespace Discord | |||||
| /// This method is used to obtain or create a channel used to send a direct message. | /// This method is used to obtain or create a channel used to send a direct message. | ||||
| /// <note type="warning"> | /// <note type="warning"> | ||||
| /// In event that the current user cannot send a message to the target user, a channel can and will | /// In event that the current user cannot send a message to the target user, a channel can and will | ||||
| /// still be created by Discord. However, attempting to send a message will yield a | |||||
| /// <see cref="Discord.Net.HttpException"/> with a 403 as its | |||||
| /// still be created by Discord. However, attempting to send a message will yield a | |||||
| /// <see cref="Discord.Net.HttpException"/> with a 403 as its | |||||
| /// <see cref="Discord.Net.HttpException.HttpCode"/>. There are currently no official workarounds by | /// <see cref="Discord.Net.HttpException.HttpCode"/>. There are currently no official workarounds by | ||||
| /// Discord. | /// Discord. | ||||
| /// </note> | /// </note> | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord | namespace Discord | ||||
| @@ -49,6 +49,11 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| IUser Creator { get; } | IUser Creator { get; } | ||||
| /// <summary> | |||||
| /// Gets the ID of the application owning this webhook. | |||||
| /// </summary> | |||||
| ulong? ApplicationId { get; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Modifies this webhook. | /// Modifies this webhook. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -15,6 +15,10 @@ namespace Discord.API | |||||
| public Optional<bool> Bot { get; set; } | public Optional<bool> Bot { get; set; } | ||||
| [JsonProperty("avatar")] | [JsonProperty("avatar")] | ||||
| public Optional<string> Avatar { get; set; } | public Optional<string> Avatar { get; set; } | ||||
| [JsonProperty("banner")] | |||||
| public Optional<string> Banner { get; set; } | |||||
| [JsonProperty("accent_color")] | |||||
| public Optional<uint?> AccentColor { get; set; } | |||||
| //CurrentUser | //CurrentUser | ||||
| [JsonProperty("verified")] | [JsonProperty("verified")] | ||||
| @@ -21,5 +21,7 @@ namespace Discord.API | |||||
| [JsonProperty("user")] | [JsonProperty("user")] | ||||
| public Optional<User> Creator { get; set; } | public Optional<User> Creator { get; set; } | ||||
| [JsonProperty("application_id")] | |||||
| public Optional<ulong> ApplicationId { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,5 +12,7 @@ namespace Discord.API.Rest | |||||
| public Optional<Embed[]> Embeds { get; set; } | public Optional<Embed[]> Embeds { get; set; } | ||||
| [JsonProperty("allowed_mentions")] | [JsonProperty("allowed_mentions")] | ||||
| public Optional<AllowedMentions> AllowedMentions { get; set; } | public Optional<AllowedMentions> AllowedMentions { get; set; } | ||||
| [JsonProperty("components")] | |||||
| public Optional<API.ActionRowComponent[]> Components { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -4778,6 +4778,9 @@ | |||||
| <member name="P:Discord.Rest.RestWebhook.Creator"> | <member name="P:Discord.Rest.RestWebhook.Creator"> | ||||
| <inheritdoc /> | <inheritdoc /> | ||||
| </member> | </member> | ||||
| <member name="P:Discord.Rest.RestWebhook.ApplicationId"> | |||||
| <inheritdoc /> | |||||
| </member> | |||||
| <member name="P:Discord.Rest.RestWebhook.CreatedAt"> | <member name="P:Discord.Rest.RestWebhook.CreatedAt"> | ||||
| <inheritdoc /> | <inheritdoc /> | ||||
| </member> | </member> | ||||
| @@ -9,7 +9,7 @@ using Model = Discord.API.ThreadMember; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Represents a thread user recieved over the REST api. | |||||
| /// Represents a thread user received over the REST api. | |||||
| /// </summary> | /// </summary> | ||||
| public class RestThreadUser : RestEntity<ulong> | public class RestThreadUser : RestEntity<ulong> | ||||
| { | { | ||||
| @@ -51,7 +51,7 @@ namespace Discord.Rest | |||||
| /// Gets the guild user for this thread user. | /// Gets the guild user for this thread user. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| /// A task representing the asyncronous get operation. The task returns a | |||||
| /// A task representing the asynchronous get operation. The task returns a | |||||
| /// <see cref="IGuildUser"/> that represents the current thread user. | /// <see cref="IGuildUser"/> that represents the current thread user. | ||||
| /// </returns> | /// </returns> | ||||
| public Task<IGuildUser> GetGuildUser() | public Task<IGuildUser> GetGuildUser() | ||||
| @@ -22,6 +22,10 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string AvatarId { get; private set; } | public string AvatarId { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string BannerId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public Color? AccentColor { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public UserProperties? PublicFlags { get; private set; } | public UserProperties? PublicFlags { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -61,6 +65,10 @@ namespace Discord.Rest | |||||
| { | { | ||||
| if (model.Avatar.IsSpecified) | if (model.Avatar.IsSpecified) | ||||
| AvatarId = model.Avatar.Value; | AvatarId = model.Avatar.Value; | ||||
| if (model.Banner.IsSpecified) | |||||
| BannerId = model.Banner.Value; | |||||
| if (model.AccentColor.IsSpecified) | |||||
| AccentColor = model.AccentColor.Value; | |||||
| if (model.Discriminator.IsSpecified) | if (model.Discriminator.IsSpecified) | ||||
| DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | ||||
| if (model.Bot.IsSpecified) | if (model.Bot.IsSpecified) | ||||
| @@ -92,6 +100,10 @@ namespace Discord.Rest | |||||
| public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | ||||
| => CDN.GetUserAvatarUrl(Id, AvatarId, size, format); | => CDN.GetUserAvatarUrl(Id, AvatarId, size, format); | ||||
| /// <inheritdoc /> | |||||
| public string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256) | |||||
| => CDN.GetUserBannerUrl(Id, BannerId, size, format); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string GetDefaultAvatarUrl() | public string GetDefaultAvatarUrl() | ||||
| => CDN.GetDefaultUserAvatarUrl(DiscriminatorValue); | => CDN.GetDefaultUserAvatarUrl(DiscriminatorValue); | ||||
| @@ -24,6 +24,8 @@ namespace Discord.Rest | |||||
| public ulong? GuildId { get; private set; } | public ulong? GuildId { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public IUser Creator { get; private set; } | public IUser Creator { get; private set; } | ||||
| /// <inheritdoc /> | |||||
| public ulong? ApplicationId { get; private set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | ||||
| @@ -66,6 +68,8 @@ namespace Discord.Rest | |||||
| GuildId = model.GuildId.Value; | GuildId = model.GuildId.Value; | ||||
| if (model.Name.IsSpecified) | if (model.Name.IsSpecified) | ||||
| Name = model.Name.Value; | Name = model.Name.Value; | ||||
| if (model.ApplicationId.IsSpecified) | |||||
| ApplicationId = model.ApplicationId.Value; | |||||
| } | } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -68,6 +68,7 @@ namespace Discord.Rest | |||||
| model.Video = entity.Video.Value.ToModel(); | model.Video = entity.Video.Value.ToModel(); | ||||
| return model; | return model; | ||||
| } | } | ||||
| public static API.AllowedMentions ToModel(this AllowedMentions entity) | public static API.AllowedMentions ToModel(this AllowedMentions entity) | ||||
| { | { | ||||
| return new API.AllowedMentions() | return new API.AllowedMentions() | ||||
| @@ -12,6 +12,8 @@ namespace Discord.WebSocket | |||||
| public override string Username { get; internal set; } | public override string Username { get; internal set; } | ||||
| public override ushort DiscriminatorValue { get; internal set; } | public override ushort DiscriminatorValue { get; internal set; } | ||||
| public override string AvatarId { get; internal set; } | public override string AvatarId { get; internal set; } | ||||
| public override string BannerId { get; internal set; } | |||||
| public override Color? AccentColor { get; internal set; } | |||||
| internal override SocketPresence Presence { get; set; } | internal override SocketPresence Presence { get; set; } | ||||
| public override bool IsWebhook => false; | public override bool IsWebhook => false; | ||||
| @@ -47,7 +49,7 @@ namespace Discord.WebSocket | |||||
| discord.RemoveUser(Id); | discord.RemoveUser(Id); | ||||
| } | } | ||||
| } | } | ||||
| internal void Update(ClientState state, PresenceModel model) | internal void Update(ClientState state, PresenceModel model) | ||||
| { | { | ||||
| Presence = SocketPresence.Create(model); | Presence = SocketPresence.Create(model); | ||||
| @@ -29,6 +29,10 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string BannerId { get { return GlobalUser.BannerId; } internal set { GlobalUser.BannerId = value; } } | |||||
| /// <inheritdoc /> | |||||
| public override Color? AccentColor { get { return GlobalUser.AccentColor; } internal set { GlobalUser.AccentColor = value; } } | |||||
| /// <inheritdoc /> | |||||
| internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } } | internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -38,6 +38,11 @@ namespace Discord.WebSocket | |||||
| public override ushort DiscriminatorValue { get { return GlobalUser.DiscriminatorValue; } internal set { GlobalUser.DiscriminatorValue = value; } } | public override ushort DiscriminatorValue { get { return GlobalUser.DiscriminatorValue; } internal set { GlobalUser.DiscriminatorValue = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | ||||
| /// <inheritdoc /> | |||||
| public override string BannerId { get { return GlobalUser.BannerId; } internal set { GlobalUser.BannerId = value; } } | |||||
| /// <inheritdoc /> | |||||
| public override Color? AccentColor { get { return GlobalUser.AccentColor; } internal set { GlobalUser.AccentColor = value; } } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public GuildPermissions GuildPermissions => new GuildPermissions(Permissions.ResolveGuild(Guild, this)); | public GuildPermissions GuildPermissions => new GuildPermissions(Permissions.ResolveGuild(Guild, this)); | ||||
| internal override SocketPresence Presence { get; set; } | internal override SocketPresence Presence { get; set; } | ||||
| @@ -91,7 +96,7 @@ namespace Discord.WebSocket | |||||
| /// Returns the position of the user within the role hierarchy. | /// Returns the position of the user within the role hierarchy. | ||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | /// <remarks> | ||||
| /// The returned value equal to the position of the highest role the user has, or | |||||
| /// The returned value equal to the position of the highest role the user has, or | |||||
| /// <see cref="int.MaxValue"/> if user is the server owner. | /// <see cref="int.MaxValue"/> if user is the server owner. | ||||
| /// </remarks> | /// </remarks> | ||||
| public int Hierarchy | public int Hierarchy | ||||
| @@ -29,6 +29,10 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string BannerId { get { return GlobalUser.BannerId; } internal set { GlobalUser.BannerId = value; } } | |||||
| /// <inheritdoc /> | |||||
| public override Color? AccentColor { get { return GlobalUser.AccentColor; } internal set { GlobalUser.AccentColor = value; } } | |||||
| /// <inheritdoc /> | |||||
| internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } } | internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public UserProperties Flags { get; internal set; } | public UserProperties Flags { get; internal set; } | ||||
| @@ -36,7 +36,7 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public string Nickname | public string Nickname | ||||
| => GuildUser.Nickname; | |||||
| => GuildUser.Nickname; | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public DateTimeOffset? PremiumSince | public DateTimeOffset? PremiumSince | ||||
| @@ -53,6 +53,20 @@ namespace Discord.WebSocket | |||||
| internal set => GuildUser.AvatarId = value; | internal set => GuildUser.AvatarId = value; | ||||
| } | } | ||||
| /// <inheritdoc/> | |||||
| public override string BannerId | |||||
| { | |||||
| get => GuildUser.BannerId; | |||||
| internal set => GuildUser.BannerId = value; | |||||
| } | |||||
| /// <inheritdoc/> | |||||
| public override Color? AccentColor | |||||
| { | |||||
| get => GuildUser.AccentColor; | |||||
| internal set => GuildUser.AccentColor = value; | |||||
| } | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public override ushort DiscriminatorValue | public override ushort DiscriminatorValue | ||||
| { | { | ||||
| @@ -19,9 +19,16 @@ namespace Discord.WebSocket | |||||
| public override ushort DiscriminatorValue { get; internal set; } | public override ushort DiscriminatorValue { get; internal set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string AvatarId { get; internal set; } | public override string AvatarId { get; internal set; } | ||||
| /// <inheritdoc /> | |||||
| public override string BannerId { get; internal set; } | |||||
| /// <inheritdoc /> | |||||
| public override Color? AccentColor { get; internal set; } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override bool IsBot { get; internal set; } | public override bool IsBot { get; internal set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override bool IsWebhook => false; | public override bool IsWebhook => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -25,6 +25,10 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public abstract string AvatarId { get; internal set; } | public abstract string AvatarId { get; internal set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public abstract string BannerId { get; internal set; } | |||||
| /// <inheritdoc /> | |||||
| public abstract Color? AccentColor { get; internal set; } | |||||
| /// <inheritdoc /> | |||||
| public abstract bool IsWebhook { get; } | public abstract bool IsWebhook { get; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public UserProperties? PublicFlags { get; private set; } | public UserProperties? PublicFlags { get; private set; } | ||||
| @@ -64,6 +68,16 @@ namespace Discord.WebSocket | |||||
| AvatarId = model.Avatar.Value; | AvatarId = model.Avatar.Value; | ||||
| hasChanges = true; | hasChanges = true; | ||||
| } | } | ||||
| if (model.Banner.IsSpecified && model.Banner.Value != BannerId) | |||||
| { | |||||
| BannerId = model.Banner.Value; | |||||
| hasChanges = true; | |||||
| } | |||||
| if (model.AccentColor.IsSpecified && model.AccentColor.Value != AccentColor?.RawValue) | |||||
| { | |||||
| AccentColor = model.AccentColor.Value; | |||||
| hasChanges = true; | |||||
| } | |||||
| if (model.Discriminator.IsSpecified) | if (model.Discriminator.IsSpecified) | ||||
| { | { | ||||
| var newVal = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | var newVal = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | ||||
| @@ -99,6 +113,10 @@ namespace Discord.WebSocket | |||||
| public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | ||||
| => CDN.GetUserAvatarUrl(Id, AvatarId, size, format); | => CDN.GetUserAvatarUrl(Id, AvatarId, size, format); | ||||
| /// <inheritdoc /> | |||||
| public string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256) | |||||
| => CDN.GetUserBannerUrl(Id, BannerId, size, format); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string GetDefaultAvatarUrl() | public string GetDefaultAvatarUrl() | ||||
| => CDN.GetDefaultUserAvatarUrl(DiscriminatorValue); | => CDN.GetDefaultUserAvatarUrl(DiscriminatorValue); | ||||
| @@ -24,6 +24,23 @@ namespace Discord.WebSocket | |||||
| public override ushort DiscriminatorValue { get; internal set; } | public override ushort DiscriminatorValue { get; internal set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override string AvatarId { get; internal set; } | public override string AvatarId { get; internal set; } | ||||
| /// <inheritdoc /> | |||||
| /// <exception cref="NotSupportedException">Webhook users does not support banners.</exception> | |||||
| public override string BannerId | |||||
| { | |||||
| get => throw new NotSupportedException("Webhook users does not support banners."); | |||||
| internal set => throw new NotSupportedException("Webhook users does not support banners."); | |||||
| } | |||||
| /// <inheritdoc /> | |||||
| /// <exception cref="NotSupportedException">Webhook users does not support accent colors.</exception> | |||||
| public override Color? AccentColor | |||||
| { | |||||
| get => throw new NotSupportedException("Webhook users does not support accent colors."); | |||||
| internal set => throw new NotSupportedException("Webhook users does not support accent colors."); | |||||
| } | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override bool IsBot { get; internal set; } | public override bool IsBot { get; internal set; } | ||||
| @@ -31,7 +31,7 @@ | |||||
| <exception cref="T:System.ArgumentException">Thrown if the <paramref name="webhookUrl"/> is an invalid format.</exception> | <exception cref="T:System.ArgumentException">Thrown if the <paramref name="webhookUrl"/> is an invalid format.</exception> | ||||
| <exception cref="T:System.ArgumentNullException">Thrown if the <paramref name="webhookUrl"/> is null or whitespace.</exception> | <exception cref="T:System.ArgumentNullException">Thrown if the <paramref name="webhookUrl"/> is null or whitespace.</exception> | ||||
| </member> | </member> | ||||
| <member name="M:Discord.Webhook.DiscordWebhookClient.SendMessageAsync(System.String,System.Boolean,System.Collections.Generic.IEnumerable{Discord.Embed},System.String,System.String,Discord.RequestOptions,Discord.AllowedMentions)"> | |||||
| <member name="M:Discord.Webhook.DiscordWebhookClient.SendMessageAsync(System.String,System.Boolean,System.Collections.Generic.IEnumerable{Discord.Embed},System.String,System.String,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageComponent)"> | |||||
| <summary> Sends a message to the channel for this webhook. </summary> | <summary> Sends a message to the channel for this webhook. </summary> | ||||
| <returns> Returns the ID of the created message. </returns> | <returns> Returns the ID of the created message. </returns> | ||||
| </member> | </member> | ||||
| @@ -99,6 +99,11 @@ | |||||
| Gets or sets the allowed mentions of the message. | Gets or sets the allowed mentions of the message. | ||||
| </summary> | </summary> | ||||
| </member> | </member> | ||||
| <member name="P:Discord.Webhook.WebhookMessageProperties.Components"> | |||||
| <summary> | |||||
| Gets or sets the components that the message should display. | |||||
| </summary> | |||||
| </member> | |||||
| <member name="M:Discord.Webhook.WebhookClientHelper.GetWebhookAsync(Discord.Webhook.DiscordWebhookClient,System.UInt64)"> | <member name="M:Discord.Webhook.WebhookClientHelper.GetWebhookAsync(Discord.Webhook.DiscordWebhookClient,System.UInt64)"> | ||||
| <exception cref="T:System.InvalidOperationException">Could not find a webhook with the supplied credentials.</exception> | <exception cref="T:System.InvalidOperationException">Could not find a webhook with the supplied credentials.</exception> | ||||
| </member> | </member> | ||||
| @@ -88,8 +88,8 @@ namespace Discord.Webhook | |||||
| /// <summary> Sends a message to the channel for this webhook. </summary> | /// <summary> Sends a message to the channel for this webhook. </summary> | ||||
| /// <returns> Returns the ID of the created message. </returns> | /// <returns> Returns the ID of the created message. </returns> | ||||
| public Task<ulong> SendMessageAsync(string text = null, bool isTTS = false, IEnumerable<Embed> embeds = null, | public Task<ulong> SendMessageAsync(string text = null, bool isTTS = false, IEnumerable<Embed> embeds = null, | ||||
| string username = null, string avatarUrl = null, RequestOptions options = null, AllowedMentions allowedMentions = null) | |||||
| => WebhookClientHelper.SendMessageAsync(this, text, isTTS, embeds, username, avatarUrl, allowedMentions, options); | |||||
| string username = null, string avatarUrl = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageComponent component = null) | |||||
| => WebhookClientHelper.SendMessageAsync(this, text, isTTS, embeds, username, avatarUrl, allowedMentions, options, component); | |||||
| /// <summary> | /// <summary> | ||||
| /// Modifies a message posted using this webhook. | /// Modifies a message posted using this webhook. | ||||
| @@ -22,5 +22,9 @@ namespace Discord.Webhook | |||||
| /// Gets or sets the allowed mentions of the message. | /// Gets or sets the allowed mentions of the message. | ||||
| /// </summary> | /// </summary> | ||||
| public Optional<AllowedMentions> AllowedMentions { get; set; } | public Optional<AllowedMentions> AllowedMentions { get; set; } | ||||
| /// <summary> | |||||
| /// Gets or sets the components that the message should display. | |||||
| /// </summary> | |||||
| public Optional<MessageComponent> Components { get; set; } | |||||
| } | } | ||||
| } | } | ||||
| @@ -17,6 +17,7 @@ namespace Discord.Webhook | |||||
| public string Name { get; private set; } | public string Name { get; private set; } | ||||
| public string AvatarId { get; private set; } | public string AvatarId { get; private set; } | ||||
| public ulong? GuildId { get; private set; } | public ulong? GuildId { get; private set; } | ||||
| public ulong? ApplicationId { get; private set; } | |||||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | ||||
| @@ -44,6 +45,8 @@ namespace Discord.Webhook | |||||
| GuildId = model.GuildId.Value; | GuildId = model.GuildId.Value; | ||||
| if (model.Name.IsSpecified) | if (model.Name.IsSpecified) | ||||
| Name = model.Name.Value; | Name = model.Name.Value; | ||||
| if (model.ApplicationId.IsSpecified) | |||||
| ApplicationId = model.ApplicationId.Value; | |||||
| } | } | ||||
| public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | ||||
| @@ -21,7 +21,7 @@ namespace Discord.Webhook | |||||
| return RestInternalWebhook.Create(client, model); | return RestInternalWebhook.Create(client, model); | ||||
| } | } | ||||
| public static async Task<ulong> SendMessageAsync(DiscordWebhookClient client, | public static async Task<ulong> SendMessageAsync(DiscordWebhookClient client, | ||||
| string text, bool isTTS, IEnumerable<Embed> embeds, string username, string avatarUrl, AllowedMentions allowedMentions, RequestOptions options) | |||||
| string text, bool isTTS, IEnumerable<Embed> embeds, string username, string avatarUrl, AllowedMentions allowedMentions, RequestOptions options, MessageComponent component) | |||||
| { | { | ||||
| var args = new CreateWebhookMessageParams | var args = new CreateWebhookMessageParams | ||||
| { | { | ||||
| @@ -37,6 +37,8 @@ namespace Discord.Webhook | |||||
| args.AvatarUrl = avatarUrl; | args.AvatarUrl = avatarUrl; | ||||
| if (allowedMentions != null) | if (allowedMentions != null) | ||||
| args.AllowedMentions = allowedMentions.ToModel(); | args.AllowedMentions = allowedMentions.ToModel(); | ||||
| if (component != null) | |||||
| args.Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray(); | |||||
| var model = await client.ApiClient.CreateWebhookMessageAsync(client.Webhook.Id, args, options: options).ConfigureAwait(false); | var model = await client.ApiClient.CreateWebhookMessageAsync(client.Webhook.Id, args, options: options).ConfigureAwait(false); | ||||
| return model.Id; | return model.Id; | ||||
| @@ -83,7 +85,8 @@ namespace Discord.Webhook | |||||
| : Optional.Create<API.Embed[]>(), | : Optional.Create<API.Embed[]>(), | ||||
| AllowedMentions = args.AllowedMentions.IsSpecified | AllowedMentions = args.AllowedMentions.IsSpecified | ||||
| ? args.AllowedMentions.Value.ToModel() | ? args.AllowedMentions.Value.ToModel() | ||||
| : Optional.Create<API.AllowedMentions>() | |||||
| : Optional.Create<API.AllowedMentions>(), | |||||
| Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified, | |||||
| }; | }; | ||||
| await client.ApiClient.ModifyWebhookMessageAsync(client.Webhook.Id, messageId, apiArgs, options) | await client.ApiClient.ModifyWebhookMessageAsync(client.Webhook.Id, messageId, apiArgs, options) | ||||