'use strict';
const ThreadManager = require('./ThreadManager');
const { TypeError } = require('../errors');
const { ChannelTypes } = require('../util/Constants');
const { resolveAutoArchiveMaxLimit } = require('../util/Util');
/**
* Manages API methods for {@link ThreadChannel} objects and stores their cache.
* @extends {ThreadManager}
*/
class GuildTextThreadManager extends ThreadManager {
/**
* The channel this Manager belongs to
* @name GuildTextThreadManager#channel
* @type {TextChannel|NewsChannel}
*/
/**
* Options for creating a thread. Only one of `startMessage` or `type` can be defined.
* @typedef {StartThreadOptions} GuildTextThreadCreateOptions
* @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 {ThreadChannelTypes|number} [type] The type of thread to create. Defaults to `GUILD_PUBLIC_THREAD` if
* created in a {@link TextChannel} When creating threads in a {@link NewsChannel} this is ignored and is always
* `GUILD_NEWS_THREAD`
* @property {boolean} [invitable] Whether non-moderators can add other non-moderators to the thread
* Can only be set when type will be `GUILD_PRIVATE_THREAD`
* @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the new channel in seconds
*/
/**
* Creates a new thread in the channel.
* @param {GuildTextThreadCreateOptions} [options] Options to create a new thread
* @returns {Promise}
* @example
* // Create a new public thread
* channel.threads
* .create({
* name: 'food-talk',
* autoArchiveDuration: 60,
* reason: 'Needed a separate thread for food',
* })
* .then(threadChannel => console.log(threadChannel))
* .catch(console.error);
* @example
* // Create a new private thread
* channel.threads
* .create({
* name: 'mod-talk',
* autoArchiveDuration: 60,
* type: 'GUILD_PRIVATE_THREAD',
* reason: 'Needed a separate thread for moderation',
* })
* .then(threadChannel => console.log(threadChannel))
* .catch(console.error);
*/
async create({
name,
autoArchiveDuration = this.channel.defaultAutoArchiveDuration,
startMessage,
type,
invitable,
reason,
rateLimitPerUser,
} = {}) {
let path = this.client.api.channels(this.channel.id);
if (type && typeof type !== 'string' && typeof type !== 'number') {
throw new TypeError('INVALID_TYPE', 'type', 'ThreadChannelType or Number');
}
let resolvedType =
this.channel.type === 'GUILD_NEWS' ? ChannelTypes.GUILD_NEWS_THREAD : ChannelTypes.GUILD_PUBLIC_THREAD;
if (startMessage) {
const startMessageId = this.channel.messages.resolveId(startMessage);
if (!startMessageId) throw new TypeError('INVALID_TYPE', 'startMessage', 'MessageResolvable');
path = path.messages(startMessageId);
} else if (this.channel.type !== 'GUILD_NEWS') {
resolvedType = typeof type === 'string' ? ChannelTypes[type] : type ?? resolvedType;
}
if (autoArchiveDuration === 'MAX') autoArchiveDuration = resolveAutoArchiveMaxLimit(this.channel.guild);
const data = await path.threads.post({
data: {
name,
auto_archive_duration: autoArchiveDuration,
type: resolvedType,
invitable: resolvedType === ChannelTypes.GUILD_PRIVATE_THREAD ? invitable : undefined,
rate_limit_per_user: rateLimitPerUser,
},
reason,
});
return this.client.actions.ThreadCreate.handle(data).thread;
}
}
module.exports = GuildTextThreadManager;