Browse Source

Add banner and accent color to user and some fixes/improvements (#81)

* Add banner and accent color to user and some fixes

* Fix

* Fix!

* increase size of user banners to 256

* Some changes and mini refactor of color class

* add constant maxDecimalValue to color and checks with exceptions

* add `NotSupportedException` for `BannerId` and `AccentColor` in `SocketWebhookUser`

* Update ComponentBuilder.cs

- `MaxLabelLength` from `ComponentBuilder` moved to `ButtonBuilder`
- Added `MaxLabelLength` for `SelectMenuOptionBuilder`
- Changed `MaxDescriptionLength` to 100
pull/1923/head
Nikon GitHub 4 years ago
parent
commit
af9519b0f5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 222 additions and 73 deletions
  1. +18
    -0
      src/Discord.Net.Core/CDN.cs
  2. +19
    -14
      src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs
  3. +4
    -4
      src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
  4. +59
    -42
      src/Discord.Net.Core/Entities/Roles/Color.cs
  5. +27
    -5
      src/Discord.Net.Core/Entities/Users/IUser.cs
  6. +4
    -0
      src/Discord.Net.Rest/API/Common/User.cs
  7. +2
    -2
      src/Discord.Net.Rest/Entities/Users/RestThreadUser.cs
  8. +12
    -0
      src/Discord.Net.Rest/Entities/Users/RestUser.cs
  9. +3
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs
  10. +4
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs
  11. +6
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
  12. +4
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs
  13. +15
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketThreadUser.cs
  14. +8
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs
  15. +18
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
  16. +17
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs
  17. +2
    -2
      test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs

+ 18
- 0
src/Discord.Net.Core/CDN.cs View File

@@ -46,6 +46,24 @@ namespace Discord
string extension = FormatToExtension(format, avatarId);
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>
/// Returns the default user avatar URL.
/// </summary>


+ 19
- 14
src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs View File

@@ -10,11 +10,6 @@ namespace Discord
/// </summary>
public class ComponentBuilder
{
/// <summary>
/// The max length of a <see cref="ButtonComponent.Label"/>.
/// </summary>
public const int MaxLabelLength = 80;

/// <summary>
/// The max length of a <see cref="ButtonComponent.CustomId"/>.
/// </summary>
@@ -307,17 +302,22 @@ namespace Discord
/// </summary>
public class ButtonBuilder
{
/// <summary>
/// The max length of a <see cref="ButtonComponent.Label"/>.
/// </summary>
public const int MaxLabelLength = 80;

/// <summary>
/// Gets or sets the label of the current button.
/// </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
{
get => _label;
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;
}
@@ -539,8 +539,8 @@ namespace Discord
if (string.IsNullOrEmpty(this.Url))
throw new InvalidOperationException("Link buttons must have a link associated with them");
else
UrlValidation.Validate(this.Url);
}
UrlValidation.Validate(this.Url);
}
else if (string.IsNullOrEmpty(this.CustomId))
throw new InvalidOperationException("Non-link buttons must have a custom id associated with them");

@@ -831,23 +831,28 @@ namespace Discord
/// </summary>
public class SelectMenuOptionBuilder
{
/// <summary>
/// The maximum length of a <see cref="SelectMenuOption.Label"/>.
/// </summary>
public const int MaxLabelLength = 100;

/// <summary>
/// The maximum length of a <see cref="SelectMenuOption.Description"/>.
/// </summary>
public const int MaxDescriptionLength = 50;
public const int MaxDescriptionLength = 100;

/// <summary>
/// Gets or sets the label of the current select menu.
/// </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
{
get => _label;
set
{
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;
}


+ 4
- 4
src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs View File

@@ -192,7 +192,7 @@ namespace Discord
bool manageNicknames = false,
bool manageRoles = false,
bool manageWebhooks = false,
bool manageEmojis = false)
bool manageEmojisAndStickers = false)
: this(0,
createInstantInvite: createInstantInvite,
manageRoles: manageRoles,
@@ -224,7 +224,7 @@ namespace Discord
changeNickname: changeNickname,
manageNicknames: manageNicknames,
manageWebhooks: manageWebhooks,
manageEmojisAndStickers: manageEmojis)
manageEmojisAndStickers: manageEmojisAndStickers)
{ }

