mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 08:33:30 +01:00
refactor: remove typing caching (#6114)
Co-authored-by: DTrombett <73136330+DTrombett@users.noreply.github.com>
This commit is contained in:
@@ -8,11 +8,6 @@ const DataResolver = require('../util/DataResolver');
|
||||
* @extends {User}
|
||||
*/
|
||||
class ClientUser extends User {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
this._typing = new Map();
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
super._patch(data);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ class DMChannel extends Channel {
|
||||
* @type {MessageManager}
|
||||
*/
|
||||
this.messages = new MessageManager(this);
|
||||
this._typing = new Map();
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
@@ -87,10 +86,7 @@ class DMChannel extends Channel {
|
||||
get lastMessage() {}
|
||||
get lastPinAt() {}
|
||||
send() {}
|
||||
startTyping() {}
|
||||
stopTyping() {}
|
||||
get typing() {}
|
||||
get typingCount() {}
|
||||
sendTyping() {}
|
||||
createMessageCollector() {}
|
||||
awaitMessages() {}
|
||||
createMessageComponentCollector() {}
|
||||
|
||||
@@ -38,7 +38,6 @@ class TextChannel extends GuildChannel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.nsfw = Boolean(data.nsfw);
|
||||
this._typing = new Map();
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
@@ -193,10 +192,7 @@ class TextChannel extends GuildChannel {
|
||||
get lastMessage() {}
|
||||
get lastPinAt() {}
|
||||
send() {}
|
||||
startTyping() {}
|
||||
stopTyping() {}
|
||||
get typing() {}
|
||||
get typingCount() {}
|
||||
sendTyping() {}
|
||||
createMessageCollector() {}
|
||||
awaitMessages() {}
|
||||
createMessageComponentCollector() {}
|
||||
|
||||
@@ -43,8 +43,6 @@ class ThreadChannel extends Channel {
|
||||
* @type {ThreadMemberManager}
|
||||
*/
|
||||
this.members = new ThreadMemberManager(this);
|
||||
|
||||
this._typing = new Map();
|
||||
if (data) this._patch(data);
|
||||
}
|
||||
|
||||
@@ -413,10 +411,7 @@ class ThreadChannel extends Channel {
|
||||
get lastMessage() {}
|
||||
get lastPinAt() {}
|
||||
send() {}
|
||||
startTyping() {}
|
||||
stopTyping() {}
|
||||
get typing() {}
|
||||
get typingCount() {}
|
||||
sendTyping() {}
|
||||
createMessageCollector() {}
|
||||
awaitMessages() {}
|
||||
createMessageComponentCollector() {}
|
||||
|
||||
82
src/structures/Typing.js
Normal file
82
src/structures/Typing.js
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
const Base = require('./Base');
|
||||
|
||||
/**
|
||||
* Represents a typing state for a user in a channel.
|
||||
* @extends {Base}
|
||||
*/
|
||||
class Typing extends Base {
|
||||
/**
|
||||
* @param {TextChannel|DMChannel|NewsChannel|ThreadChannel} channel The channel this typing came from
|
||||
* @param {User} user The user that started typing
|
||||
* @param {APITypingStart} data The raw data received
|
||||
*/
|
||||
constructor(channel, user, data) {
|
||||
super(channel.client);
|
||||
|
||||
/**
|
||||
* The channel the status is from
|
||||
* @type {TextChannel|DMChannel|NewsChannel|ThreadChannel}
|
||||
*/
|
||||
this.channel = channel;
|
||||
|
||||
/**
|
||||
* The user who is typing
|
||||
* @type {User}
|
||||
*/
|
||||
this.user = user;
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
/**
|
||||
* The UNIX timestamp in milliseconds the user started typing at
|
||||
* @type {number}
|
||||
*/
|
||||
this.startedTimestamp = data.timestamp * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the status is received from a guild.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
inGuild() {
|
||||
return this.guild !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The time the user started typing at
|
||||
* @type {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get startedAt() {
|
||||
return new Date(this.startedTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* The guild the status is from
|
||||
* @type {?Guild}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.channel.guild ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The member who is typing
|
||||
* @type {?GuildMember}
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
return this.guild?.members.resolve(this.user) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Typing;
|
||||
|
||||
/**
|
||||
* @external APITypingStart
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#typing-start-typing-start-event-fields}
|
||||
*/
|
||||
@@ -159,34 +159,6 @@ class User extends Base {
|
||||
return typeof this.username === 'string' ? `${this.username}#${this.discriminator}` : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the user is typing in a channel.
|
||||
* @param {ChannelResolvable} channel The channel to check in
|
||||
* @returns {boolean}
|
||||
*/
|
||||
typingIn(channel) {
|
||||
return this.client.channels.resolve(channel)._typing.has(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time that the user started typing.
|
||||
* @param {ChannelResolvable} channel The channel to get the time in
|
||||
* @returns {?Date}
|
||||
*/
|
||||
typingSinceIn(channel) {
|
||||
channel = this.client.channels.resolve(channel);
|
||||
return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of time the user has been typing in a channel for (in milliseconds), or -1 if they're not typing.
|
||||
* @param {ChannelResolvable} channel The channel to get the time in
|
||||
* @returns {number}
|
||||
*/
|
||||
typingDurationIn(channel) {
|
||||
return this.client.channels.resolve(channel)._typing.get(this.id)?.elapsedTime ?? -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The DM between the client's user and this user
|
||||
* @type {?DMChannel}
|
||||
|
||||
@@ -6,7 +6,7 @@ const MessagePayload = require('../MessagePayload');
|
||||
const SnowflakeUtil = require('../../util/SnowflakeUtil');
|
||||
const Collection = require('../../util/Collection');
|
||||
const { InteractionTypes } = require('../../util/Constants');
|
||||
const { RangeError, TypeError, Error } = require('../../errors');
|
||||
const { TypeError, Error } = require('../../errors');
|
||||
const InteractionCollector = require('../InteractionCollector');
|
||||
|
||||
/**
|
||||
@@ -172,88 +172,14 @@ class TextBasedChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a typing indicator in the channel.
|
||||
* @param {number} [count=1] The number of times startTyping should be considered to have been called
|
||||
* @returns {Promise} Resolves once the bot stops typing gracefully, or rejects when an error occurs
|
||||
* Sends a typing indicator in the channel.
|
||||
* @returns {Promise<void>} Resolves upon the typing status being sent
|
||||
* @example
|
||||
* // Start typing in a channel, or increase the typing count by one
|
||||
* channel.startTyping();
|
||||
* @example
|
||||
* // Start typing in a channel with a typing count of five, or set it to five
|
||||
* channel.startTyping(5);
|
||||
* // Start typing in a channel
|
||||
* channel.sendTyping();
|
||||
*/
|
||||
startTyping(count) {
|
||||
if (typeof count !== 'undefined' && count < 1) throw new RangeError('TYPING_COUNT');
|
||||
if (this.client.user._typing.has(this.id)) {
|
||||
const entry = this.client.user._typing.get(this.id);
|
||||
entry.count = count ?? entry.count + 1;
|
||||
return entry.promise;
|
||||
}
|
||||
|
||||
const entry = {};
|
||||
entry.promise = new Promise((resolve, reject) => {
|
||||
const endpoint = this.client.api.channels[this.id].typing;
|
||||
Object.assign(entry, {
|
||||
count: count ?? 1,
|
||||
interval: this.client.setInterval(() => {
|
||||
endpoint.post().catch(error => {
|
||||
this.client.clearInterval(entry.interval);
|
||||
this.client.user._typing.delete(this.id);
|
||||
reject(error);
|
||||
});
|
||||
}, 9000),
|
||||
resolve,
|
||||
});
|
||||
endpoint.post().catch(error => {
|
||||
this.client.clearInterval(entry.interval);
|
||||
this.client.user._typing.delete(this.id);
|
||||
reject(error);
|
||||
});
|
||||
this.client.user._typing.set(this.id, entry);
|
||||
});
|
||||
return entry.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the typing indicator in the channel.
|
||||
* The indicator will only stop if this is called as many times as startTyping().
|
||||
* <info>It can take a few seconds for the client user to stop typing.</info>
|
||||
* @param {boolean} [force=false] Whether or not to reset the call count and force the indicator to stop
|
||||
* @example
|
||||
* // Reduce the typing count by one and stop typing if it reached 0
|
||||
* channel.stopTyping();
|
||||
* @example
|
||||
* // Force typing to fully stop regardless of typing count
|
||||
* channel.stopTyping(true);
|
||||
*/
|
||||
stopTyping(force = false) {
|
||||
if (this.client.user._typing.has(this.id)) {
|
||||
const entry = this.client.user._typing.get(this.id);
|
||||
entry.count--;
|
||||
if (entry.count <= 0 || force) {
|
||||
this.client.clearInterval(entry.interval);
|
||||
this.client.user._typing.delete(this.id);
|
||||
entry.resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the typing indicator is being shown in the channel
|
||||
* @type {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get typing() {
|
||||
return this.client.user._typing.has(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of times `startTyping` has been called
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
get typingCount() {
|
||||
return this.client.user._typing.get(this.id)?.count ?? 0;
|
||||
async sendTyping() {
|
||||
await this.client.api.channels(this.id).typing.post();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,10 +330,7 @@ class TextBasedChannel {
|
||||
'lastMessage',
|
||||
'lastPinAt',
|
||||
'bulkDelete',
|
||||
'startTyping',
|
||||
'stopTyping',
|
||||
'typing',
|
||||
'typingCount',
|
||||
'sendTyping',
|
||||
'createMessageCollector',
|
||||
'awaitMessages',
|
||||
'createMessageComponentCollector',
|
||||
|
||||
Reference in New Issue
Block a user