mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 08:03:30 +01:00
feat: support new username system (#9634)
* feat: support new username system (v13) * fix(User): check global name in equals * Update typings/index.d.ts Co-authored-by: Jaw0r3k <jaworekwiadomosci@gmail.com> * Update src/util/Util.js Co-authored-by: Jaw0r3k <jaworekwiadomosci@gmail.com> * typing * Update User.js * Update index.d.ts * Update User.js --------- Co-authored-by: Jaw0r3k <jaworekwiadomosci@gmail.com>
This commit is contained in:
@@ -259,12 +259,12 @@ class GuildMember extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* The nickname of this member, or their username if they don't have one
|
||||
* The nickname of this member, or their user display name if they don't have one
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get displayName() {
|
||||
return this.nickname ?? this.user.username;
|
||||
return this.nickname ?? this.user.displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { Error } = require('../errors');
|
||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
||||
const UserFlags = require('../util/UserFlags');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents a user on Discord.
|
||||
@@ -41,6 +42,16 @@ class User extends Base {
|
||||
this.username ??= null;
|
||||
}
|
||||
|
||||
if ('global_name' in data) {
|
||||
/**
|
||||
* The global name of this user
|
||||
* @type {?string}
|
||||
*/
|
||||
this.globalName = data.global_name;
|
||||
} else {
|
||||
this.globalName ??= null;
|
||||
}
|
||||
|
||||
if ('bot' in data) {
|
||||
/**
|
||||
* Whether or not the user is a bot
|
||||
@@ -53,7 +64,8 @@ class User extends Base {
|
||||
|
||||
if ('discriminator' in data) {
|
||||
/**
|
||||
* A discriminator based on username for the user
|
||||
* The discriminator of this user
|
||||
* <info>`'0'`, or a 4-digit stringified number if they're using the legacy username system</info>
|
||||
* @type {?string}
|
||||
*/
|
||||
this.discriminator = data.discriminator;
|
||||
@@ -155,7 +167,8 @@ class User extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get defaultAvatarURL() {
|
||||
return this.client.rest.cdn.DefaultAvatar(this.discriminator % 5);
|
||||
const index = this.discriminator === '0' ? Util.calculateUserDefaultAvatarIndex(this.id) : this.discriminator % 5;
|
||||
return this.client.rest.cdn.DefaultAvatar(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,12 +206,27 @@ class User extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Discord "tag" (e.g. `hydrabolt#0001`) for this user
|
||||
* The tag of this user
|
||||
* <info>This user's username, or their legacy tag (e.g. `hydrabolt#0001`)
|
||||
* if they're using the legacy username system</info>
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get tag() {
|
||||
return typeof this.username === 'string' ? `${this.username}#${this.discriminator}` : null;
|
||||
return typeof this.username === 'string'
|
||||
? this.discriminator === '0'
|
||||
? this.username
|
||||
: `${this.username}#${this.discriminator}`
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The global name of this user, or their username if they don't have one
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get displayName() {
|
||||
return this.globalName ?? this.username;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,6 +268,7 @@ class User extends Base {
|
||||
this.id === user.id &&
|
||||
this.username === user.username &&
|
||||
this.discriminator === user.discriminator &&
|
||||
this.globalName === user.globalName &&
|
||||
this.avatar === user.avatar &&
|
||||
this.flags?.bitfield === user.flags?.bitfield &&
|
||||
this.banner === user.banner &&
|
||||
@@ -259,6 +288,7 @@ class User extends Base {
|
||||
this.id === user.id &&
|
||||
this.username === user.username &&
|
||||
this.discriminator === user.discriminator &&
|
||||
this.globalName === user.global_name &&
|
||||
this.avatar === user.avatar &&
|
||||
this.flags?.bitfield === user.public_flags &&
|
||||
('banner' in user ? this.banner === user.banner : true) &&
|
||||
|
||||
@@ -68,7 +68,7 @@ exports.Endpoints = {
|
||||
return {
|
||||
Emoji: (emojiId, format = 'webp') => `${root}/emojis/${emojiId}.${format}`,
|
||||
Asset: name => `${root}/assets/${name}`,
|
||||
DefaultAvatar: discriminator => `${root}/embed/avatars/${discriminator}.png`,
|
||||
DefaultAvatar: index => `${root}/embed/avatars/${index}.png`,
|
||||
Avatar: (userId, hash, format, size, dynamic = false) => {
|
||||
if (dynamic && hash.startsWith('a_')) format = 'gif';
|
||||
return makeImageUrl(`${root}/avatars/${userId}/${hash}`, { format, size });
|
||||
|
||||
@@ -741,6 +741,15 @@ class Util extends null {
|
||||
emoji_name: defaultReaction.name,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the default avatar index for a given user id.
|
||||
* @param {Snowflake} userId - The user id to calculate the default avatar index for
|
||||
* @returns {number}
|
||||
*/
|
||||
static calculateUserDefaultAvatarIndex(userId) {
|
||||
return Number(BigInt(userId) >> 22n) % 6;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Util;
|
||||
|
||||
5
typings/index.d.ts
vendored
5
typings/index.d.ts
vendored
@@ -2703,9 +2703,11 @@ export class User extends PartialTextBasedChannel(Base) {
|
||||
public readonly createdAt: Date;
|
||||
public readonly createdTimestamp: number;
|
||||
public discriminator: string;
|
||||
public readonly displayName: string;
|
||||
public readonly defaultAvatarURL: string;
|
||||
public readonly dmChannel: DMChannel | null;
|
||||
public flags: Readonly<UserFlags> | null;
|
||||
public globalName: string | null;
|
||||
public readonly hexAccentColor: HexColorString | null | undefined;
|
||||
public id: Snowflake;
|
||||
public readonly partial: false;
|
||||
@@ -2785,6 +2787,7 @@ export class Util extends null {
|
||||
public static splitMessage(text: string, options?: SplitOptions): string[];
|
||||
/** @deprecated This will be removed in the next major version. */
|
||||
public static resolveAutoArchiveMaxLimit(guild: Guild): Exclude<ThreadAutoArchiveDuration, 60>;
|
||||
public static calculateUserDefaultAvatarIndex(userId: Snowflake): number;
|
||||
}
|
||||
|
||||
export class Formatters extends null {
|
||||
@@ -3093,7 +3096,7 @@ export const Constants: {
|
||||
dynamic: boolean,
|
||||
): string;
|
||||
Banner(id: Snowflake, hash: string, format: DynamicImageFormat, size: AllowedImageSize, dynamic: boolean): string;
|
||||
DefaultAvatar(discriminator: number): string;
|
||||
DefaultAvatar(index: number): string;
|
||||
DiscoverySplash(guildId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize): string;
|
||||
Emoji(emojiId: Snowflake, format: DynamicImageFormat): string;
|
||||
GDMIcon(channelId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize): string;
|
||||
|
||||
Reference in New Issue
Block a user