/// <summary> Creates a new <see cref="GuildPermissions"/> from this one, changing the provided non-null permissions. </summary>
@@ -259,11 +259,11 @@ namespace Discord
bool? manageNicknames = null,
bool? manageRoles = null,
bool? manageWebhooks = null,
bool? manageEmojis = null)
bool? manageEmojisAndStickers = null)
=> new GuildPermissions(RawValue, createInstantInvite, kickMembers, banMembers, administrator, manageChannels, manageGuild, addReactions,
viewAuditLog, viewGuildInsights, viewChannel, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles,
readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, moveMembers,
useVoiceActivation, prioritySpeaker, stream, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojis);
useVoiceActivation, prioritySpeaker, stream, changeNickname, manageNicknames, manageRoles, manageWebhooks, manageEmojisAndStickers);

/// <summary>
/// Returns a value that indicates if a specific <see cref="GuildPermission"/> is enabled


+ 59
- 42
src/Discord.Net.Core/Entities/Roles/Color.cs View File

@@ -10,68 +10,70 @@ namespace Discord
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
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>
public static readonly Color Default = new Color(0);
public static readonly Color Default = new(0);
/// <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>
public static readonly Color Teal = new Color(0x1ABC9C);
public static readonly Color Teal = new(0x1ABC9C);
/// <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>
public static readonly Color DarkTeal = new Color(0x11806A);
public static readonly Color DarkTeal = new(0x11806A);
/// <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>
public static readonly Color Green = new Color(0x2ECC71);
public static readonly Color Green = new(0x2ECC71);
/// <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>
public static readonly Color DarkGreen = new Color(0x1F8B4C);
public static readonly Color DarkGreen = new(0x1F8B4C);
/// <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>
public static readonly Color Blue = new Color(0x3498DB);
public static readonly Color Blue = new(0x3498DB);
/// <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>
public static readonly Color DarkBlue = new Color(0x206694);
public static readonly Color DarkBlue = new(0x206694);
/// <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>
public static readonly Color Purple = new Color(0x9B59B6);
public static readonly Color Purple = new(0x9B59B6);
/// <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>
public static readonly Color DarkPurple = new Color(0x71368A);
public static readonly Color DarkPurple = new(0x71368A);
/// <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>
public static readonly Color Magenta = new Color(0xE91E63);
public static readonly Color Magenta = new(0xE91E63);
/// <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>
public static readonly Color DarkMagenta = new Color(0xAD1457);
public static readonly Color DarkMagenta = new(0xAD1457);
/// <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>
public static readonly Color Gold = new Color(0xF1C40F);
public static readonly Color Gold = new(0xF1C40F);
/// <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>
public static readonly Color LightOrange = new Color(0xC27C0E);
public static readonly Color LightOrange = new(0xC27C0E);
/// <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>
public static readonly Color Orange = new Color(0xE67E22);
public static readonly Color Orange = new(0xE67E22);
/// <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>
public static readonly Color DarkOrange = new Color(0xA84300);
public static readonly Color DarkOrange = new(0xA84300);
/// <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>
public static readonly Color Red = new Color(0xE74C3C);
public static readonly Color Red = new(0xE74C3C);
/// <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>
public static readonly Color DarkRed = new Color(0x992D22);
public static readonly Color DarkRed = new(0x992D22);
/// <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>
public static readonly Color LightGrey = new Color(0x979C9F);
public static readonly Color LightGrey = new(0x979C9F);
/// <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>
public static readonly Color LighterGrey = new Color(0x95A5A6);
public static readonly Color LighterGrey = new(0x95A5A6);
/// <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>
public static readonly Color DarkGrey = new Color(0x607D8B);
public static readonly Color DarkGrey = new(0x607D8B);
/// <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>
public static readonly Color DarkerGrey = new Color(0x546E7A);
public static readonly Color DarkerGrey = new(0x546E7A);

/// <summary> Gets the encoded value for this color. </summary>
/// <remarks>
@@ -91,22 +93,27 @@ namespace Discord
/// Initializes a <see cref="Color"/> struct with the given raw value.
/// </summary>
/// <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>.
/// <code language="cs">
/// Color darkGrey = new Color(0x607D8B);
/// </code>
/// </example>
/// <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)
{
if (rawValue > MaxDecimalValue)
throw new ArgumentException($"{nameof(RawValue)} of color cannot be greater than {MaxDecimalValue}!", nameof(rawValue));

RawValue = rawValue;
}

/// <summary>
/// Initializes a <see cref="Color" /> struct with the given RGB bytes.
/// </summary>
/// <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>.
/// <code language="cs">
/// 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="g">The byte that represents the green 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)
{
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>
/// Initializes a <see cref="Color"/> struct with the given RGB value.
/// </summary>
/// <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>.
/// <code language="cs">
/// Color darkGrey = new Color(96, 125, 139);
@@ -145,16 +157,15 @@ namespace Discord
throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,255].");
if (b < 0 || b > 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>
/// Initializes a <see cref="Color"/> struct with the given RGB float value.
/// </summary>
/// <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>.
/// <code language="cs">
/// 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].");
if (b < 0.0f || b > 1.0f)
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)
@@ -184,15 +194,22 @@ namespace Discord
public static bool operator !=(Color lhs, Color rhs)
=> 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)
=> (obj is Color c && RawValue == c.RawValue);
=> obj is Color c && RawValue == c.RawValue;

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>
/// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>).


