diff --git a/src/client/ClientDataManager.js b/src/client/ClientDataManager.js index 5c2201810..ae5132947 100644 --- a/src/client/ClientDataManager.js +++ b/src/client/ClientDataManager.js @@ -69,6 +69,11 @@ class ClientDataManager { return null; } + newGuildMember(guild, data) { + if (guild.members.has(data.user.id)) return guild.members.get(data.user.id); + return guild._addMember(data); + } + killGuild(guild) { const already = this.client.guilds.has(guild.id); this.client.guilds.delete(guild.id); diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js index e70cdcbd8..f9addff29 100644 --- a/src/client/actions/ActionsManager.js +++ b/src/client/actions/ActionsManager.js @@ -11,6 +11,7 @@ class ActionsManager { this.register('ChannelUpdate'); this.register('GuildDelete'); this.register('GuildUpdate'); + this.register('GuildMemberGet'); this.register('GuildMemberRemove'); this.register('GuildBanRemove'); this.register('GuildRoleCreate'); diff --git a/src/client/actions/GuildMemberGet.js b/src/client/actions/GuildMemberGet.js new file mode 100644 index 000000000..256c80c05 --- /dev/null +++ b/src/client/actions/GuildMemberGet.js @@ -0,0 +1,13 @@ +const Action = require('./Action'); + +class GuildMemberGetAction extends Action { + handle(guild, data) { + const client = this.client; + const member = client.dataManager.newGuildMember(guild, data); + return { + member, + }; + } +} + +module.exports = GuildMemberGetAction; diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 8425e8acb..a465899c7 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -306,6 +306,14 @@ class RESTMethods { }); } + getGuildMember(guild, user) { + return new Promise((resolve, reject) => { + this.rest.makeRequest('get', Constants.Endpoints.guildMember(guild.id, user.id), true).then((data) => { + resolve(this.rest.client.actions.GuildMemberGet.handle(guild, data).member); + }).catch(reject); + }); + } + updateGuildMember(member, data) { return new Promise((resolve, reject) => { if (data.channel) data.channel_id = this.rest.client.resolver.resolveChannel(data.channel).id; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 7141983a4..72c8ca336 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -67,9 +67,7 @@ class Guild { } _addMember(guildUser, noEvent) { - if (!(guildUser.user instanceof User)) { - guildUser.user = this.client.dataManager.newUser(guildUser.user); - } + if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user); guildUser.joined_at = guildUser.joined_at || 0; const member = new GuildMember(this, guildUser); @@ -576,6 +574,18 @@ class Guild { return this.client.rest.methods.getGuildInvites(this); } + /** + * Fetch a single guild member from a user. + * @param {UserResolvable} user The user to fetch the member for + * @returns {Promise} + */ + fetchMember(user) { + user = this.client.resolver.resolveUser(user); + if (!user) return Promise.reject(new Error('user is not cached')); + if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id)); + return this.client.rest.methods.getGuildMember(this, user); + } + /** * Fetches all the members in the Guild, even if they are offline. If the Guild has less than 250 members, * this should not be necessary. @@ -584,9 +594,7 @@ class Guild { */ fetchMembers(query = '') { return new Promise((resolve, reject) => { - if (this._fetchWaiter) { - throw new Error('already fetching guild members'); - } + if (this._fetchWaiter) throw new Error('already fetching guild members'); if (this.memberCount === this.members.size) { resolve(this); return;