-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
ThreadMemberManager.js
155 lines (135 loc) · 4.97 KB
/
ThreadMemberManager.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
'use strict';
const { Collection } = require('@discordjs/collection');
const { Routes } = require('discord-api-types/v10');
const CachedManager = require('./CachedManager');
const { TypeError, ErrorCodes } = require('../errors');
const ThreadMember = require('../structures/ThreadMember');
/**
* Manages API methods for GuildMembers and stores their cache.
* @extends {CachedManager}
*/
class ThreadMemberManager extends CachedManager {
constructor(thread, iterable) {
super(thread.client, ThreadMember, iterable);
/**
* The thread this manager belongs to
* @type {ThreadChannel}
*/
this.thread = thread;
}
/**
* The cache of this Manager
* @type {Collection<Snowflake, ThreadMember>}
* @name ThreadMemberManager#cache
*/
_add(data, cache = true) {
const existing = this.cache.get(data.user_id);
if (cache) existing?._patch(data);
if (existing) return existing;
const member = new ThreadMember(this.thread, data);
if (cache) this.cache.set(data.user_id, member);
return member;
}
/**
* Fetches the client user as a ThreadMember of the thread.
* @param {BaseFetchOptions} [options] The options for fetching the member
* @returns {Promise<ThreadMember>}
*/
fetchMe(options) {
return this.fetch({ ...options, member: this.client.user.id });
}
/**
* The client user as a ThreadMember of this ThreadChannel
* @type {?ThreadMember}
* @readonly
*/
get me() {
return this.resolve(this.client.user.id);
}
/**
* Data that resolves to give a ThreadMember object. This can be:
* * A ThreadMember object
* * A User resolvable
* @typedef {ThreadMember|UserResolvable} ThreadMemberResolvable
*/
/**
* Resolves a {@link ThreadMemberResolvable} to a {@link ThreadMember} object.
* @param {ThreadMemberResolvable} member The user that is part of the thread
* @returns {?GuildMember}
*/
resolve(member) {
const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable;
const userResolvable = this.client.users.resolveId(member);
if (userResolvable) return super.resolve(userResolvable);
return null;
}
/**
* Resolves a {@link ThreadMemberResolvable} to a {@link ThreadMember} id string.
* @param {ThreadMemberResolvable} member The user that is part of the guild
* @returns {?Snowflake}
*/
resolveId(member) {
const memberResolvable = super.resolveId(member);
if (memberResolvable) return memberResolvable;
const userResolvable = this.client.users.resolveId(member);
return this.cache.has(userResolvable) ? userResolvable : null;
}
/**
* Adds a member to the thread.
* @param {UserResolvable|'@me'} member The member to add
* @param {string} [reason] The reason for adding this member
* @returns {Promise<Snowflake>}
*/
async add(member, reason) {
const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
await this.client.rest.put(Routes.threadMembers(this.thread.id, id), { reason });
return id;
}
/**
* Remove a user from the thread.
* @param {Snowflake|'@me'} id The id of the member to remove
* @param {string} [reason] The reason for removing this member from the thread
* @returns {Promise<Snowflake>}
*/
async remove(id, reason) {
await this.client.rest.delete(Routes.threadMembers(this.thread.id, id), { reason });
return id;
}
/**
* @typedef {BaseFetchOptions} FetchThreadMemberOptions
* @property {ThreadMemberResolvable} member The thread member to fetch
*/
/**
* @typedef {Object} FetchThreadMembersOptions
* @property {boolean} [cache] Whether to cache the fetched thread members
*/
/**
* Fetches thread member(s) from Discord.
* <info>This method requires the {@link GatewayIntentBits.GuildMembers} privileged gateway intent.</info>
* @param {ThreadMemberResolvable|FetchThreadMemberOptions|FetchThreadMembersOptions} [options]
* Options for fetching thread member(s)
* @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
*/
fetch(options) {
if (!options) return this._fetchMany();
const { member, cache, force } = options;
const resolvedMember = this.resolveId(member ?? options);
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, cache, force });
return this._fetchMany(options);
}
async _fetchSingle({ member, cache, force = false }) {
if (!force) {
const existing = this.cache.get(member);
if (existing) return existing;
}
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member));
return this._add(data, cache);
}
async _fetchMany(options = {}) {
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id));
return data.reduce((col, member) => col.set(member.user_id, this._add(member, options.cache)), new Collection());
}
}
module.exports = ThreadMemberManager;