diff --git a/src/client/actions/PresenceUpdate.js b/src/client/actions/PresenceUpdate.js index 649bf6ce0850..538789e25119 100644 --- a/src/client/actions/PresenceUpdate.js +++ b/src/client/actions/PresenceUpdate.js @@ -5,40 +5,38 @@ const { Events } = require('../../util/Constants'); class PresenceUpdateAction extends Action { handle(data) { - let cached = this.client.users.get(data.user.id); - if (!cached && data.user.username) cached = this.client.users.add(data.user); - if (!cached) return; + let user = this.client.users.get(data.user.id); + if (!user && data.user.username) user = this.client.users.add(data.user); + if (!user) return; if (data.user && data.user.username) { - if (!cached.equals(data.user)) this.client.actions.UserUpdate.handle(data.user); + if (!user.equals(data.user)) this.client.actions.UserUpdate.handle(data.user); } const guild = this.client.guilds.get(data.guild_id); if (!guild) return; - let member = guild.members.get(cached.id); + let oldPresence = guild.presences.get(user.id); + if (oldPresence) oldPresence = oldPresence._clone(); + let member = guild.members.get(user.id); if (!member && data.status !== 'offline') { - member = guild.members.add({ user: cached, roles: data.roles, deaf: false, mute: false }); + member = guild.members.add({ + user, + roles: data.roles, + deaf: false, + mute: false, + }); this.client.emit(Events.GUILD_MEMBER_AVAILABLE, member); } - - if (member) { - if (this.client.listenerCount(Events.PRESENCE_UPDATE) === 0) { - guild.presences.add(data); - return; - } - const old = member._clone(); - if (member.presence) old.frozenPresence = member.presence._clone(); - guild.presences.add(data); + guild.presences.add(Object.assign(data, { guild })); + if (member && this.client.listenerCount(Events.PRESENCE_UPDATE)) { /** - * Emitted whenever a guild member's presence changes, or they change one of their details. + * Emitted whenever a guild member's presence (e.g. status, activity) is changed. * @event Client#presenceUpdate - * @param {GuildMember} oldMember The member before the presence update - * @param {GuildMember} newMember The member after the presence update + * @param {?Presence} oldPresence The presence before the update, if one at all + * @param {Presence} newPresence The presence after the update */ - this.client.emit(Events.PRESENCE_UPDATE, old, member); - } else { - guild.presences.add(data); + this.client.emit(Events.PRESENCE_UPDATE, oldPresence, member.presence); } } } diff --git a/typings/index.d.ts b/typings/index.d.ts index 4c32f0b1bb94..d1894df89d59 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -169,13 +169,14 @@ declare module 'discord.js' { public on(event: 'guildMemberAdd' | 'guildMemberAvailable' | 'guildMemberRemove', listener: (member: GuildMember) => void): this; public on(event: 'guildMembersChunk', listener: (members: Collection, guild: Guild) => void): this; public on(event: 'guildMemberSpeaking', listener: (member: GuildMember, speaking: Readonly) => void): this; - public on(event: 'guildMemberUpdate' | 'presenceUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this; + public on(event: 'guildMemberUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this; public on(event: 'guildUpdate', listener: (oldGuild: Guild, newGuild: Guild) => void): this; public on(event: 'guildIntegrationsUpdate', listener: (guild: Guild) => void): this; public on(event: 'message' | 'messageDelete' | 'messageReactionRemoveAll', listener: (message: Message) => void): this; public on(event: 'messageDeleteBulk', listener: (messages: Collection) => void): this; public on(event: 'messageReactionAdd' | 'messageReactionRemove', listener: (messageReaction: MessageReaction, user: User) => void): this; public on(event: 'messageUpdate', listener: (oldMessage: Message, newMessage: Message) => void): this; + public on(event: 'presenceUpdate', listener: (oldPresence: Presence | undefined, newPresence: Presence) => void): this; public on(event: 'rateLimit', listener: (rateLimitData: RateLimitData) => void): this; public on(event: 'ready', listener: () => void): this; public on(event: 'resume', listener: (replayed: number, shardID: number) => void): this; @@ -206,13 +207,14 @@ declare module 'discord.js' { public once(event: 'guildMemberAdd' | 'guildMemberAvailable' | 'guildMemberRemove', listener: (member: GuildMember) => void): this; public once(event: 'guildMembersChunk', listener: (members: Collection, guild: Guild) => void): this; public once(event: 'guildMemberSpeaking', listener: (member: GuildMember, speaking: Readonly) => void): this; - public once(event: 'guildMemberUpdate' | 'presenceUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this; + public once(event: 'guildMemberUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this; public once(event: 'guildUpdate', listener: (oldGuild: Guild, newGuild: Guild) => void): this; public once(event: 'guildIntegrationsUpdate', listener: (guild: Guild) => void): this; public once(event: 'message' | 'messageDelete' | 'messageReactionRemoveAll', listener: (message: Message) => void): this; public once(event: 'messageDeleteBulk', listener: (messages: Collection) => void): this; public once(event: 'messageReactionAdd' | 'messageReactionRemove', listener: (messageReaction: MessageReaction, user: User) => void): this; public once(event: 'messageUpdate', listener: (oldMessage: Message, newMessage: Message) => void): this; + public once(event: 'presenceUpdate', listener: (oldPresence: Presence | undefined, newPresence: Presence) => void): this; public once(event: 'rateLimit', listener: (rateLimitData: RateLimitData) => void): this; public once(event: 'ready', listener: () => void): this; public once(event: 'resume', listener: (replayed: number, shardID: number) => void): this;