Skip to content

Commit

Permalink
Implement user banners.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nihlus committed Aug 18, 2021
1 parent ed99eaf commit 8ff4585
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.Core;

Expand Down Expand Up @@ -67,6 +68,16 @@ public interface IPartialUser
/// </summary>
Optional<bool> IsMFAEnabled { get; }

/// <summary>
/// Gets the user's banner.
/// </summary>
Optional<IImageHash?> Banner { get; }

/// <summary>
/// Gets the user's banner colour.
/// </summary>
Optional<Color?> AccentColour { get; }

/// <summary>
/// Gets the user's chosen language option.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions Backend/Remora.Discord.API.Abstractions/API/Objects/Users/IUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.Core;

Expand Down Expand Up @@ -67,6 +68,16 @@ public interface IUser
/// </summary>
Optional<bool> IsMFAEnabled { get; }

/// <summary>
/// Gets the user's banner.
/// </summary>
Optional<IImageHash?> Banner { get; }

/// <summary>
/// Gets the user's banner colour.
/// </summary>
Optional<Color?> AccentColour { get; }

/// <summary>
/// Gets the user's chosen language option.
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions Backend/Remora.Discord.API/API/CDN.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,79 @@ public static Result<Uri> GetGuildBannerUrl
return ub.Uri;
}

/// <summary>
/// Gets the CDN URI of the given user's banner.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="imageFormat">The requested image format.</param>
/// <param name="imageSize">The requested image size. May be any power of two between 16 and 4096.</param>
/// <returns>A result which may or may not have succeeded.</returns>
public static Result<Uri> GetUserBannerUrl
(
IUser user,
Optional<CDNImageFormat> imageFormat = default,
Optional<ushort> imageSize = default
)
{
if (!user.Banner.HasValue || user.Banner.Value is null)
{
return new ImageNotFoundError();
}

return GetUserBannerUrl(user.ID, user.Banner.Value, imageFormat, imageSize);
}

/// <summary>
/// Gets the CDN URI of the given user's banner.
/// </summary>
/// <param name="userID">The ID of the user.</param>
/// <param name="bannerHash">The image hash of the user's banner.</param>
/// <param name="imageFormat">The requested image format.</param>
/// <param name="imageSize">The requested image size. May be any power of two between 16 and 4096.</param>
/// <returns>A result which may or may not have succeeded.</returns>
public static Result<Uri> GetUserBannerUrl
(
Snowflake userID,
IImageHash bannerHash,
Optional<CDNImageFormat> imageFormat = default,
Optional<ushort> imageSize = default
)
{
var formatValidation = ValidateOrDefaultImageFormat
(
imageFormat,
CDNImageFormat.PNG,
CDNImageFormat.JPEG,
CDNImageFormat.WebP,
CDNImageFormat.GIF
);

if (!formatValidation.IsSuccess)
{
return Result<Uri>.FromError(formatValidation);
}

imageFormat = formatValidation.Entity;

var checkImageSize = CheckImageSize(imageSize);
if (!checkImageSize.IsSuccess)
{
return Result<Uri>.FromError(checkImageSize);
}

var ub = new UriBuilder(Constants.CDNBaseURL)
{
Path = $"banners/{userID}/{bannerHash.Value}.{imageFormat.Value.ToFileExtension()}"
};

if (imageSize.HasValue)
{
ub.Query = $"size={imageSize.Value}";
}

return ub.Uri;
}

