feat(GuildMemberStore): add options.withPresences to fetch() (#3562)

* feat: add options.withPresences to fetch()

feat: update presences if present on received data

typings: add user & withPresences to FetchMembersOptions

fix: checking for added options

ref: qol changes to return type

so that all members are fetched

oopsie

* fix: use Manager.cache

* fix(typings): tslint error

Co-authored-by: Crawl <icrawltogo@gmail.com>
This commit is contained in:
izexi
2020-02-29 13:18:37 +00:00
committed by GitHub
parent 2ee0f1cdc6
commit de4b4a0939
3 changed files with 32 additions and 9 deletions

View File

@@ -9,6 +9,9 @@ module.exports = (client, { d: data }) => {
const members = new Collection();
for (const member of data.members) members.set(member.user.id, guild.members.add(member));
if (data.presences) {
for (const presence of data.presences) guild.presences.cache.add(Object.assign(presence, { guild }));
}
/**
* Emitted whenever a chunk of guild members is received (all members come from the same guild).
* @event Client#guildMembersChunk

View File

@@ -72,8 +72,10 @@ class GuildMemberManager extends BaseManager {
/**
* Options used to fetch multiple members from a guild.
* @typedef {Object} FetchMembersOptions
* @property {string} [query=''] Limit fetch to members with similar usernames
* @property {UserResolvable|UserResolvable[]} user The user(s) to fetch
* @property {?string} query Limit fetch to members with similar usernames
* @property {number} [limit=0] Maximum number of members to request
* @property {boolean} [withPresences=false] Whether or not to include the presences
*/
/**
@@ -98,6 +100,11 @@ class GuildMemberManager extends BaseManager {
* .then(console.log)
* .catch(console.error);
* @example
* // Fetch by an array of users including their presences
* guild.members.fetch({ user: ['66564597481480192', '191615925336670208'], withPresences: true })
* .then(console.log)
* .catch(console.error);
* @example
* // Fetch by query
* guild.members.fetch({ query: 'hydra', limit: 1 })
* .then(console.log)
@@ -108,8 +115,13 @@ class GuildMemberManager extends BaseManager {
const user = this.client.users.resolveID(options);
if (user) return this._fetchSingle({ user, cache: true });
if (options.user) {
options.user = this.client.users.resolveID(options.user);
if (options.user) return this._fetchSingle(options);
if (Array.isArray(options.user)) {
options.user = options.user.map(u => this.client.users.resolveID(u));
return this._fetchMany(options);
} else {
options.user = this.client.users.resolveID(options.user);
}
if (!options.limit && !options.withPresences) return this._fetchSingle(options);
}
return this._fetchMany(options);
}
@@ -200,32 +212,38 @@ class GuildMemberManager extends BaseManager {
.then(data => this.add(data, cache));
}
_fetchMany({ query = '', limit = 0 } = {}) {
_fetchMany({ limit = 0, withPresences: presences = false, user: user_ids, query } = {}) {
return new Promise((resolve, reject) => {
if (this.guild.memberCount === this.cache.size && !query && !limit) {
if (this.guild.memberCount === this.cache.size && (!query && !limit && !presences && !user_ids)) {
resolve(this.cache);
return;
}
if (!query && !user_ids) query = '';
this.guild.shard.send({
op: OPCodes.REQUEST_GUILD_MEMBERS,
d: {
guild_id: this.guild.id,
presences,
user_ids,
query,
limit,
},
});
const fetchedMembers = new Collection();
const option = query || limit || presences || user_ids;
const handler = (members, guild) => {
if (guild.id !== this.guild.id) return;
timeout.refresh();
for (const member of members.values()) {
if (query || limit) fetchedMembers.set(member.id, member);
if (option) fetchedMembers.set(member.id, member);
}
if (this.guild.memberCount <= this.cache.size ||
((query || limit) && members.size < 1000) ||
(option && members.size < 1000) ||
(limit && fetchedMembers.size >= limit)) {
this.guild.client.removeListener(Events.GUILD_MEMBERS_CHUNK, handler);
resolve(query || limit ? fetchedMembers : this.cache);
let fetched = option ? fetchedMembers : this.cache;
if (user_ids && !Array.isArray(user_ids) && fetched.size) fetched = fetched.first();
resolve(fetched);
}
};
const timeout = this.guild.client.setTimeout(() => {

4
typings/index.d.ts vendored
View File

@@ -1784,7 +1784,7 @@ declare module 'discord.js' {
constructor(guild: Guild, iterable?: Iterable<any>);
public guild: Guild;
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
public fetch(options: UserResolvable | FetchMemberOptions): Promise<GuildMember>;
public fetch(options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable })): Promise<GuildMember>;
public fetch(options?: FetchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
public prune(options: GuildPruneMembersOptions & { dry?: false; count: false; }): Promise<null>;
public prune(options?: GuildPruneMembersOptions): Promise<number>;
@@ -2207,8 +2207,10 @@ declare module 'discord.js' {
}
interface FetchMembersOptions {
user?: UserResolvable | UserResolvable[];
query?: string;
limit?: number;
withPresences?: boolean;
}
interface FileOptions {