From 9788c4f6b6876e4239716a781562260f1ab671db Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 16:35:27 +0200 Subject: [PATCH 01/14] feat(User): support banners don't mind it for now, just trying --- src/structures/User.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/structures/User.js b/src/structures/User.js index 1deb996916aa..ca269d17d326 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -83,6 +83,16 @@ class User extends Base { } else if (typeof this.avatar !== 'string') { this.avatar = null; } + + if ('banner' in data) { + /** + * The ID of the user's banner + * @type {?string} + */ + this.banner = data.banner; + } else if (typeof this.banner !== 'string') { + this.banner = null; + } if ('system' in data) { /** From df6839872857b887a69d46c2ffdfae2d7a377b43 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 16:45:55 +0200 Subject: [PATCH 02/14] feat(User): support banners --- src/structures/User.js | 10 ++++++++++ src/util/Constants.js | 6 ++++-- typings/index.d.ts | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index ca269d17d326..772fb5df43e0 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -191,6 +191,16 @@ class User extends Base { return this.avatarURL(options) || this.defaultAvatarURL; } + /** + * A link to the user's banner. + * @param {ImageURLOptions} [options={}] Options for the Image URL + * @returns {?string} + */ + bannerURL({ format, size, dynamic } = {}) { + if (!this.banner) return null; + return this.client.rest.cdn.Banner(this.id, this.banner, format, size, dynamic); + } + /** * The Discord "tag" (e.g. `hydrabolt#0001`) for this user * @type {?string} diff --git a/src/util/Constants.js b/src/util/Constants.js index e4e158bc0ea7..a10adfa38fe5 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -159,8 +159,10 @@ exports.Endpoints = { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/avatars/${userID}/${hash}`, { format, size }); }, - Banner: (guildID, hash, format = 'webp', size) => - makeImageUrl(`${root}/banners/${guildID}/${hash}`, { format, size }), + Banner: (id, hash, format = 'webp', size) => { + if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; + return makeImageUrl(`${root}/banners/${id}/${hash}`, { format, size }); + }, Icon: (guildID, hash, format = 'webp', size, dynamic = false) => { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/icons/${guildID}/${hash}`, { format, size }); diff --git a/typings/index.d.ts b/typings/index.d.ts index 6231d16eba2b..1dae27ed7dba 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -570,7 +570,7 @@ declare module 'discord.js' { format: 'default' | AllowedImageFormat, size: number, ) => string; - Banner: (guildID: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; + Banner: (id: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; Icon: ( userID: Snowflake | number, hash: string, From 7f22b98357d37596a915b2ba348250d75c91b167 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 16:54:29 +0200 Subject: [PATCH 03/14] fix(Constants): declare dynamic --- src/util/Constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/Constants.js b/src/util/Constants.js index a10adfa38fe5..76bdf67d2488 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -159,7 +159,7 @@ exports.Endpoints = { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/avatars/${userID}/${hash}`, { format, size }); }, - Banner: (id, hash, format = 'webp', size) => { + Banner: (id, hash, format = 'webp', size, dynamic = false) => { if (dynamic) format = hash.startsWith('a_') ? 'gif' : format; return makeImageUrl(`${root}/banners/${id}/${hash}`, { format, size }); }, From 726e77c9371955acb04c6a35fc6fdbf34acad60d Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 16:54:37 +0200 Subject: [PATCH 04/14] fix(User): eslint --- src/structures/User.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/User.js b/src/structures/User.js index 772fb5df43e0..bb97620c8d97 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -83,7 +83,7 @@ class User extends Base { } else if (typeof this.avatar !== 'string') { this.avatar = null; } - + if ('banner' in data) { /** * The ID of the user's banner From 089e98483dd6d76e45400eb632d635c6c8a10209 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 17:00:30 +0200 Subject: [PATCH 05/14] typings: update User typings --- typings/index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/typings/index.d.ts b/typings/index.d.ts index 1dae27ed7dba..370638bd9fcb 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1973,6 +1973,7 @@ declare module 'discord.js' { export class User extends PartialTextBasedChannel(Base) { constructor(client: Client, data: unknown); public avatar: string | null; + public banner: string | null; public bot: boolean; public readonly createdAt: Date; public readonly createdTimestamp: number; @@ -1988,6 +1989,7 @@ declare module 'discord.js' { public readonly tag: string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; + public bannerURL(options?: ImageURLOptions): string | null; public createDM(): Promise; public deleteDM(): Promise; public displayAvatarURL(options?: ImageURLOptions): string; From e8134d558d4ad5da4a37b0b120be14a15bf70b61 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 17:28:17 +0200 Subject: [PATCH 06/14] fix(User): add banner to equals and json bannerURL --- src/structures/User.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index bb97620c8d97..c293c0694200 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -281,7 +281,7 @@ class User extends Base { } /** - * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, and bot flags. + * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, banner, and bot flags. * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. * @param {User} user User to compare with * @returns {boolean} @@ -292,7 +292,8 @@ class User extends Base { this.id === user.id && this.username === user.username && this.discriminator === user.discriminator && - this.avatar === user.avatar; + this.avatar === user.avatar && + this.banner === user.banner; return equal; } @@ -342,6 +343,7 @@ class User extends Base { ); json.avatarURL = this.avatarURL(); json.displayAvatarURL = this.displayAvatarURL(); + json.bannerURL = this.bannerURL(); return json; } From 6c57e2ec1b09a05b6af86a3851ac72c4037db660 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sat, 26 Jun 2021 22:22:13 +0200 Subject: [PATCH 07/14] typings: missing dynamic --- typings/index.d.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index 370638bd9fcb..0a84510be081 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -569,13 +569,21 @@ declare module 'discord.js' { hash: string, format: 'default' | AllowedImageFormat, size: number, + dynamic: boolean, + ) => string; + Banner: ( + id: Snowflake | number, + hash: string, + format: AllowedImageFormat, + size: number, + dynamic: boolean, ) => string; - Banner: (id: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; Icon: ( userID: Snowflake | number, hash: string, format: 'default' | AllowedImageFormat, size: number, + dynamic: boolean, ) => string; AppIcon: (userID: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; AppAsset: (userID: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; From 93df74782b598ca125b62d0d5e261bcde46de548 Mon Sep 17 00:00:00 2001 From: Koyamie Date: Sun, 4 Jul 2021 22:23:14 +0200 Subject: [PATCH 08/14] refactor: xID to xId --- src/structures/User.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index c293c0694200..b03b0542eddf 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -86,7 +86,7 @@ class User extends Base { if ('banner' in data) { /** - * The ID of the user's banner + * The user banner's hash * @type {?string} */ this.banner = data.banner; @@ -281,7 +281,7 @@ class User extends Base { } /** - * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, banner, and bot flags. + * Checks if the user is equal to another. It compares id, username, discriminator, avatar, banner, and bot flags. * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. * @param {User} user User to compare with * @returns {boolean} From 5c66ccb9f835b5091a78e4b7d9a1511e74183b6c Mon Sep 17 00:00:00 2001 From: Advaith Date: Thu, 15 Jul 2021 03:05:04 -0700 Subject: [PATCH 09/14] types: re-add typings --- typings/index.d.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index c8caf4dee5af..0bf943fe91f9 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1652,6 +1652,7 @@ export class ThreadMemberFlags extends BitField { export class User extends PartialTextBasedChannel(Base) { public constructor(client: Client, data: unknown); public avatar: string | null; + public banner: string | null; public bot: boolean; public readonly createdAt: Date; public readonly createdTimestamp: number; @@ -1665,6 +1666,7 @@ export class User extends PartialTextBasedChannel(Base) { public readonly tag: string; public username: string; public avatarURL(options?: ImageURLOptions): string | null; + public bannerURL(options?: ImageURLOptions): string | null; public createDM(): Promise; public deleteDM(): Promise; public displayAvatarURL(options?: ImageURLOptions): string; @@ -1977,8 +1979,20 @@ export const Constants: { format: 'default' | AllowedImageFormat, size: number, ) => string; - Banner: (guildId: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; - Icon: (userId: Snowflake | number, hash: string, format: 'default' | AllowedImageFormat, size: number) => string; + Banner: ( + id: Snowflake | number, + hash: string, + format: AllowedImageFormat, + size: number, + dynamic: boolean, + ) => string; + Icon: ( + userId: Snowflake | number, + hash: string, + format: 'default' | AllowedImageFormat, + size: number, + dynamic: boolean, + ) => string; AppIcon: (userId: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; AppAsset: (userId: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; GDMIcon: (userId: Snowflake | number, hash: string, format: AllowedImageFormat, size: number) => string; From 0456e43b7b968d0e0afdc1a7f39a1417140ee61e Mon Sep 17 00:00:00 2001 From: Advaith Date: Thu, 15 Jul 2021 04:15:53 -0700 Subject: [PATCH 10/14] feat: add banner color and fetch note --- src/structures/User.js | 30 ++++++++++++++++++++++++++++-- typings/index.d.ts | 2 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index b786b9ea9349..1443cac2ab82 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -78,6 +78,7 @@ class User extends Base { if ('banner' in data) { /** * The user banner's hash + * The user must be force fetched * @type {?string} */ this.banner = data.banner; @@ -85,6 +86,17 @@ class User extends Base { this.banner = null; } + if ('banner_color' in data) { + /** + * The hexadecimal version of the user banner color, with a leading hash + * The user must be force fetched + * @type {?string} + */ + this.hexBannerColor = data.banner_color; + } else if (typeof this.hexBannerColor !== 'string') { + this.hexBannerColor = null; + } + if ('system' in data) { /** * Whether the user is an Official Discord System user (part of the urgent message system) @@ -160,8 +172,20 @@ class User extends Base { return this.avatarURL(options) ?? this.defaultAvatarURL; } + /** + * The base 10 banner color of the user + * The user must be force fetched + * @type {?number} + * @readonly + */ + get bannerColor() { + if (!this.hexBannerColor) return null; + return parseInt(this.hexBannerColor.substring(1), 16); + } + /** * A link to the user's banner. + * The user must be force fetched * @param {ImageURLOptions} [options={}] Options for the Image URL * @returns {?string} */ @@ -248,7 +272,8 @@ class User extends Base { } /** - * Checks if the user is equal to another. It compares id, username, discriminator, avatar, banner, and bot flags. + * Checks if the user is equal to another. + * It compares id, username, discriminator, avatar, banner, banner color, and bot flags. * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. * @param {User} user User to compare with * @returns {boolean} @@ -260,7 +285,8 @@ class User extends Base { this.username === user.username && this.discriminator === user.discriminator && this.avatar === user.avatar && - this.banner === user.banner; + this.banner === user.banner && + this.hexBannerColor === user.hexBannerColor; return equal; } diff --git a/typings/index.d.ts b/typings/index.d.ts index 0bf943fe91f9..4f3d915e74b3 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1653,6 +1653,7 @@ export class User extends PartialTextBasedChannel(Base) { public constructor(client: Client, data: unknown); public avatar: string | null; public banner: string | null; + public readonly bannerColor: number | null; public bot: boolean; public readonly createdAt: Date; public readonly createdTimestamp: number; @@ -1660,6 +1661,7 @@ export class User extends PartialTextBasedChannel(Base) { public readonly defaultAvatarURL: string; public readonly dmChannel: DMChannel | null; public flags: Readonly | null; + public hexBannerColor: string | null; public id: Snowflake; public readonly partial: false; public system: boolean; From d7806caa9d108a76cd2d3c90d108102885b50b0c Mon Sep 17 00:00:00 2001 From: Advaith Date: Mon, 19 Jul 2021 15:07:15 -0700 Subject: [PATCH 11/14] feat: switch to accent color (swap hex and dec)) --- src/structures/User.js | 27 ++++++++++++++------------- typings/index.d.ts | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index 1443cac2ab82..e7cae9124c54 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -86,15 +86,15 @@ class User extends Base { this.banner = null; } - if ('banner_color' in data) { + if ('accent_color' in data) { /** - * The hexadecimal version of the user banner color, with a leading hash + * The base 10 accent color of the user * The user must be force fetched - * @type {?string} + * @type {?number} */ - this.hexBannerColor = data.banner_color; - } else if (typeof this.hexBannerColor !== 'string') { - this.hexBannerColor = null; + this.accentColor = data.accent_color; + } else if (typeof this.accentColor === 'undefined') { + this.accentColor = null; } if ('system' in data) { @@ -173,14 +173,14 @@ class User extends Base { } /** - * The base 10 banner color of the user + * The hexadecimal version of the user accent color, with a leading hash * The user must be force fetched - * @type {?number} + * @type {?string} * @readonly */ - get bannerColor() { - if (!this.hexBannerColor) return null; - return parseInt(this.hexBannerColor.substring(1), 16); + get hexAccentColor() { + if (!this.accentColor) return null; + return `#${this.accentColor.toString(16).padStart(6, '0')}`; } /** @@ -273,7 +273,7 @@ class User extends Base { /** * Checks if the user is equal to another. - * It compares id, username, discriminator, avatar, banner, banner color, and bot flags. + * It compares id, username, discriminator, avatar, banner, accent color, and bot flags. * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. * @param {User} user User to compare with * @returns {boolean} @@ -286,7 +286,7 @@ class User extends Base { this.discriminator === user.discriminator && this.avatar === user.avatar && this.banner === user.banner && - this.hexBannerColor === user.hexBannerColor; + this.accentColor === user.accentColor; return equal; } @@ -328,6 +328,7 @@ class User extends Base { { createdTimestamp: true, defaultAvatarURL: true, + hexAccentColor: true, tag: true, }, ...props, diff --git a/typings/index.d.ts b/typings/index.d.ts index 4f3d915e74b3..d707b3f6efe4 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1651,9 +1651,9 @@ export class ThreadMemberFlags extends BitField { export class User extends PartialTextBasedChannel(Base) { public constructor(client: Client, data: unknown); + public accentColor: number | null; public avatar: string | null; public banner: string | null; - public readonly bannerColor: number | null; public bot: boolean; public readonly createdAt: Date; public readonly createdTimestamp: number; @@ -1661,7 +1661,7 @@ export class User extends PartialTextBasedChannel(Base) { public readonly defaultAvatarURL: string; public readonly dmChannel: DMChannel | null; public flags: Readonly | null; - public hexBannerColor: string | null; + public readonly hexAccentColor: string | null; public id: Snowflake; public readonly partial: false; public system: boolean; From b96af9197043d4e69ba18fe9ab7bd0b8e3a17862 Mon Sep 17 00:00:00 2001 From: Noel Date: Tue, 24 Aug 2021 22:28:00 +0200 Subject: [PATCH 12/14] Update src/structures/User.js Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com> --- src/structures/User.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index 207322910f7d..f8ca84c09fa9 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -88,8 +88,8 @@ class User extends Base { if ('accent_color' in data) { /** - * The base 10 accent color of the user - * The user must be force fetched + * The base 10 color of the user's banner + * The user must be force fetched for this property to be present * @type {?number} */ this.accentColor = data.accent_color; From a4341b6698a079c47e6bf4225a51de461355d896 Mon Sep 17 00:00:00 2001 From: Noel Date: Tue, 24 Aug 2021 22:28:07 +0200 Subject: [PATCH 13/14] Update typings/index.d.ts Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com> --- typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index be27ecbe29ab..9a55e9ff4071 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1833,7 +1833,7 @@ export class User extends PartialTextBasedChannel(Base) { public readonly defaultAvatarURL: string; public readonly dmChannel: DMChannel | null; public flags: Readonly | null; - public readonly hexAccentColor: string | null; + public readonly hexAccentColor: HexColorString | null; public id: Snowflake; public readonly partial: false; public system: boolean; From 225eb4c0089ee035e06546c67e2613c57d0c3ec2 Mon Sep 17 00:00:00 2001 From: Noel Date: Tue, 24 Aug 2021 22:31:06 +0200 Subject: [PATCH 14/14] Apply suggestions from code review --- src/structures/User.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/structures/User.js b/src/structures/User.js index f8ca84c09fa9..4af93f5f2f1a 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -78,7 +78,7 @@ class User extends Base { if ('banner' in data) { /** * The user banner's hash - * The user must be force fetched + * The user must be force fetched for this property to be present * @type {?string} */ this.banner = data.banner; @@ -88,7 +88,7 @@ class User extends Base { if ('accent_color' in data) { /** - * The base 10 color of the user's banner + * The base 10 accent color of the user's banner * The user must be force fetched for this property to be present * @type {?number} */ @@ -174,7 +174,7 @@ class User extends Base { /** * The hexadecimal version of the user accent color, with a leading hash - * The user must be force fetched + * The user must be force fetched for this property to be present * @type {?string} * @readonly */ @@ -185,7 +185,7 @@ class User extends Base { /** * A link to the user's banner. - * The user must be force fetched + * The user must be force fetched for this property to be present * @param {ImageURLOptions} [options={}] Options for the Image URL * @returns {?string} */