/// <summary>
/// Gets the CDN URI of the given user's default avatar.
/// </summary>
Expand Down
74 changes: 36 additions & 38 deletions Backend/Remora.Discord.API/API/Gateway/Events/Users/UserUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Gateway.Events;
using Remora.Discord.API.Abstractions.Objects;
Expand All @@ -30,42 +31,39 @@ namespace Remora.Discord.API.Gateway.Events
{
/// <inheritdoc cref="Remora.Discord.API.Abstractions.Gateway.Events.IUserUpdate" />
[PublicAPI]
public record UserUpdate : User, IUserUpdate
{
/// <inheritdoc cref="User" />
public UserUpdate
(
Snowflake id,
string username,
ushort discriminator,
IImageHash? avatar,
Optional<bool> isBot = default,
Optional<bool> isSystem = default,
Optional<bool> isMFAEnabled = default,
Optional<string> locale = default,
Optional<bool> isVerified = default,
Optional<string?> email = default,
Optional<UserFlags> flags = default,
Optional<PremiumType> premiumType = default,
Optional<UserFlags> publicFlags = default
)
: base
(
id,
username,
discriminator,
avatar,
isBot,
isSystem,
isMFAEnabled,
locale,
isVerified,
email,
flags,
premiumType,
publicFlags
)
{
}
}
public record UserUpdate
(
Snowflake ID,
string Username,
ushort Discriminator,
IImageHash? Avatar,
Optional<bool> IsBot = default,
Optional<bool> IsSystem = default,
Optional<bool> IsMFAEnabled = default,
Optional<IImageHash?> Banner = default,
Optional<Color?> AccentColour = default,
Optional<string> Locale = default,
Optional<bool> IsVerified = default,
Optional<string?> Email = default,
Optional<UserFlags> Flags = default,
Optional<PremiumType> PremiumType = default,
Optional<UserFlags> PublicFlags = default
) : User
(
ID,
Username,
Discriminator,
Avatar,
IsBot,
IsSystem,
IsMFAEnabled,
Banner,
AccentColour,
Locale,
IsVerified,
Email,
Flags,
PremiumType,
PublicFlags
), IUserUpdate;
}
3 changes: 3 additions & 0 deletions Backend/Remora.Discord.API/API/Objects/Users/PartialUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.Core;
Expand All @@ -39,6 +40,8 @@ public record PartialUser
Optional<bool> IsBot = default,
Optional<bool> IsSystem = default,
Optional<bool> IsMFAEnabled = default,
Optional<IImageHash?> Banner = default,
Optional<Color?> AccentColour = default,
Optional<string> Locale = default,
Optional<bool> IsVerified = default,
Optional<string?> Email = default,
Expand Down
3 changes: 3 additions & 0 deletions Backend/Remora.Discord.API/API/Objects/Users/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.Core;
Expand All @@ -39,6 +40,8 @@ public record User
Optional<bool> IsBot = default,
Optional<bool> IsSystem = default,
Optional<bool> IsMFAEnabled = default,
Optional<IImageHash?> Banner = default,
Optional<Color?> AccentColour = default,
Optional<string> Locale = default,
Optional<bool> IsVerified = default,
Optional<string?> Email = default,
Expand Down
96 changes: 37 additions & 59 deletions Backend/Remora.Discord.API/API/Objects/Users/UserMention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System.Drawing;
using JetBrains.Annotations;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.Core;
Expand All @@ -28,63 +29,40 @@ namespace Remora.Discord.API.Objects
{
/// <inheritdoc cref="IUserMention"/>
[PublicAPI]
public record UserMention : User, IUserMention
{
/// <inheritdoc />
public Optional<IPartialGuildMember> Member { get; }

/// <summary>
/// Initializes a new instance of the <see cref="UserMention"/> class.
/// </summary>
/// <param name="id">The ID of the user.</param>
/// <param name="username">The user's username.</param>
/// <param name="discriminator">The user's discriminator.</param>
/// <param name="avatar">The user's avatar.</param>
/// <param name="isBot">Whether the user is a bot.</param>
/// <param name="isSystem">Whether the user is a system user.</param>
/// <param name="isMFAEnabled">Whether MFA is enabled.</param>
/// <param name="locale">The user's locale.</param>
/// <param name="isVerified">Whether the user is verified.</param>
/// <param name="email">The user's email.</param>
/// <param name="flags">The user's flags.</param>
/// <param name="premiumType">The user's premium type.</param>
/// <param name="publicFlags">The user's public flags.</param>
/// <param name="member">The member information.</param>
public UserMention
(
Snowflake id,
string username,
ushort discriminator,
IImageHash? avatar,
Optional<bool> isBot = default,
Optional<bool> isSystem = default,
Optional<bool> isMFAEnabled = default,
Optional<string> locale = default,
Optional<bool> isVerified = default,
Optional<string?> email = default,
Optional<UserFlags> flags = default,
Optional<PremiumType> premiumType = default,
Optional<UserFlags> publicFlags = default,
Optional<IPartialGuildMember> member = default
)
: base
(
id,
username,
discriminator,
avatar,
isBot,
isSystem,
isMFAEnabled,
locale,
isVerified,
email,
flags,
premiumType,
publicFlags
)
{
this.Member = member;
}
}
public record UserMention
(
Snowflake ID,
string Username,
ushort Discriminator,
IImageHash? Avatar,
Optional<bool> IsBot = default,
Optional<bool> IsSystem = default,
Optional<bool> IsMFAEnabled = default,
Optional<IImageHash?> Banner = default,
Optional<Color?> AccentColour = default,
Optional<string> Locale = default,
Optional<bool> IsVerified = default,
Optional<string?> Email = default,
Optional<UserFlags> Flags = default,
Optional<PremiumType> PremiumType = default,
Optional<UserFlags> PublicFlags = default,
Optional<IPartialGuildMember> Member = default
) : User
(
ID,
Username,
Discriminator,
Avatar,
IsBot,
IsSystem,
IsMFAEnabled,
Banner,
AccentColour,
Locale,
IsVerified,
Email,
Flags,
PremiumType,
PublicFlags
), IUserMention;
}
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ private static JsonSerializerOptions AddGatewayEventConverters(this JsonSerializ
.WithPropertyName(u => u.IsBot, "bot")
.WithPropertyName(u => u.IsSystem, "system")
.WithPropertyName(u => u.IsVerified, "verified")
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled");
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled")
.WithPropertyName(u => u.AccentColour, "accent_color");

// Voice
options.AddDataObjectConverter<IVoiceStateUpdate, VoiceStateUpdate>()
Expand Down Expand Up @@ -705,21 +706,24 @@ private static JsonSerializerOptions AddUserObjectConverters(this JsonSerializer
.WithPropertyName(u => u.IsBot, "bot")
.WithPropertyName(u => u.IsSystem, "system")
.WithPropertyName(u => u.IsVerified, "verified")
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled");
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled")
.WithPropertyName(u => u.AccentColour, "accent_color");

options.AddDataObjectConverter<IPartialUser, PartialUser>()
.WithPropertyConverter(u => u.Discriminator, new DiscriminatorConverter())
.WithPropertyName(u => u.IsBot, "bot")
.WithPropertyName(u => u.IsSystem, "system")
.WithPropertyName(u => u.IsVerified, "verified")
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled");
.WithPropertyName(u => u.IsMFAEnabled, "mfa_enabled")
.WithPropertyName(u => u.AccentColour, "accent_color");

options.AddDataObjectConverter<IUserMention, UserMention>()
.WithPropertyConverter(u => u.Discriminator, new DiscriminatorConverter())
.WithPropertyName(m => m.IsBot, "bot")
.WithPropertyName(m => m.IsSystem, "system")
.WithPropertyName(m => m.IsVerified, "verified")
.WithPropertyName(m => m.IsMFAEnabled, "mfa_enabled");
.WithPropertyName(m => m.IsMFAEnabled, "mfa_enabled")
.WithPropertyName(u => u.AccentColour, "accent_color");

options.AddDataObjectConverter<IConnection, Connection>()
.WithPropertyName(c => c.IsRevoked, "revoked")
Expand Down
Loading

0 comments on commit 8ff4585

Please sign in to comment.