feat: support user guilds

backport #10995
This commit is contained in:
Elysia
2025-09-13 18:04:34 +07:00
parent ad64e2be11
commit 6fbb62ac64
3 changed files with 87 additions and 56 deletions

View File

@@ -142,6 +142,7 @@ class User extends Base {
* @property {Snowflake} skuId The id of the avatar decoration's SKU * @property {Snowflake} skuId The id of the avatar decoration's SKU
*/ */
if (data.avatar_decoration_data) {
if (data.avatar_decoration_data) { if (data.avatar_decoration_data) {
/** /**
* The user avatar decoration's data * The user avatar decoration's data
@@ -154,20 +155,23 @@ class User extends Base {
} else { } else {
this.avatarDecorationData = null; this.avatarDecorationData = null;
} }
} else {
this.avatarDecorationData ??= null;
}
if ('primary_guild' in data && data.primary_guild) {
/** /**
* Primary Guild Structure * @typedef {Object} UserPrimaryGuild
* @see {@link https://docs.discord.food/resources/user#primary-guild-structure} * @property {?Snowflake} identityGuildId The id of the user's primary guild
* @typedef {Object} PrimaryGuild * @property {?boolean} identityEnabled Whether the user is displaying the primary guild's tag
* @property {?Snowflake} identityGuildId The ID of the user's primary clan * @property {?string} tag The user's guild tag. Limited to 4 characters
* @property {?boolean} identityEnabled Whether the user is displaying their guild tag
* @property {?string} tag The user's guild tag (max 4 characters)
* @property {?string} badge The guild tag badge hash * @property {?string} badge The guild tag badge hash
*/ */
if ('primary_guild' in data) {
if (data.primary_guild) {
/** /**
* The primary clan the user is in * The primary guild of the user
* @type {?PrimaryGuild} * @type {?UserPrimaryGuild}
*/ */
this.primaryGuild = { this.primaryGuild = {
identityGuildId: data.primary_guild.identity_guild_id, identityGuildId: data.primary_guild.identity_guild_id,
@@ -175,6 +179,9 @@ class User extends Base {
tag: data.primary_guild.tag, tag: data.primary_guild.tag,
badge: data.primary_guild.badge, badge: data.primary_guild.badge,
}; };
} else {
this.primaryGuild = null;
}
} else { } else {
this.primaryGuild ??= null; this.primaryGuild ??= null;
} }
@@ -193,22 +200,24 @@ class User extends Base {
*/ */
if (data.collectibles) { if (data.collectibles) {
if (data.collectibles.nameplate) {
/** /**
* The user's collectibles * The user's collectibles
* @type {?Collectibles} * @type {?Collectibles}
*/ */
this.collectibles = data.collectibles.nameplate this.collectibles = {
? {
nameplate: { nameplate: {
skuId: data.collectibles.nameplate.sku_id, skuId: data.collectibles.nameplate.sku_id,
asset: data.collectibles.nameplate.asset, asset: data.collectibles.nameplate.asset,
label: data.collectibles.nameplate.label, label: data.collectibles.nameplate.label,
palette: data.collectibles.nameplate.palette, palette: data.collectibles.nameplate.palette,
}, },
} };
: { nameplate: null };
} else { } else {
this.collectibles = null; this.collectibles = { nameplate: null };
}
} else {
this.collectibles ??= null;
} }
} }
@@ -278,12 +287,21 @@ class User extends Base {
} }
/** /**
* A link to the user's clan badge. * A link to the user's guild tag badge.
* @returns {?string} * @returns {?string}
* @deprecated
*/ */
clanBadgeURL() { clanBadgeURL() {
if (!this.clan || !this.clan.identityGuildId || !this.clan.badge) return null; return this.guildTagBadgeURL();
return this.client.rest.cdn.ClanBadge(this.clan.identityGuildId, this.clan.badge); }
/**
* A link to the user's guild tag badge.
* @returns {?string}
*/
guildTagBadgeURL() {
if (!this.primaryGuild || !this.primaryGuild.identityGuildId || !this.primaryGuild.badge) return null;
return this.client.rest.cdn.GuildTagBadge(this.primaryGuild.identityGuildId, this.primaryGuild.badge);
} }
/** /**
@@ -403,7 +421,11 @@ class User extends Base {
this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.skuId && this.collectibles?.nameplate?.skuId === user.collectibles?.nameplate?.skuId &&
this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset && this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset &&
this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label && this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label &&
this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette &&
this.primaryGuild?.identityGuildId === user.primaryGuild?.identityGuildId &&
this.primaryGuild?.identityEnabled === user.primaryGuild?.identityEnabled &&
this.primaryGuild?.tag === user.primaryGuild?.tag &&
this.primaryGuild?.badge === user.primaryGuild?.badge
); );
} }
@@ -433,6 +455,12 @@ class User extends Base {
this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset && this.collectibles?.nameplate?.asset === user.collectibles?.nameplate?.asset &&
this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label && this.collectibles?.nameplate?.label === user.collectibles?.nameplate?.label &&
this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette this.collectibles?.nameplate?.palette === user.collectibles?.nameplate?.palette
: true) &&
('primary_guild' in user
? this.primaryGuild?.identityGuildId === user.primary_guild?.identity_guild_id &&
this.primaryGuild?.identityEnabled === user.primary_guild?.identity_enabled &&
this.primaryGuild?.tag === user.primary_guild?.tag &&
this.primaryGuild?.badge === user.primary_guild?.badge
: true) : true)
); );
} }
@@ -493,6 +521,7 @@ class User extends Base {
json.avatarURL = this.avatarURL(); json.avatarURL = this.avatarURL();
json.displayAvatarURL = this.displayAvatarURL(); json.displayAvatarURL = this.displayAvatarURL();
json.bannerURL = this.banner ? this.bannerURL() : this.banner; json.bannerURL = this.banner ? this.bannerURL() : this.banner;
json.guildTagBadgeURL = this.guildTagBadgeURL();
return json; return json;
} }

View File

@@ -97,7 +97,7 @@ exports.Endpoints = {
return makeImageUrl(`${root}/avatars/${userId}/${hash}`, { format, size }); return makeImageUrl(`${root}/avatars/${userId}/${hash}`, { format, size });
}, },
AvatarDecoration: hash => makeImageUrl(`${root}/avatar-decoration-presets/${hash}`, { format: 'png' }), AvatarDecoration: hash => makeImageUrl(`${root}/avatar-decoration-presets/${hash}`, { format: 'png' }),
ClanBadge: (guildId, hash) => `${root}/clan-badges/${guildId}/${hash}.png`, GuildTagBadge: (guildId, hash) => `${root}/guild-tag-badges/${guildId}/${hash}.png`,
GuildMemberAvatar: (guildId, memberId, hash, format = 'webp', size, dynamic = false) => { GuildMemberAvatar: (guildId, memberId, hash, format = 'webp', size, dynamic = false) => {
if (dynamic && hash.startsWith('a_')) format = 'gif'; if (dynamic && hash.startsWith('a_')) format = 'gif';
return makeImageUrl(`${root}/guilds/${guildId}/users/${memberId}/avatars/${hash}`, { format, size }); return makeImageUrl(`${root}/guilds/${guildId}/users/${memberId}/avatars/${hash}`, { format, size });

16
typings/index.d.ts vendored
View File

@@ -3716,11 +3716,11 @@ export class Typing extends Base {
}; };
} }
export interface PrimaryGuild { export interface UserPrimaryGuild {
identityGuildId?: Snowflake; badge: string | null;
identityEnabled?: boolean; identityEnabled: boolean | null;
tag?: string; identityGuildId: Snowflake | null;
badge?: string; tag: string | null;
} }
export interface AvatarDecorationData { export interface AvatarDecorationData {
@@ -3770,13 +3770,15 @@ export class User extends PartialTextBasedChannel(Base) {
public readonly voice?: VoiceState; public readonly voice?: VoiceState;
public readonly relationship: RelationshipTypes; public readonly relationship: RelationshipTypes;
public readonly friendNickname: string | null | undefined; public readonly friendNickname: string | null | undefined;
public primaryGuild: PrimaryGuild | null; public primaryGuild: UserPrimaryGuild | null;
/** @deprecated Use {@link User.primaryGuild} instead */ /** @deprecated Use {@link User.primaryGuild} instead */
public clan: PrimaryGuild | null; public clan: PrimaryGuild | null;
public avatarURL(options?: ImageURLOptions): string | null; public avatarURL(options?: ImageURLOptions): string | null;
public avatarDecorationURL(): string | null; public avatarDecorationURL(): string | null;
public bannerURL(options?: ImageURLOptions): string | null; public bannerURL(options?: ImageURLOptions): string | null;
/** @deprecated Use {@link User.guildTagBadgeURL} instead */
public clanBadgeURL(): string | null; public clanBadgeURL(): string | null;
public guildTagBadgeURL(options?: ImageURLOptions): string | null;
public createDM(force?: boolean): Promise<DMChannel>; public createDM(force?: boolean): Promise<DMChannel>;
public deleteDM(): Promise<DMChannel>; public deleteDM(): Promise<DMChannel>;
public displayAvatarURL(options?: ImageURLOptions): string; public displayAvatarURL(options?: ImageURLOptions): string;
@@ -4178,7 +4180,7 @@ export const Constants: {
dynamic: boolean, dynamic: boolean,
): string; ): string;
AvatarDecoration(hash: string): string; AvatarDecoration(hash: string): string;
ClanBadge(guildId: Snowflake, hash: string): string; GuildTagBadge(guildId: Snowflake, hash: string): string;
Banner(id: Snowflake, hash: string, format: DynamicImageFormat, size: AllowedImageSize, dynamic: boolean): string; Banner(id: Snowflake, hash: string, format: DynamicImageFormat, size: AllowedImageSize, dynamic: boolean): string;
DefaultAvatar(index: number): string; DefaultAvatar(index: number): string;
DiscoverySplash(guildId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize): string; DiscoverySplash(guildId: Snowflake, hash: string, format: AllowedImageFormat, size: AllowedImageSize): string;