diff --git a/src/structures/User.js b/src/structures/User.js
index b7731e69a8f2..4af93f5f2f1a 100644
--- a/src/structures/User.js
+++ b/src/structures/User.js
@@ -75,6 +75,28 @@ class User extends Base {
this.avatar = null;
}
+ if ('banner' in data) {
+ /**
+ * The user banner's hash
+ * The user must be force fetched for this property to be present
+ * @type {?string}
+ */
+ this.banner = data.banner;
+ } else if (typeof this.banner !== 'string') {
+ this.banner = null;
+ }
+
+ if ('accent_color' in data) {
+ /**
+ * The base 10 accent 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;
+ } else if (typeof this.accentColor === 'undefined') {
+ this.accentColor = null;
+ }
+
if ('system' in data) {
/**
* Whether the user is an Official Discord System user (part of the urgent message system)
@@ -150,6 +172,28 @@ class User extends Base {
return this.avatarURL(options) ?? this.defaultAvatarURL;
}
+ /**
+ * The hexadecimal version of the user accent color, with a leading hash
+ * The user must be force fetched for this property to be present
+ * @type {?string}
+ * @readonly
+ */
+ get hexAccentColor() {
+ if (!this.accentColor) return null;
+ return `#${this.accentColor.toString(16).padStart(6, '0')}`;
+ }
+
+ /**
+ * A link to the user's banner.
+ * The user must be force fetched for this property to be present
+ * @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}
@@ -200,7 +244,8 @@ 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, 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}
@@ -211,7 +256,9 @@ 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 &&
+ this.accentColor === user.accentColor;
return equal;
}
@@ -253,12 +300,14 @@ class User extends Base {
{
createdTimestamp: true,
defaultAvatarURL: true,
+ hexAccentColor: true,
tag: true,
},
...props,
);
json.avatarURL = this.avatarURL();
json.displayAvatarURL = this.displayAvatarURL();
+ json.bannerURL = this.bannerURL();
return json;
}
diff --git a/src/util/Constants.js b/src/util/Constants.js
index dd6f5136c9fd..cb7d7abd739e 100644
--- a/src/util/Constants.js
+++ b/src/util/Constants.js
@@ -49,8 +49,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, dynamic = false) => {
+ 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 6155282bee79..9a55e9ff4071 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -1823,7 +1823,9 @@ export class Typing extends Base {
export class User extends PartialTextBasedChannel(Base) {
public constructor(client: Client, data: RawUserData);
+ public accentColor: number | null;
public avatar: string | null;
+ public banner: string | null;
public bot: boolean;
public readonly createdAt: Date;
public readonly createdTimestamp: number;
@@ -1831,12 +1833,14 @@ export class User extends PartialTextBasedChannel(Base) {
public readonly defaultAvatarURL: string;
public readonly dmChannel: DMChannel | null;
public flags: Readonly | null;
+ public readonly hexAccentColor: HexColorString | null;
public id: Snowflake;
public readonly partial: false;
public system: boolean;
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;
@@ -2151,7 +2155,13 @@ export const Constants: {
size: AllowedImageSize,
dynamic: boolean,
) => string;
- Banner: (guildId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize) => string;
+ Banner: (
+ id: Snowflake,
+ hash: string,
+ format: DynamicImageFormat,
+ size: AllowedImageSize,
+ dynamic: boolean,
+ ) => string;
Icon: (
guildId: Snowflake,
hash: string,