From 1d89380f23f049955dfa709eb1ef5b802fa098ba Mon Sep 17 00:00:00 2001 From: Lexedia Date: Sun, 13 Oct 2024 01:11:42 +0200 Subject: [PATCH] fix user avatar decoration, add member avatar decoration --- lib/src/http/managers/member_manager.dart | 4 ++++ lib/src/http/managers/user_manager.dart | 13 ++++++++++++- lib/src/http/route.dart | 3 +++ lib/src/models/guild/member.dart | 17 +++++++++++++++++ lib/src/models/user/avatar_decoration_data.dart | 17 +++++++++++++++++ lib/src/models/user/user.dart | 7 ++++++- 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 lib/src/models/user/avatar_decoration_data.dart diff --git a/lib/src/http/managers/member_manager.dart b/lib/src/http/managers/member_manager.dart index a083c39b9..812ded256 100644 --- a/lib/src/http/managers/member_manager.dart +++ b/lib/src/http/managers/member_manager.dart @@ -23,6 +23,8 @@ class MemberManager extends Manager { @override Member parse(Map raw, {Snowflake? userId}) { + final avatarDecorationData = maybeParse(raw['avatar_decoration_data'], client.users.parseAvatarDecorationData); + return Member( id: maybeParse((raw['user'] as Map?)?['id'], Snowflake.parse) ?? userId ?? Snowflake.zero, manager: this, @@ -38,6 +40,8 @@ class MemberManager extends Manager { isPending: raw['pending'] as bool? ?? false, permissions: maybeParse(raw['permissions'], (String raw) => Permissions(int.parse(raw))), communicationDisabledUntil: maybeParse(raw['communication_disabled_until'], DateTime.parse), + avatarDecorationData: avatarDecorationData, + avatarDecorationHash: avatarDecorationData?.asset, ); } diff --git a/lib/src/http/managers/user_manager.dart b/lib/src/http/managers/user_manager.dart index ce903a67b..9f59d4856 100644 --- a/lib/src/http/managers/user_manager.dart +++ b/lib/src/http/managers/user_manager.dart @@ -17,6 +17,7 @@ import 'package:nyxx/src/models/locale.dart'; import 'package:nyxx/src/models/oauth2.dart'; import 'package:nyxx/src/models/snowflake.dart'; import 'package:nyxx/src/models/user/application_role_connection.dart'; +import 'package:nyxx/src/models/user/avatar_decoration_data.dart'; import 'package:nyxx/src/models/user/connection.dart'; import 'package:nyxx/src/models/user/user.dart'; import 'package:nyxx/src/utils/cache_helpers.dart'; @@ -37,6 +38,7 @@ class UserManager extends ReadOnlyManager { final hasFlags = raw['flags'] != null; final hasPremiumType = raw['premium_type'] != null; final hasPublicFlags = raw['public_flags'] != null; + final avatarDecorationData = maybeParse(raw['avatar_decoration_data'], parseAvatarDecorationData); return User( manager: this, @@ -54,7 +56,8 @@ class UserManager extends ReadOnlyManager { flags: hasFlags ? UserFlags(raw['flags'] as int) : null, nitroType: hasPremiumType ? NitroType(raw['premium_type'] as int) : NitroType.none, publicFlags: hasPublicFlags ? UserFlags(raw['public_flags'] as int) : null, - avatarDecorationHash: raw['avatar_decoration'] as String?, + avatarDecorationHash: avatarDecorationData?.asset, + avatarDecorationData: avatarDecorationData, ); } @@ -90,6 +93,14 @@ class UserManager extends ReadOnlyManager { ); } + /// Parse an [AvatarDecorationData] from [raw]. + AvatarDecorationData parseAvatarDecorationData(Map raw) { + return AvatarDecorationData( + asset: raw['asset'] as String, + skuId: Snowflake.parse(raw['sku_id']!), + ); + } + @override Future fetch(Snowflake id) async { final route = HttpRoute()..users(id: id.toString()); diff --git a/lib/src/http/route.dart b/lib/src/http/route.dart index b7cebaf49..ea86f5f81 100644 --- a/lib/src/http/route.dart +++ b/lib/src/http/route.dart @@ -315,6 +315,9 @@ extension RouteHelpers on HttpRoute { /// Adds the [`avatar-decorations`](https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints) part to this [HttpRoute]. void avatarDecorations({String? id}) => add(HttpRoutePart('avatar-decorations', [if (id != null) HttpRouteParam(id)])); + /// Adds the [`avatar-decoration-presets`](https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints) part to this [HttpRoute]. + void avatarDecorationPresets() => add(HttpRoutePart('avatar-decoration-presets')); + /// Adds the [`recipients`](https://discord.com/developers/docs/resources/channel#group-dm-add-recipient) part to this [HttpRoute]. void recipients({String? id}) => add(HttpRoutePart('recipients', [if (id != null) HttpRouteParam(id)])); diff --git a/lib/src/models/guild/member.dart b/lib/src/models/guild/member.dart index 8c48a17ed..74fd2738d 100644 --- a/lib/src/models/guild/member.dart +++ b/lib/src/models/guild/member.dart @@ -6,6 +6,7 @@ import 'package:nyxx/src/models/permissions.dart'; import 'package:nyxx/src/models/role.dart'; import 'package:nyxx/src/models/snowflake.dart'; import 'package:nyxx/src/models/snowflake_entity/snowflake_entity.dart'; +import 'package:nyxx/src/models/user/avatar_decoration_data.dart'; import 'package:nyxx/src/models/user/user.dart'; import 'package:nyxx/src/utils/flags.dart'; @@ -88,6 +89,12 @@ class Member extends PartialMember { /// The time until which this member is timed out. final DateTime? communicationDisabledUntil; + /// The member's guild avatar decoration data. + final AvatarDecorationData? avatarDecorationData; + + /// The member's guild avatar decoration. + final String? avatarDecorationHash; + /// {@macro member} /// @nodoc Member({ @@ -105,6 +112,8 @@ class Member extends PartialMember { required this.isPending, required this.permissions, required this.communicationDisabledUntil, + required this.avatarDecorationData, + required this.avatarDecorationHash, }); /// The roles this member has. @@ -121,6 +130,14 @@ class Member extends PartialMember { ..avatars(), hash: avatarHash!, ); + + CdnAsset? get avatarDecoration => avatarDecorationHash == null + ? null + : CdnAsset( + client: manager.client, + base: HttpRoute()..avatarDecorationPresets(), + hash: avatarDecorationHash!, + ); } /// Flags that can be applied to a [Member]. diff --git a/lib/src/models/user/avatar_decoration_data.dart b/lib/src/models/user/avatar_decoration_data.dart new file mode 100644 index 000000000..6b47f2f5d --- /dev/null +++ b/lib/src/models/user/avatar_decoration_data.dart @@ -0,0 +1,17 @@ +import 'package:nyxx/src/models/snowflake.dart'; +import 'package:nyxx/src/utils/to_string_helper/to_string_helper.dart'; + +/// {@template avatar_decoration_data} +/// The data for the user's [avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations). +/// {@endtemplate} +class AvatarDecorationData with ToStringHelper { + /// The ID of the avatar decoration's SKU. + final Snowflake skuId; + + /// The avatar decoration hash. + final String asset; + + /// {@macro avatar_decoration_data} + /// @nodoc + AvatarDecorationData({required this.skuId, required this.asset}); +} diff --git a/lib/src/models/user/user.dart b/lib/src/models/user/user.dart index 3d19f2fc6..998103ab5 100644 --- a/lib/src/models/user/user.dart +++ b/lib/src/models/user/user.dart @@ -6,6 +6,7 @@ import 'package:nyxx/src/models/discord_color.dart'; import 'package:nyxx/src/models/locale.dart'; import 'package:nyxx/src/models/message/author.dart'; import 'package:nyxx/src/models/snowflake_entity/snowflake_entity.dart'; +import 'package:nyxx/src/models/user/avatar_decoration_data.dart'; import 'package:nyxx/src/utils/enum_like.dart'; import 'package:nyxx/src/utils/flags.dart'; @@ -73,6 +74,9 @@ class User extends PartialUser implements MessageAuthor, CommandOptionMentionabl /// The hash of this user's avatar decoration. final String? avatarDecorationHash; + /// The user's avatar deciration data. + final AvatarDecorationData? avatarDecorationData; + /// {@macro user} /// @nodoc User({ @@ -92,6 +96,7 @@ class User extends PartialUser implements MessageAuthor, CommandOptionMentionabl required this.nitroType, required this.publicFlags, required this.avatarDecorationHash, + required this.avatarDecorationData, }); /// This user's banner. @@ -125,7 +130,7 @@ class User extends PartialUser implements MessageAuthor, CommandOptionMentionabl ? null : CdnAsset( client: manager.client, - base: HttpRoute()..avatarDecorations(id: id.toString()), + base: HttpRoute()..avatarDecorationPresets(), hash: avatarDecorationHash!, ); }