diff --git a/src/managers/ThreadManager.js b/src/managers/ThreadManager.js index 4f998c214..7587c9ba3 100644 --- a/src/managers/ThreadManager.js +++ b/src/managers/ThreadManager.js @@ -7,7 +7,7 @@ const Collection = require('../util/Collection'); const { ChannelTypes } = require('../util/Constants'); /** - * Manages API methods for ThreadChannels and stores their cache. + * Manages API methods for {@link ThreadChannel} objects and stores their cache. * @extends {BaseManager} */ class ThreadManager extends BaseManager { @@ -35,7 +35,7 @@ class ThreadManager extends BaseManager { } /** - * Data that can be resolved to give a Thread Channel object. This can be: + * Data that can be resolved to a Thread Channel object. This can be: * * A ThreadChannel object * * A Snowflake * @typedef {ThreadChannel|Snowflake} ThreadChannelResolvable @@ -60,7 +60,8 @@ class ThreadManager extends BaseManager { */ /** - * A number that is allowed to be the duration in minutes before a thread is automatically archived. This can be: + * A number that is allowed to be the duration (in minutes) of inactivity after which a thread is automatically + * archived. This can be: * * `60` (1 hour) * * `1440` (1 day) * * `4320` (3 days) This is only available when the guild has the `THREE_DAY_THREAD_ARCHIVE` feature. @@ -69,20 +70,22 @@ class ThreadManager extends BaseManager { */ /** - * Options for creating a thread Only one of `startMessage` or `type` can be defined. - * If `startMessage` is defined, `type` is automatically defined and cannot be changed. + * Options for creating a thread. Only one of `startMessage` or `type` can be defined. * @typedef {Object} ThreadCreateOptions - * @property {string} name The name of the new Thread - * @property {ThreadAutoArchiveDuration} autoArchiveDuration How long before the thread is automatically archived - * @property {MessageResolvable} [startMessage] The message to start a thread from - * @property {ThreadChannelType|number} [type='public_thread'] The type of thread to create - * When creating threads in a `news` channel this is ignored and is always `news_thread` + * @property {string} name The name of the new thread + * @property {ThreadAutoArchiveDuration} autoArchiveDuration The amount of time (in minutes) after which the thread + * should automatically archive in case of no recent activity + * @property {MessageResolvable} [startMessage] The message to start a thread from. If this is defined then type + * of thread gets automatically defined and cannot be changed. The provided `type` field will be ignored + * @property {ThreadChannelType|number} [type] The type of thread to create. Defaults to `public_thread` if created in + * a {@link TextChannel} When creating threads in a {@link NewsChannel} this is ignored and is always + * `news_thread` * @property {string} [reason] Reason for creating the thread */ /** * Creates a new thread in the channel. - * @param {ThreadCreateOptions} [options] Options + * @param {ThreadCreateOptions} [options] Options to create a new thread * @returns {Promise} * @example * // Create a new public thread @@ -92,7 +95,7 @@ class ThreadManager extends BaseManager { * autoArchiveDuration: 60, * reason: 'Needed a separate thread for food', * }) - * .then(console.log) + * .then(threadChannel => console.log(threadChannel)) * .catch(console.error); * @example * // Create a new private thread @@ -103,7 +106,7 @@ class ThreadManager extends BaseManager { * type: 'private_thread', * reason: 'Needed a separate thread for moderation', * }) - * .then(console.log) + * .then(threadChannel => console.log(threadChannel)) * .catch(console.error); */ async create({ name, autoArchiveDuration, startMessage, type, reason } = {}) { @@ -141,11 +144,10 @@ class ThreadManager extends BaseManager { /** * Obtains a thread from Discord, or the channel cache if it's already available. - * @param {ThreadChannelResolvable|FetchThreadsOptions} [options] If a ThreadChannelResolvable, the thread to fetch. - * If undefined, fetches all active threads. - * If an Object, fetches the specified threads. - * @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch - * only applies when fetching a single thread + * @param {ThreadChannelResolvable|FetchThreadsOptions} [options] The options to fetch threads. If it is a + * ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined` + * @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. The `force` field gets ignored + * if `options` is not a ThreadChannelResolvable * @returns {Promise} * @example * // Fetch a thread by its id @@ -164,10 +166,10 @@ class ThreadManager extends BaseManager { } /** - * Data that can be resolved to give a Date object. This can be: + * Data that can be resolved to a Date object. This can be: * * A Date object * * A number representing a timestamp - * * An ISO8601 string + * * An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) string * @typedef {Date|number|string} DateResolvable */ @@ -175,24 +177,23 @@ class ThreadManager extends BaseManager { * The options used to fetch archived threads. * @typedef {Object} FetchArchivedThreadOptions * @property {string} [type='public'] The type of threads to fetch, either `public` or `private` - * @property {boolean} [fetchAll=false] When type is `private` whether to fetch **all** archived threads, - * requires `MANAGE_THREADS` if true - * @property {DateResolvable|ThreadChannelResolvable} [before] Identifier for a Date or Snowflake - * to get threads that were created before it, - * must be a ThreadChannelResolvable when type is `private` and fetchAll is `false` + * @property {boolean} [fetchAll=false] Whether to fetch **all** archived threads when type is `private`. + * Requires `MANAGE_THREADS` if true + * @property {DateResolvable|ThreadChannelResolvable} [before] Only return threads that were created before this Date + * or Snowflake. Must be a {@link ThreadChannelResolvable} when type is `private` and fetchAll is `false` * @property {number} [limit] Maximum number of threads to return */ /** * The data returned from a thread fetch that returns multiple threads. * @typedef {Object} FetchedThreads - * @property {Collection} threads The threads fetched, with any members returned + * @property {Collection} threads The threads that were fetched, with any members returned * @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call */ /** * Obtains a set of archived threads from Discord, requires `READ_MESSAGE_HISTORY` in the parent channel. - * @param {FetchArchivedThreadOptions} [options] The options to use when fetch archived threads + * @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads * @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already * @returns {Promise} */ diff --git a/src/structures/ThreadChannel.js b/src/structures/ThreadChannel.js index 02d29109a..9ad2c7aab 100644 --- a/src/structures/ThreadChannel.js +++ b/src/structures/ThreadChannel.js @@ -26,7 +26,7 @@ class ThreadChannel extends Channel { this.guild = guild; /** - * A manager of the messages set to this thread + * A manager of the messages sent to this thread * @type {MessageManager} */ this.messages = new MessageManager(this); @@ -52,7 +52,7 @@ class ThreadChannel extends Channel { if ('parent_id' in data) { /** - * The ID of the parent channel to this thread + * The ID of the parent channel of this thread * @type {Snowflake} */ this.parentID = data.parent_id; @@ -66,20 +66,21 @@ class ThreadChannel extends Channel { this.locked = data.thread_metadata.locked ?? false; /** - * Whether the thread is active (false) or archived (true) + * Whether the thread is archived * @type {boolean} */ this.archived = data.thread_metadata.archived; /** - * How long in minutes after recent activity before the thread is automatically archived + * The amount of time (in minutes) after which the thread will automatically archive in case of no recent activity * @type {number} */ this.autoArchiveDuration = data.thread_metadata.auto_archive_duration; /** * The timestamp when the thread's archive status was last changed - * If the thread was never archived or unarchived, this is set when it's created + * If the thread was never archived or unarchived, this is the timestamp at which the thread was + * created * @type {number} */ this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime(); @@ -87,7 +88,7 @@ class ThreadChannel extends Channel { if ('owner_id' in data) { /** - * The id of the member that created this thread + * The id of the member who created this thread * @type {?Snowflake} */ this.ownerID = data.owner_id; @@ -111,7 +112,7 @@ class ThreadChannel extends Channel { if ('rate_limit_per_user' in data) { /** - * The ratelimit per user for this thread in seconds + * The ratelimit per user for this thread (in seconds) * @type {number} */ this.rateLimitPerUser = data.rate_limit_per_user ?? 0; @@ -120,8 +121,8 @@ class ThreadChannel extends Channel { if ('message_count' in data) { /** * The approximate count of messages in this thread - * This value will not count above 50 even when there are more than 50 messages - * If you need an approximate value higher than this, use ThreadChannel#messages.cache.size + * This stops counting at 50. If you need an approximate value higher than that, use + * `ThreadChannel#messages.cache.size` * @type {number} */ this.messageCount = data.message_count; @@ -130,7 +131,8 @@ class ThreadChannel extends Channel { if ('member_count' in data) { /** * The approximate count of users in this thread - * This value will not count above 50 even when there are more than 50 members + * This stops counting at 50. If you need an approximate value higher than that, use + * `ThreadChannel#members.cache.size` * @type {number} */ this.memberCount = data.member_count; @@ -141,7 +143,7 @@ class ThreadChannel extends Channel { } /** - * A collection of the guild member objects for each of this thread's members + * A collection of associated guild member objects of this thread's members * @type {Collection} * @readonly */ @@ -150,8 +152,8 @@ class ThreadChannel extends Channel { } /** - * The time when the thread's archive status was last changed - * If the thread was never archived or unarchived, this is set when it's created + * The time at which this thread's archive status was last changed + * If the thread was never archived or unarchived, this is the time at which the thread was created * @type {Date} * @readonly */ @@ -185,7 +187,8 @@ class ThreadChannel extends Channel { } /** - * Gets the overall set of permissions for a member or role in this threads' parent, taking into account overwrites. + * Gets the overall set of permissions for a member or role in this thread's parent channel, taking overwrites into + * account. * @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for * @returns {?Readonly} */ @@ -194,20 +197,25 @@ class ThreadChannel extends Channel { } /** - * Edits the thread. - * @param {APIChannel} data The new data for the thread - * @param {string} [data.name] The new name for the trhead - * @param {boolean} [data.archived] Whether the thread is archived - * @param {number} [data.autoArchiveDuration] How long in minutes before the thread is automatically archived, - * one of `60`, `1440`, `4320`, or `10080` - * @param {number} [data.rateLimitPerUser] The ratelimit per user for the thread in seconds - * @param {boolean} [data.locked] Whether the thread is locked + * The options used to edit a thread channel + * @typedef {Object} ThreadEditData + * @property {string} [name] The new name for the thread + * @property {boolean} [archived] Whether the thread is archived + * @property {ThreadAutoArchiveDuration} [autoArchiveDuration] The amount of time (in minutes) after which the thread + * should automatically archive in case of no recent activity + * @property {number} [rateLimitPerUser] The ratelimit per user for the thread in seconds + * @property {boolean} [locked] Whether the thread is locked + */ + + /** + * Edits this thread. + * @param {ThreadEditData} data The new data for this thread * @param {string} [reason] Reason for editing this thread * @returns {Promise} * @example * // Edit a thread * thread.edit({ name: 'new-thread' }) - * .then(console.log) + * .then(editedThread => console.log(editedThread)) * .catch(console.error); */ async edit(data, reason) { @@ -231,7 +239,7 @@ class ThreadChannel extends Channel { * @param {string} [reason] Reason for archiving or unarchiving * @returns {Promise} * @example - * // Set the thread to archived + * // Archive the thread * thread.setArchived(true) * .then(newThread => console.log(`Thread is now ${newThread.archived ? 'archived' : 'active'}`)) * .catch(console.error); @@ -241,15 +249,16 @@ class ThreadChannel extends Channel { } /** - * Sets the duration before the channel is automatically archived. - * @param {ThreadAutoArchiveDuration} autoArchiveDuration How long before the thread is automatically archived - * @param {string} [reason] Reason for changing the archive time + * Sets the duration after which the thread will automatically archive in case of no recent activity. + * @param {ThreadAutoArchiveDuration} autoArchiveDuration The amount of time (in minutes) after which the thread + * should automatically archive in case of no recent activity + * @param {string} [reason] Reason for changing the auto archive duration * @returns {Promise} * @example - * // Set the thread auto archive time to 1 hour + * // Set the thread's auto archive time to 1 hour * thread.setAutoArchiveDuration(60) * .then(newThread => { - * console.log(`Thread will now archive after ${newThread.autoArchiveDuration}`); + * console.log(`Thread will now archive after ${newThread.autoArchiveDuration} minutes of inactivity`); * }); * .catch(console.error); */ @@ -273,12 +282,12 @@ class ThreadChannel extends Channel { } /** - * Sets a new name for the thread. + * Sets a new name for this thread. * @param {string} name The new name for the thread * @param {string} [reason] Reason for changing the thread's name * @returns {Promise} * @example - * // Set a new thread name + * // Change the thread's name * thread.setName('not_general') * .then(newThread => console.log(`Thread's new name is ${newThread.name}`)) * .catch(console.error); @@ -375,7 +384,7 @@ class ThreadChannel extends Channel { * @example * // Delete the thread * thread.delete('cleaning out old threads') - * .then(console.log) + * .then(deletedThread => console.log(deletedThread)) * .catch(console.error); */ delete(reason) { diff --git a/src/structures/ThreadMember.js b/src/structures/ThreadMember.js index e25795947..526334455 100644 --- a/src/structures/ThreadMember.js +++ b/src/structures/ThreadMember.js @@ -47,7 +47,7 @@ class ThreadMember extends Base { } /** - * The guild member that this thread member instance represents + * The guild member associated with this thread member * @type {?GuildMember} * @readonly */ @@ -65,7 +65,7 @@ class ThreadMember extends Base { } /** - * The user that this thread member instance represents + * The user associated with this thread member * @type {?User} * @readonly */ @@ -83,7 +83,7 @@ class ThreadMember extends Base { } /** - * Remove this member from the thread. + * Removes this member from the thread. * @param {string} [reason] Reason for removing the member * @returns {ThreadMember} */ diff --git a/typings/index.d.ts b/typings/index.d.ts index 28f9a871c..423be4069 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1582,7 +1582,7 @@ declare module 'discord.js' { public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration; public messages: MessageManager; public nsfw: boolean; - public threads: ThreadManager; + public threads: ThreadManager; public topic: string | null; public type: 'news'; public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise; @@ -1936,7 +1936,7 @@ declare module 'discord.js' { public nsfw: boolean; public type: 'text'; public rateLimitPerUser: number; - public threads: ThreadManager; + public threads: ThreadManager; public topic: string | null; public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise; public setDefaultAutoArchiveDuration( @@ -2655,21 +2655,12 @@ declare module 'discord.js' { public delete(channel: StageChannel | Snowflake): Promise; } - export class ThreadManager extends BaseManager { + export class ThreadManager extends BaseManager { constructor(channel: TextChannel | NewsChannel, iterable?: Iterable); public channel: TextChannel | NewsChannel; - public create(options: { - name: string; - autoArchiveDuration: ThreadAutoArchiveDuration; - startMessage?: MessageResolvable; - type?: ThreadChannelType | number; - reason?: string; - }): Promise; + public create(options: ThreadCreateOptions): Promise; public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise; - public fetch( - options?: { archived?: FetchArchivedThreadOptions; active?: boolean }, - cacheOptions?: { cache?: boolean }, - ): Promise; + public fetch(options?: FetchThreadsOptions, cacheOptions?: { cache?: boolean }): Promise; public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise; public fetchActive(cache?: boolean): Promise; } @@ -2790,6 +2781,10 @@ declare module 'discord.js' { deaf?: boolean; } + type AllowedThreadTypeForNewsChannel = 'news_thread' | 10; + + type AllowedThreadTypeForTextChannel = 'public_thread' | 'private_thread' | 11 | 12; + interface APIErrors { UNKNOWN_ACCOUNT: 10001; UNKNOWN_APPLICATION: 10002; @@ -3387,6 +3382,11 @@ declare module 'discord.js' { after?: Snowflake; } + interface FetchThreadsOptions { + archived?: FetchArchivedThreadOptions; + active?: boolean; + } + interface FileOptions { attachment: BufferResolvable | Stream; name?: string; @@ -4349,6 +4349,14 @@ declare module 'discord.js' { type ThreadChannelType = 'news_thread' | 'public_thread' | 'private_thread'; + interface ThreadCreateOptions { + name: string; + autoArchiveDuration: ThreadAutoArchiveDuration; + startMessage?: MessageResolvable; + type?: AllowedThreadType; + reason?: string; + } + interface ThreadEditData { name?: string; archived?: boolean;