+ 27
- 5
src/Discord.Net.Core/Entities/Users/IUser.cs View File

@@ -12,17 +12,29 @@ namespace Discord
/// </summary>
string AvatarId { get; }
/// <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.
/// </summary>
/// <remarks>
/// 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
/// example).
/// </remarks>
/// <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"
/// source="..\..\..\Discord.Net.Examples\Core\Entities\Users\IUser.Examples.cs"/>
/// </example>
@@ -34,6 +46,16 @@ namespace Discord
/// </returns>
string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128);
/// <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.
/// </summary>
/// <remarks>
@@ -93,8 +115,8 @@ namespace Discord
/// This method is used to obtain or create a channel used to send a direct message.
/// <note type="warning">
/// 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
/// Discord.
/// </note>


+ 4
- 0
src/Discord.Net.Rest/API/Common/User.cs View File

@@ -15,6 +15,10 @@ namespace Discord.API
public Optional<bool> Bot { get; set; }
[JsonProperty("avatar")]
public Optional<string> Avatar { get; set; }
[JsonProperty("banner")]
public Optional<string> Banner { get; set; }
[JsonProperty("accent_color")]
public Optional<uint?> AccentColor { get; set; }

//CurrentUser
[JsonProperty("verified")]


+ 2
- 2
src/Discord.Net.Rest/Entities/Users/RestThreadUser.cs View File

@@ -9,7 +9,7 @@ using Model = Discord.API.ThreadMember;
namespace Discord.Rest
{
/// <summary>
/// Represents a thread user recieved over the REST api.
/// Represents a thread user received over the REST api.
/// </summary>
public class RestThreadUser : RestEntity<ulong>
{
@@ -51,7 +51,7 @@ namespace Discord.Rest
/// Gets the guild user for this thread user.
/// </summary>
/// <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.
/// </returns>
public Task<IGuildUser> GetGuildUser()


+ 12
- 0
src/Discord.Net.Rest/Entities/Users/RestUser.cs View File

@@ -22,6 +22,10 @@ namespace Discord.Rest
/// <inheritdoc />
public string AvatarId { get; private set; }
/// <inheritdoc />
public string BannerId { get; private set; }
/// <inheritdoc />
public Color? AccentColor { get; private set; }
/// <inheritdoc />
public UserProperties? PublicFlags { get; private set; }

/// <inheritdoc />
@@ -61,6 +65,10 @@ namespace Discord.Rest
{
if (model.Avatar.IsSpecified)
AvatarId = model.Avatar.Value;
if (model.Banner.IsSpecified)
BannerId = model.Banner.Value;
if (model.AccentColor.IsSpecified)
AccentColor = model.AccentColor.Value;
if (model.Discriminator.IsSpecified)
DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture);
if (model.Bot.IsSpecified)
@@ -92,6 +100,10 @@ namespace Discord.Rest
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetUserAvatarUrl(Id, AvatarId, size, format);

/// <inheritdoc />
public string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256)
=> CDN.GetUserBannerUrl(Id, BannerId, size, format);

/// <inheritdoc />
public string GetDefaultAvatarUrl()
=> CDN.GetDefaultUserAvatarUrl(DiscriminatorValue);


+ 3
- 1
src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs View File

@@ -12,6 +12,8 @@ namespace Discord.WebSocket
public override string Username { get; internal set; }
public override ushort DiscriminatorValue { 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; }

public override bool IsWebhook => false;
@@ -47,7 +49,7 @@ namespace Discord.WebSocket
discord.RemoveUser(Id);
}
}
internal void Update(ClientState state, PresenceModel model)
{
Presence = SocketPresence.Create(model);


+ 4
- 0
src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs View File

@@ -29,6 +29,10 @@ namespace Discord.WebSocket
/// <inheritdoc />
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 />
internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } }

/// <inheritdoc />


+ 6
- 1
src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs View File

