From 54ef7a49fa247f72fc42f9b620ee8052d0e4d722 Mon Sep 17 00:00:00 2001 From: Bsian Date: Tue, 25 May 2021 14:00:47 +0100 Subject: [PATCH] Thread events (so far) --- index.d.ts | 7 ++++ lib/gateway/Shard.js | 90 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/index.d.ts b/index.d.ts index 48cbbd7bc..470e71c52 100644 --- a/index.d.ts +++ b/index.d.ts @@ -490,6 +490,11 @@ declare namespace Eris { permissions: Permission; position: number; } + interface OldThread { + name: string; + rateLimitPerUser: number; + threadMetadata: ThreadMetadata; + } interface OldVoiceState { deaf: boolean; mute: boolean; @@ -556,6 +561,8 @@ declare namespace Eris { event: "relationshipUpdate", listener: (relationship: Relationship, oldRelationship: { type: number }) => void ): T; + (event: "threadCreate" | "threadDelete", listener: (channel: AnyThreadChannel) => void): T; + (event: "threadUpdate", listener: (channel: AnyThreadChannel, oldChannel: OldThread) => void): T; (event: "typingStart", listener: (channel: GuildTextableChannel | Uncached, user: User | Uncached, member: Member) => void): T; (event: "typingStart", listener: (channel: PrivateChannel | Uncached, user: User | Uncached, member: null) => void): T; ( diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 99a641251..8aa4ecf43 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -14,6 +14,7 @@ const ExtendedUser = require("../structures/ExtendedUser"); const User = require("../structures/User"); const Invite = require("../structures/Invite"); const Constants = require("../Constants"); +const ThreadChannel = require("../structures/ThreadChannel"); const WebSocket = typeof window !== "undefined" ? require("../util/BrowserWebSocket") : require("ws"); @@ -2069,6 +2070,95 @@ class Shard extends EventEmitter { this.client.userGuildSettings[packet.d.guild_id] = packet.d; break; } + case "THREAD_CREATE": { + const channel = Channel.from(packet.d, this.client); + if(!channel.guild) { + channel.guild = this.client.guilds.get(packet.d.guild_id); + if(!channel.guild) { + this.emit("debug", `Received THREAD_CREATE for channel in missing guild ${packet.d.guild_id}`); + break; + } + } + channel.guild.threads.add(channel, this.client); + this.client.threadGuildMap[packet.d.id] = packet.d.guild_id; + /** + * Fired when a channel is created + * @event Client#threadCreate + * @prop {NewsThreadChannel | PrivateThreadChannel | PublicThreadChannel} channel The channel + */ + this.emit("threadCreate", channel); + break; + } + case "THREAD_UPDATE": { + const channel = this.client.getChannel(packet.d.id); + if(!channel) { + break; + } + if(!(channel instanceof ThreadChannel)) { + this.emit("warn", `Unexpected THREAD_UPDATE for channel ${packet.d.id} with type ${channel.type}`); + break; + } + const oldChannel = { + name: channel.name, + rateLimitPerUser: channel.rateLimitPerUser, + threadMetadata: channel.threadMetadata + }; + channel.update(packet.d); + + /** + * Fired when a thread channel is updated + * @event Client#threadUpdate + * @prop {NewsThreadChannel | PrivateThreadChannel | PublicThreadChannel} channel The updated channel + * @prop {Object} oldChannel + * @prop {String} oldChannel.name The name of the channel + * @prop {Number} oldChannel.rateLimitPerUser The ratelimit of the channel, in seconds. 0 means no ratelimit is enabled + * @prop {Object} oldChannel.threadMetadata Metadata for the thread + * @prop {Number} oldChannel.threadMetadata.archiveTimestamp Timestamp when the thread's archive status was last changed, used for calculating recent activity + * @prop {Boolean} oldChannel.threadMetadata.archived Whether the thread is archived + * @prop {String?} oldChannel.threadMetadata.archiverID The ID of the user that last (un)archived the thread + * @prop {Number} oldChannel.threadMetadata.autoArchiveDuration Duration in minutes to automatically archive the thread after recent activity, either 60, 1440, 4320 or 10080 + * @prop {Boolean?} oldChannel.threadMetadata.locked Whether the thread is locked + */ + this.emit("threadUpdate", channel, oldChannel); + break; + } + case "THREAD_DELETE": { + delete this.client.threadGuildMap[packet.d.id]; + const guild = this.client.guilds.get(packet.d.guild_id); + if(!guild) { + this.emit("debug", `Missing guild ${packet.d.guild_id} in THREAD_DELETE`); + break; + } + const channel = guild.threads.remove(packet.d); + if(!channel) { + break; + } + /** + * Fired when a thread channel is deleted + * @event Client#threadDelete + * @prop {NewsThreadChannel | PrivateThreadChannel | PublicThreadChannel} channel The channel + */ + this.emit("threadDelete", channel); + break; + } + case "THREAD_LIST_SYNC": { + // TODO Need to double check this + break; + } + case "THREAD_MEMBER_UPDATE": { + // TODO Need to sort out caching Thread Members + break; + } + case "THREAD_MEMBERS_UPDATE": { + const channel = this.cleint.getChannel(packet.d.id); + if(!channel) { + this.emit("debug", `Missing channel ${packet.d.id} in THREAD_MEMBERS_UPDATE`); + break; + } + channel.update(packet.d); + // TODO Other fields? + break; + } case "MESSAGE_ACK": // Ignore these case "GUILD_INTEGRATIONS_UPDATE": case "USER_SETTINGS_UPDATE":