diff --git a/packages/discord.js/src/structures/GuildMember.js b/packages/discord.js/src/structures/GuildMember.js index 6c428284cb85..3be4822e071c 100644 --- a/packages/discord.js/src/structures/GuildMember.js +++ b/packages/discord.js/src/structures/GuildMember.js @@ -133,6 +133,20 @@ class GuildMember extends Base { } else { this.flags ??= new GuildMemberFlagsBitField().freeze(); } + + if (data.avatar_decoration_data) { + /** + * The member avatar decoration's data + * + * @type {?AvatarDecorationData} + */ + this.avatarDecorationData = { + asset: data.avatar_decoration_data.asset, + skuId: data.avatar_decoration_data.sku_id, + }; + } else { + this.avatarDecorationData = null; + } } _clone() { @@ -181,6 +195,15 @@ class GuildMember extends Base { return this.avatar && this.client.rest.cdn.guildMemberAvatar(this.guild.id, this.id, this.avatar, options); } + /** + * A link to the member's avatar decoration. + * + * @returns {?string} + */ + avatarDecorationURL() { + return this.avatarDecorationData ? this.client.rest.cdn.avatarDecoration(this.avatarDecorationData.asset) : null; + } + /** * A link to the member's banner. * @@ -213,6 +236,16 @@ class GuildMember extends Base { return this.bannerURL(options) ?? this.user.bannerURL(options); } + /** + * A link to the member's guild avatar decoration if they have one. + * Otherwise, a link to their {@link User#avatarDecorationURL} will be returned. + * + * @returns {?string} + */ + displayAvatarDecorationURL() { + return this.avatarDecorationURL() ?? this.user.avatarDecorationURL(); + } + /** * The time this member joined the guild * @@ -560,7 +593,9 @@ class GuildMember extends Base { this.flags.bitfield === member.flags.bitfield && (this._roles === member._roles || (this._roles.length === member._roles.length && - this._roles.every((role, index) => role === member._roles[index]))) + this._roles.every((role, index) => role === member._roles[index]))) && + this.avatarDecorationData?.asset === member.avatarDecorationData?.asset && + this.avatarDecorationData?.skuId === member.avatarDecorationData?.skuId ); } @@ -587,6 +622,7 @@ class GuildMember extends Base { json.bannerURL = this.bannerURL(); json.displayAvatarURL = this.displayAvatarURL(); json.displayBannerURL = this.displayBannerURL(); + json.avatarDecorationURL = this.avatarDecorationURL(); return json; } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index ed2da0646c0f..5858f8e3f6b5 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1596,6 +1596,7 @@ export class GuildMember extends Base { private constructor(client: Client, data: unknown, guild: Guild); private readonly _roles: Snowflake[]; public avatar: string | null; + public avatarDecorationData: AvatarDecorationData | null; public banner: string | null; public get bannable(): boolean; public get dmChannel(): DMChannel | null; @@ -1623,6 +1624,7 @@ export class GuildMember extends Base { public user: User; public get voice(): VoiceState; public avatarURL(options?: ImageURLOptions): string | null; + public avatarDecorationURL(): string | null; public bannerURL(options?: ImageURLOptions): string | null; public ban(options?: BanOptions): Promise; public disableCommunicationUntil(timeout: DateResolvable | null, reason?: string): Promise; @@ -1632,6 +1634,7 @@ export class GuildMember extends Base { public deleteDM(): Promise; public displayAvatarURL(options?: ImageURLOptions): string; public displayBannerURL(options?: ImageURLOptions): string | null; + public displayAvatarDecorationURL(): string | null; public edit(options: GuildMemberEditOptions): Promise; public isCommunicationDisabled(): this is GuildMember & { readonly communicationDisabledUntil: Date; @@ -3534,7 +3537,7 @@ export class User extends Base { public get tag(): string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; - public avatarDecorationURL(options?: BaseImageURLOptions): string | null; + public avatarDecorationURL(): string | null; public bannerURL(options?: ImageURLOptions): string | null | undefined; public createDM(force?: boolean): Promise; public deleteDM(): Promise;