@@ -38,6 +38,11 @@ namespace Discord.WebSocket
public override ushort DiscriminatorValue { get { return GlobalUser.DiscriminatorValue; } internal set { GlobalUser.DiscriminatorValue = value; } }
/// <inheritdoc />
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 />
public GuildPermissions GuildPermissions => new GuildPermissions(Permissions.ResolveGuild(Guild, this));
internal override SocketPresence Presence { get; set; }
@@ -91,7 +96,7 @@ namespace Discord.WebSocket
/// Returns the position of the user within the role hierarchy.
/// </summary>
/// <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.
/// </remarks>
public int Hierarchy


+ 4
- 0
src/Discord.Net.WebSocket/Entities/Users/SocketSelfUser.cs View File

@@ -29,6 +29,10 @@ namespace Discord.WebSocket
/// <inheritdoc />
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 />
internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } }
/// <inheritdoc />
public UserProperties Flags { get; internal set; }


+ 15
- 1
src/Discord.Net.WebSocket/Entities/Users/SocketThreadUser.cs View File

@@ -36,7 +36,7 @@ namespace Discord.WebSocket

/// <inheritdoc/>
public string Nickname
=> GuildUser.Nickname;
=> GuildUser.Nickname;

/// <inheritdoc/>
public DateTimeOffset? PremiumSince
@@ -53,6 +53,20 @@ namespace Discord.WebSocket
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/>
public override ushort DiscriminatorValue
{


+ 8
- 1
src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs View File

@@ -19,9 +19,16 @@ namespace Discord.WebSocket
public override ushort DiscriminatorValue { get; internal set; }
/// <inheritdoc />
public override string AvatarId { get; internal set; }

/// <inheritdoc />
public override string BannerId { get; internal set; }

/// <inheritdoc />
public override Color? AccentColor { get; internal set; }

/// <inheritdoc />
public override bool IsBot { get; internal set; }
/// <inheritdoc />
public override bool IsWebhook => false;
/// <inheritdoc />


+ 18
- 0
src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs View File

@@ -25,6 +25,10 @@ namespace Discord.WebSocket
/// <inheritdoc />
public abstract string AvatarId { get; internal set; }
/// <inheritdoc />
public abstract string BannerId { get; internal set; }
/// <inheritdoc />
public abstract Color? AccentColor { get; internal set; }
/// <inheritdoc />
public abstract bool IsWebhook { get; }
/// <inheritdoc />
public UserProperties? PublicFlags { get; private set; }
@@ -64,6 +68,16 @@ namespace Discord.WebSocket
AvatarId = model.Avatar.Value;
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)
{
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)
=> CDN.GetUserAvatarUrl(Id, AvatarId, size, format);

/// <inheritdoc />
public string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256)
=> CDN.GetUserBannerUrl(Id, BannerId, size, format);

/// <inheritdoc />
public string GetDefaultAvatarUrl()
=> CDN.GetDefaultUserAvatarUrl(DiscriminatorValue);


+ 17
- 0
src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs View File

@@ -24,6 +24,23 @@ namespace Discord.WebSocket
public override ushort DiscriminatorValue { get; internal set; }
/// <inheritdoc />
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 />
public override bool IsBot { get; internal set; }



+ 2
- 2
test/Discord.Net.Tests.Unit/GuildPermissionsTests.cs View File

@@ -91,7 +91,7 @@ namespace Discord
AssertFlag(() => new GuildPermissions(manageNicknames: true), GuildPermission.ManageNicknames);
AssertFlag(() => new GuildPermissions(manageRoles: true), GuildPermission.ManageRoles);
AssertFlag(() => new GuildPermissions(manageWebhooks: true), GuildPermission.ManageWebhooks);
AssertFlag(() => new GuildPermissions(manageEmojis: true), GuildPermission.ManageEmojisAndStickers);
AssertFlag(() => new GuildPermissions(manageEmojisAndStickers: true), GuildPermission.ManageEmojisAndStickers);
}

/// <summary>
@@ -161,7 +161,7 @@ namespace Discord
AssertUtil(GuildPermission.ManageNicknames, x => x.ManageNicknames, (p, enable) => p.Modify(manageNicknames: enable));
AssertUtil(GuildPermission.ManageRoles, x => x.ManageRoles, (p, enable) => p.Modify(manageRoles: enable));
AssertUtil(GuildPermission.ManageWebhooks, x => x.ManageWebhooks, (p, enable) => p.Modify(manageWebhooks: enable));
AssertUtil(GuildPermission.ManageEmojisAndStickers, x => x.ManageEmojisAndStickers, (p, enable) => p.Modify(manageEmojis: enable));
AssertUtil(GuildPermission.ManageEmojisAndStickers, x => x.ManageEmojisAndStickers, (p, enable) => p.Modify(manageEmojisAndStickers: enable));
}
}
}

Loading…
Cancel
Save