feat(GuildMember): add guild avatars (#5696)

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Shubham Parihar <shubhamparihar391@gmail.com>
Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>
This commit is contained in:
Rodry
2021-09-28 17:53:37 +01:00
committed by GitHub
parent 7cba67620e
commit dfd7b403a9
3 changed files with 49 additions and 1 deletions

View File

@@ -71,6 +71,15 @@ class GuildMember extends Base {
}
if ('nick' in data) this.nickname = data.nick;
if ('avatar' in data) {
/**
* The guild member's avatar hash
* @type {?string}
*/
this.avatar = data.avatar;
} else if (typeof this.avatar !== 'string') {
this.avatar = null;
}
if ('joined_at' in data) this.joinedTimestamp = new Date(data.joined_at).getTime();
if ('premium_since' in data) {
this.premiumSinceTimestamp = data.premium_since ? new Date(data.premium_since).getTime() : null;
@@ -112,6 +121,26 @@ class GuildMember extends Base {
return this.guild.voiceStates.cache.get(this.id) ?? new VoiceState(this.guild, { user_id: this.id });
}
/**
* A link to the member's guild avatar.
* @param {ImageURLOptions} [options={}] Options for the Image URL
* @returns {?string}
*/
avatarURL({ format, size, dynamic } = {}) {
if (!this.avatar) return null;
return this.client.rest.cdn.GuildMemberAvatar(this.guild.id, this.id, this.avatar, format, size, dynamic);
}
/**
* A link to the member's guild avatar if they have one.
* Otherwise, a link to their {@link User#displayAvatarURL} will be returned.
* @param {ImageURLOptions} [options={}] Options for the Image URL
* @returns {string}
*/
displayAvatarURL(options) {
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
}
/**
* The time this member joined the guild
* @type {?Date}
@@ -323,6 +352,7 @@ class GuildMember extends Base {
this.guild.id === member.guild.id &&
this.joinedTimestamp === member.joinedTimestamp &&
this.nickname === member.nickname &&
this.avatar === member.avatar &&
this.pending === member.pending &&
(this._roles === member._roles ||
(this._roles.length === member._roles.length && this._roles.every((role, i) => role === member._roles[i])))
@@ -341,12 +371,15 @@ class GuildMember extends Base {
}
toJSON() {
return super.toJSON({
const json = super.toJSON({
guild: 'guildId',
user: 'userId',
displayName: true,
roles: true,
});
json.avatarURL = this.avatarURL();
json.displayAvatarURL = this.displayAvatarURL();
return json;
}
// These are here only for documentation purposes - they are implemented by TextBasedChannel

View File

@@ -49,6 +49,10 @@ exports.Endpoints = {
if (dynamic && hash.startsWith('a_')) format = 'gif';
return makeImageUrl(`${root}/avatars/${userId}/${hash}`, { format, size });
},
GuildMemberAvatar: (guildId, memberId, hash, format = 'webp', size, dynamic = false) => {
if (dynamic && hash.startsWith('a_')) format = 'gif';
return makeImageUrl(`${root}/guilds/${guildId}/users/${memberId}/avatars/${hash}`, { format, size });
},
Banner: (id, hash, format, size, dynamic = false) => {
if (dynamic && hash.startsWith('a_')) format = 'gif';
return makeImageUrl(`${root}/banners/${id}/${hash}`, { format, size });

11
typings/index.d.ts vendored
View File

@@ -873,6 +873,7 @@ export class GuildEmoji extends BaseGuildEmoji {
export class GuildMember extends PartialTextBasedChannel(Base) {
public constructor(client: Client, data: RawGuildMemberData, guild: Guild);
public avatar: string | null;
public readonly bannable: boolean;
public deleted: boolean;
public readonly displayColor: number;
@@ -894,10 +895,12 @@ export class GuildMember extends PartialTextBasedChannel(Base) {
public readonly roles: GuildMemberRoleManager;
public user: User;
public readonly voice: VoiceState;
public avatarURL(options?: ImageURLOptions): string | null;
public ban(options?: BanOptions): Promise<GuildMember>;
public fetch(force?: boolean): Promise<GuildMember>;
public createDM(force?: boolean): Promise<DMChannel>;
public deleteDM(): Promise<DMChannel>;
public displayAvatarURL(options?: ImageURLOptions): string;
public edit(data: GuildMemberEditData, reason?: string): Promise<GuildMember>;
public kick(reason?: string): Promise<GuildMember>;
public permissionsIn(channel: GuildChannelResolvable): Readonly<Permissions>;
@@ -2297,6 +2300,14 @@ export const Constants: {
size: AllowedImageSize,
dynamic: boolean,
) => string;
GuildMemberAvatar: (
guildId: Snowflake,
memberId: Snowflake,
hash: string,
format?: DynamicImageFormat,
size?: AllowedImageSize,
dynamic?: boolean,
) => string;
Icon: (
guildId: Snowflake,
hash: string,