Skip to content

Commit

Permalink
fix(ThreadChannel): better property handling (#6172)
Browse files Browse the repository at this point in the history
  • Loading branch information
ckohen committed Jul 28, 2021
1 parent 30a58dc commit 9679b90
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 33 deletions.
8 changes: 4 additions & 4 deletions src/managers/ChannelManager.js
Expand Up @@ -19,18 +19,18 @@ class ChannelManager extends CachedManager {
* @name ChannelManager#cache
*/

_add(data, guild, cache = true, allowUnknownGuild = false) {
_add(data, guild, { cache = true, allowUnknownGuild = false, fromInteraction = false } = {}) {
const existing = this.cache.get(data.id);
if (existing) {
if (cache) existing._patch(data);
if (cache) existing._patch(data, fromInteraction);
guild?.channels?._add(existing);
if (ThreadChannelTypes.includes(existing.type)) {
existing.parent?.threads?._add(existing);
}
return existing;
}

const channel = Channel.create(this.client, data, guild, allowUnknownGuild);
const channel = Channel.create(this.client, data, guild, { allowUnknownGuild, fromInteraction });

if (!channel) {
this.client.emit(Events.DEBUG, `Failed to find guild, or unknown type for channel ${data.id} ${data.type}`);
Expand Down Expand Up @@ -99,7 +99,7 @@ class ChannelManager extends CachedManager {
}

const data = await this.client.api.channels(id).get();
return this._add(data, null, cache, allowUnknownGuild);
return this._add(data, null, { cache, allowUnknownGuild });
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/managers/GuildChannelManager.js
Expand Up @@ -169,12 +169,12 @@ class GuildChannelManager extends CachedManager {
const data = await this.client.api.channels(id).get();
// Since this is the guild manager, throw if on a different guild
if (this.guild.id !== data.guild_id) throw new Error('GUILD_CHANNEL_UNOWNED');
return this.client.channels._add(data, this.guild, cache);
return this.client.channels._add(data, this.guild, { cache });
}

const data = await this.client.api.guilds(this.guild.id).channels.get();
const channels = new Collection();
for (const channel of data) channels.set(channel.id, this.client.channels._add(channel, this.guild, cache));
for (const channel of data) channels.set(channel.id, this.client.channels._add(channel, this.guild, { cache }));
return channels;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/managers/ThreadManager.js
Expand Up @@ -235,7 +235,7 @@ class ThreadManager extends CachedManager {

_mapThreads(rawThreads, cache) {
const threads = rawThreads.threads.reduce((coll, raw) => {
const thread = this.client.channels._add(raw, null, cache);
const thread = this.client.channels._add(raw, null, { cache });
return coll.set(thread.id, thread);
}, new Collection());
// Discord sends the thread id as id in this object
Expand Down
4 changes: 2 additions & 2 deletions src/structures/Channel.js
Expand Up @@ -126,7 +126,7 @@ class Channel extends Base {
return ThreadChannelTypes.includes(this.type);
}

static create(client, data, guild, allowUnknownGuild) {
static create(client, data, guild, { allowUnknownGuild, fromInteraction }) {
if (!CategoryChannel) CategoryChannel = require('./CategoryChannel');
if (!DMChannel) DMChannel = require('./DMChannel');
if (!NewsChannel) NewsChannel = require('./NewsChannel');
Expand Down Expand Up @@ -176,7 +176,7 @@ class Channel extends Base {
case ChannelTypes.GUILD_NEWS_THREAD:
case ChannelTypes.GUILD_PUBLIC_THREAD:
case ChannelTypes.GUILD_PRIVATE_THREAD: {
channel = new ThreadChannel(guild, data, client);
channel = new ThreadChannel(guild, data, client, fromInteraction);
if (!allowUnknownGuild) channel.parent?.threads.cache.set(channel.id, channel);
break;
}
Expand Down
4 changes: 3 additions & 1 deletion src/structures/CommandInteraction.js
Expand Up @@ -121,7 +121,9 @@ class CommandInteraction extends Interaction {
if (member) result.member = this.guild?.members._add({ user, ...member }) ?? member;

const channel = resolved.channels?.[option.value];
if (channel) result.channel = this.client.channels._add(channel, this.guild) ?? channel;
if (channel) {
result.channel = this.client.channels._add(channel, this.guild, { fromInteraction: true }) ?? channel;
}

const role = resolved.roles?.[option.value];
if (role) result.role = this.guild?.roles._add(role) ?? role;
Expand Down
2 changes: 1 addition & 1 deletion src/structures/Invite.js
Expand Up @@ -109,7 +109,7 @@ class Invite extends Base {
* The channel the invite is for
* @type {Channel}
*/
this.channel = this.client.channels._add(data.channel, this.guild, false);
this.channel = this.client.channels._add(data.channel, this.guild, { cache: false });

/**
* The timestamp the invite was created at
Expand Down
55 changes: 42 additions & 13 deletions src/structures/ThreadChannel.js
Expand Up @@ -16,8 +16,9 @@ class ThreadChannel extends Channel {
* @param {Guild} guild The guild the thread channel is part of
* @param {APIChannel} data The data for the thread channel
* @param {Client} [client] A safety parameter for the client that instantiated this
* @param {boolean} [fromInteraction=false] Whether the data was from an interaction (partial)
*/
constructor(guild, data, client) {
constructor(guild, data, client, fromInteraction = false) {
super(guild?.client ?? client, data, false);

/**
Expand All @@ -43,10 +44,10 @@ class ThreadChannel extends Channel {
* @type {ThreadMemberManager}
*/
this.members = new ThreadMemberManager(this);
if (data) this._patch(data);
if (data) this._patch(data, fromInteraction);
}

_patch(data) {
_patch(data, partial = false) {
super._patch(data);

/**
Expand All @@ -62,37 +63,52 @@ class ThreadChannel extends Channel {
if ('parent_id' in data) {
/**
* The id of the parent channel of this thread
* @type {Snowflake}
* @type {?Snowflake}
*/
this.parentId = data.parent_id;
} else if (!this.parentId) {
this.parentId = null;
}

if ('thread_metadata' in data) {
/**
* Whether the thread is locked
* @type {boolean}
* @type {?boolean}
*/
this.locked = data.thread_metadata.locked ?? false;

/**
* Whether the thread is archived
* @type {boolean}
* @type {?boolean}
*/
this.archived = data.thread_metadata.archived;

/**
* The amount of time (in minutes) after which the thread will automatically archive in case of no recent activity
* @type {number}
* @type {?number}
*/
this.autoArchiveDuration = data.thread_metadata.auto_archive_duration;

/**
* The timestamp when the thread's archive status was last changed
* <info>If the thread was never archived or unarchived, this is the timestamp at which the thread was
* created</info>
* @type {number}
* @type {?number}
*/
this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime();
} else {
if (!this.locked) {
this.locked = null;
}
if (!this.archived) {
this.archived = null;
}
if (!this.autoArchiveDuration) {
this.autoArchiveDuration = null;
}
if (!this.archiveTimestamp) {
this.archiveTimestamp = null;
}
}

if ('owner_id' in data) {
Expand All @@ -101,6 +117,8 @@ class ThreadChannel extends Channel {
* @type {?Snowflake}
*/
this.ownerId = data.owner_id;
} else if (!this.ownerId) {
this.ownerId = null;
}

if ('last_message_id' in data) {
Expand All @@ -109,6 +127,8 @@ class ThreadChannel extends Channel {
* @type {?Snowflake}
*/
this.lastMessageId = data.last_message_id;
} else if (!this.lastMessageId) {
this.lastMessageId = null;
}

if ('last_pin_timestamp' in data) {
Expand All @@ -117,34 +137,42 @@ class ThreadChannel extends Channel {
* @type {?number}
*/
this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null;
} else if (!this.lastPinTimestamp) {
this.lastPinTimestamp = null;
}

if ('rate_limit_per_user' in data) {
if ('rate_limit_per_user' in data || !partial) {
/**
* The ratelimit per user for this thread (in seconds)
* @type {number}
* @type {?number}
*/
this.rateLimitPerUser = data.rate_limit_per_user ?? 0;
} else if (!this.rateLimitPerUser) {
this.rateLimitPerUser = null;
}

if ('message_count' in data) {
/**
* The approximate count of messages in this thread
* <info>This stops counting at 50. If you need an approximate value higher than that, use
* `ThreadChannel#messages.cache.size`</info>
* @type {number}
* @type {?number}
*/
this.messageCount = data.message_count;
} else if (!this.messageCount) {
this.messageCount = null;
}

if ('member_count' in data) {
/**
* The approximate count of users in this thread
* <info>This stops counting at 50. If you need an approximate value higher than that, use
* `ThreadChannel#members.cache.size`</info>
* @type {number}
* @type {?number}
*/
this.memberCount = data.member_count;
} else if (!this.memberCount) {
this.memberCount = null;
}

if (data.member && this.client.user) this.members._add({ user_id: this.client.user.id, ...data.member });
Expand All @@ -163,10 +191,11 @@ class ThreadChannel extends Channel {
/**
* The time at which this thread's archive status was last changed
* <info>If the thread was never archived or unarchived, this is the time at which the thread was created</info>
* @type {Date}
* @type {?Date}
* @readonly
*/
get archivedAt() {
if (!this.archiveTimestamp) return null;
return new Date(this.archiveTimestamp);
}

Expand Down
18 changes: 9 additions & 9 deletions typings/index.d.ts
Expand Up @@ -1667,29 +1667,29 @@ export class TextChannel extends TextBasedChannel(GuildChannel) {
}

export class ThreadChannel extends TextBasedChannel(Channel) {
public constructor(guild: Guild, data?: object, client?: Client);
public archived: boolean;
public readonly archivedAt: Date;
public archiveTimestamp: number;
public autoArchiveDuration: ThreadAutoArchiveDuration;
public constructor(guild: Guild, data?: object, client?: Client, fromInteraction?: boolean);
public archived: boolean | null;
public readonly archivedAt: Date | null;
public archiveTimestamp: number | null;
public autoArchiveDuration: ThreadAutoArchiveDuration | null;
public readonly editable: boolean;
public guild: Guild;
public guildId: Snowflake;
public readonly guildMembers: Collection<Snowflake, GuildMember>;
public readonly joinable: boolean;
public readonly joined: boolean;
public locked: boolean;
public locked: boolean | null;
public readonly manageable: boolean;
public readonly sendable: boolean;
public memberCount: number | null;
public messageCount: number | null;
public messages: MessageManager;
public members: ThreadMemberManager;
public name: string;
public ownerId: Snowflake;
public ownerId: Snowflake | null;
public readonly parent: TextChannel | NewsChannel | null;
public parentId: Snowflake;
public rateLimitPerUser: number;
public parentId: Snowflake | null;
public rateLimitPerUser: number | null;
public type: ThreadChannelTypes;
public readonly unarchivable: boolean;
public delete(reason?: string): Promise<ThreadChannel>;
Expand Down

0 comments on commit 9679b90

Please sign in to comment.