mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +01:00
refactor: remove typing caching (#6114)
Co-authored-by: DTrombett <73136330+DTrombett@users.noreply.github.com>
This commit is contained in:
@@ -15,8 +15,6 @@ class ChannelUpdateAction extends Action {
|
|||||||
if (ChannelTypes[channel.type] !== data.type) {
|
if (ChannelTypes[channel.type] !== data.type) {
|
||||||
const newChannel = Channel.create(this.client, data, channel.guild);
|
const newChannel = Channel.create(this.client, data, channel.guild);
|
||||||
for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message);
|
for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message);
|
||||||
newChannel._typing = new Map(channel._typing);
|
|
||||||
channel = newChannel;
|
|
||||||
this.client.channels.cache.set(channel.id, channel);
|
this.client.channels.cache.set(channel.id, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Action = require('./Action');
|
const Action = require('./Action');
|
||||||
const { Events, TextBasedChannelTypes } = require('../../util/Constants');
|
const { Events } = require('../../util/Constants');
|
||||||
|
|
||||||
class GuildDeleteAction extends Action {
|
class GuildDeleteAction extends Action {
|
||||||
constructor(client) {
|
constructor(client) {
|
||||||
@@ -14,10 +14,6 @@ class GuildDeleteAction extends Action {
|
|||||||
|
|
||||||
let guild = client.guilds.cache.get(data.id);
|
let guild = client.guilds.cache.get(data.id);
|
||||||
if (guild) {
|
if (guild) {
|
||||||
for (const channel of guild.channels.cache.values()) {
|
|
||||||
if (TextBasedChannelTypes.includes(channel.type)) channel.stopTyping(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.unavailable) {
|
if (data.unavailable) {
|
||||||
// Guild is unavailable
|
// Guild is unavailable
|
||||||
guild.available = false;
|
guild.available = false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Action = require('./Action');
|
const Action = require('./Action');
|
||||||
|
const Typing = require('../../structures/Typing');
|
||||||
const { Events, TextBasedChannelTypes } = require('../../util/Constants');
|
const { Events, TextBasedChannelTypes } = require('../../util/Constants');
|
||||||
|
|
||||||
class TypingStart extends Action {
|
class TypingStart extends Action {
|
||||||
@@ -15,43 +16,15 @@ class TypingStart extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const user = this.getUserFromMember(data);
|
const user = this.getUserFromMember(data);
|
||||||
const timestamp = new Date(data.timestamp * 1000);
|
|
||||||
|
|
||||||
if (channel && user) {
|
if (channel && user) {
|
||||||
if (channel._typing.has(user.id)) {
|
/**
|
||||||
const typing = channel._typing.get(user.id);
|
* Emitted whenever a user starts typing in a channel.
|
||||||
|
* @event Client#typingStart
|
||||||
typing.lastTimestamp = timestamp;
|
* @param {Typing} typing The typing state
|
||||||
typing.elapsedTime = Date.now() - typing.since;
|
*/
|
||||||
this.client.clearTimeout(typing.timeout);
|
this.client.emit(Events.TYPING_START, new Typing(channel, user, data));
|
||||||
typing.timeout = this.tooLate(channel, user);
|
|
||||||
} else {
|
|
||||||
const since = new Date();
|
|
||||||
const lastTimestamp = new Date();
|
|
||||||
channel._typing.set(user.id, {
|
|
||||||
user,
|
|
||||||
since,
|
|
||||||
lastTimestamp,
|
|
||||||
elapsedTime: Date.now() - since,
|
|
||||||
timeout: this.tooLate(channel, user),
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted whenever a user starts typing in a channel.
|
|
||||||
* @event Client#typingStart
|
|
||||||
* @param {DMChannel|TextChannel|NewsChannel} channel The channel the user started typing in
|
|
||||||
* @param {User} user The user that started typing
|
|
||||||
*/
|
|
||||||
this.client.emit(Events.TYPING_START, channel, user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tooLate(channel, user) {
|
|
||||||
return channel.client.setTimeout(() => {
|
|
||||||
channel._typing.delete(user.id);
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TypingStart;
|
module.exports = TypingStart;
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ const Messages = {
|
|||||||
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
||||||
MESSAGE_CONTENT_TYPE: 'Message content must be a non-empty string.',
|
MESSAGE_CONTENT_TYPE: 'Message content must be a non-empty string.',
|
||||||
|
|
||||||
TYPING_COUNT: 'Count must be at least 1',
|
|
||||||
|
|
||||||
SPLIT_MAX_LEN: 'Chunk exceeds the max length and contains no split characters.',
|
SPLIT_MAX_LEN: 'Chunk exceeds the max length and contains no split characters.',
|
||||||
|
|
||||||
BAN_RESOLVE_ID: (ban = false) => `Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
BAN_RESOLVE_ID: (ban = false) => `Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ const DataResolver = require('../util/DataResolver');
|
|||||||
* @extends {User}
|
* @extends {User}
|
||||||
*/
|
*/
|
||||||
class ClientUser extends User {
|
class ClientUser extends User {
|
||||||
constructor(client, data) {
|
|
||||||
super(client, data);
|
|
||||||
this._typing = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
_patch(data) {
|
_patch(data) {
|
||||||
super._patch(data);
|
super._patch(data);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class DMChannel extends Channel {
|
|||||||
* @type {MessageManager}
|
* @type {MessageManager}
|
||||||
*/
|
*/
|
||||||
this.messages = new MessageManager(this);
|
this.messages = new MessageManager(this);
|
||||||
this._typing = new Map();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_patch(data) {
|
_patch(data) {
|
||||||
@@ -87,10 +86,7 @@ class DMChannel extends Channel {
|
|||||||
get lastMessage() {}
|
get lastMessage() {}
|
||||||
get lastPinAt() {}
|
get lastPinAt() {}
|
||||||
send() {}
|
send() {}
|
||||||
startTyping() {}
|
sendTyping() {}
|
||||||
stopTyping() {}
|
|
||||||
get typing() {}
|
|
||||||
get typingCount() {}
|
|
||||||
createMessageCollector() {}
|
createMessageCollector() {}
|
||||||
awaitMessages() {}
|
awaitMessages() {}
|
||||||
createMessageComponentCollector() {}
|
createMessageComponentCollector() {}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class TextChannel extends GuildChannel {
|
|||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
this.nsfw = Boolean(data.nsfw);
|
this.nsfw = Boolean(data.nsfw);
|
||||||
this._typing = new Map();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_patch(data) {
|
_patch(data) {
|
||||||
@@ -193,10 +192,7 @@ class TextChannel extends GuildChannel {
|
|||||||
get lastMessage() {}
|
get lastMessage() {}
|
||||||
get lastPinAt() {}
|
get lastPinAt() {}
|
||||||
send() {}
|
send() {}
|
||||||
startTyping() {}
|
sendTyping() {}
|
||||||
stopTyping() {}
|
|
||||||
get typing() {}
|
|
||||||
get typingCount() {}
|
|
||||||
createMessageCollector() {}
|
createMessageCollector() {}
|
||||||
awaitMessages() {}
|
awaitMessages() {}
|
||||||
createMessageComponentCollector() {}
|
createMessageComponentCollector() {}
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ class ThreadChannel extends Channel {
|
|||||||
* @type {ThreadMemberManager}
|
* @type {ThreadMemberManager}
|
||||||
*/
|
*/
|
||||||
this.members = new ThreadMemberManager(this);
|
this.members = new ThreadMemberManager(this);
|
||||||
|
|
||||||
this._typing = new Map();
|
|
||||||
if (data) this._patch(data);
|
if (data) this._patch(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,10 +411,7 @@ class ThreadChannel extends Channel {
|
|||||||
get lastMessage() {}
|
get lastMessage() {}
|
||||||
get lastPinAt() {}
|
get lastPinAt() {}
|
||||||
send() {}
|
send() {}
|
||||||
startTyping() {}
|
sendTyping() {}
|
||||||
stopTyping() {}
|
|
||||||
get typing() {}
|
|
||||||
get typingCount() {}
|
|
||||||
createMessageCollector() {}
|
createMessageCollector() {}
|
||||||
awaitMessages() {}
|
awaitMessages() {}
|
||||||
createMessageComponentCollector() {}
|
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;
|
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
|
* The DM between the client's user and this user
|
||||||
* @type {?DMChannel}
|
* @type {?DMChannel}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const MessagePayload = require('../MessagePayload');
|
|||||||
const SnowflakeUtil = require('../../util/SnowflakeUtil');
|
const SnowflakeUtil = require('../../util/SnowflakeUtil');
|
||||||
const Collection = require('../../util/Collection');
|
const Collection = require('../../util/Collection');
|
||||||
const { InteractionTypes } = require('../../util/Constants');
|
const { InteractionTypes } = require('../../util/Constants');
|
||||||
const { RangeError, TypeError, Error } = require('../../errors');
|
const { TypeError, Error } = require('../../errors');
|
||||||
const InteractionCollector = require('../InteractionCollector');
|
const InteractionCollector = require('../InteractionCollector');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,88 +172,14 @@ class TextBasedChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a typing indicator in the channel.
|
* Sends a typing indicator in the channel.
|
||||||
* @param {number} [count=1] The number of times startTyping should be considered to have been called
|
* @returns {Promise<void>} Resolves upon the typing status being sent
|
||||||
* @returns {Promise} Resolves once the bot stops typing gracefully, or rejects when an error occurs
|
|
||||||
* @example
|
* @example
|
||||||
* // Start typing in a channel, or increase the typing count by one
|
* // Start typing in a channel
|
||||||
* channel.startTyping();
|
* channel.sendTyping();
|
||||||
* @example
|
|
||||||
* // Start typing in a channel with a typing count of five, or set it to five
|
|
||||||
* channel.startTyping(5);
|
|
||||||
*/
|
*/
|
||||||
startTyping(count) {
|
async sendTyping() {
|
||||||
if (typeof count !== 'undefined' && count < 1) throw new RangeError('TYPING_COUNT');
|
await this.client.api.channels(this.id).typing.post();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -404,10 +330,7 @@ class TextBasedChannel {
|
|||||||
'lastMessage',
|
'lastMessage',
|
||||||
'lastPinAt',
|
'lastPinAt',
|
||||||
'bulkDelete',
|
'bulkDelete',
|
||||||
'startTyping',
|
'sendTyping',
|
||||||
'stopTyping',
|
|
||||||
'typing',
|
|
||||||
'typingCount',
|
|
||||||
'createMessageCollector',
|
'createMessageCollector',
|
||||||
'awaitMessages',
|
'awaitMessages',
|
||||||
'createMessageComponentCollector',
|
'createMessageComponentCollector',
|
||||||
|
|||||||
37
typings/index.d.ts
vendored
37
typings/index.d.ts
vendored
@@ -1649,6 +1649,24 @@ export class ThreadMemberFlags extends BitField<ThreadMemberFlagsString> {
|
|||||||
public static resolve(bit?: BitFieldResolvable<ThreadMemberFlagsString, number>): number;
|
public static resolve(bit?: BitFieldResolvable<ThreadMemberFlagsString, number>): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Typing extends Base {
|
||||||
|
public constructor(
|
||||||
|
channel: TextChannel | PartialDMChannel | NewsChannel | ThreadChannel,
|
||||||
|
user: PartialUser,
|
||||||
|
data?: object,
|
||||||
|
);
|
||||||
|
public channel: TextChannel | PartialDMChannel | NewsChannel | ThreadChannel;
|
||||||
|
public user: PartialUser;
|
||||||
|
public startedTimestamp: number;
|
||||||
|
public readonly startedAt: Date;
|
||||||
|
public readonly guild: Guild | null;
|
||||||
|
public readonly member: GuildMember | null;
|
||||||
|
public inGuild(): this is this & {
|
||||||
|
channel: TextChannel | NewsChannel | ThreadChannel;
|
||||||
|
readonly guild: Guild;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class User extends PartialTextBasedChannel(Base) {
|
export class User extends PartialTextBasedChannel(Base) {
|
||||||
public constructor(client: Client, data: unknown);
|
public constructor(client: Client, data: unknown);
|
||||||
public avatar: string | null;
|
public avatar: string | null;
|
||||||
@@ -1672,9 +1690,6 @@ export class User extends PartialTextBasedChannel(Base) {
|
|||||||
public fetch(force?: boolean): Promise<User>;
|
public fetch(force?: boolean): Promise<User>;
|
||||||
public fetchFlags(force?: boolean): Promise<UserFlags>;
|
public fetchFlags(force?: boolean): Promise<UserFlags>;
|
||||||
public toString(): UserMention;
|
public toString(): UserMention;
|
||||||
public typingDurationIn(channel: ChannelResolvable): number;
|
|
||||||
public typingIn(channel: ChannelResolvable): boolean;
|
|
||||||
public typingSinceIn(channel: ChannelResolvable): Date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserFlags extends BitField<UserFlagsString> {
|
export class UserFlags extends BitField<UserFlagsString> {
|
||||||
@@ -2420,13 +2435,10 @@ export interface PartialTextBasedChannelFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
||||||
_typing: Map<string, TypingData>;
|
|
||||||
lastMessageId: Snowflake | null;
|
lastMessageId: Snowflake | null;
|
||||||
readonly lastMessage: Message | null;
|
readonly lastMessage: Message | null;
|
||||||
lastPinTimestamp: number | null;
|
lastPinTimestamp: number | null;
|
||||||
readonly lastPinAt: Date | null;
|
readonly lastPinAt: Date | null;
|
||||||
typing: boolean;
|
|
||||||
typingCount: number;
|
|
||||||
awaitMessageComponent<T extends MessageComponentInteraction = MessageComponentInteraction>(
|
awaitMessageComponent<T extends MessageComponentInteraction = MessageComponentInteraction>(
|
||||||
options?: AwaitMessageComponentOptions<T>,
|
options?: AwaitMessageComponentOptions<T>,
|
||||||
): Promise<T>;
|
): Promise<T>;
|
||||||
@@ -2439,8 +2451,7 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
|||||||
options?: InteractionCollectorOptions<T>,
|
options?: InteractionCollectorOptions<T>,
|
||||||
): InteractionCollector<T>;
|
): InteractionCollector<T>;
|
||||||
createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
|
createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
|
||||||
startTyping(count?: number): Promise<void>;
|
sendTyping(): Promise<void>;
|
||||||
stopTyping(force?: boolean): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PartialWebhookMixin<T>(Base?: Constructable<T>): Constructable<T & PartialWebhookFields>;
|
export function PartialWebhookMixin<T>(Base?: Constructable<T>): Constructable<T & PartialWebhookFields>;
|
||||||
@@ -2835,7 +2846,7 @@ export interface ClientEvents {
|
|||||||
mewMembers: Collection<Snowflake, ThreadMember>,
|
mewMembers: Collection<Snowflake, ThreadMember>,
|
||||||
];
|
];
|
||||||
threadUpdate: [oldThread: ThreadChannel, newThread: ThreadChannel];
|
threadUpdate: [oldThread: ThreadChannel, newThread: ThreadChannel];
|
||||||
typingStart: [channel: Channel | PartialDMChannel, user: User | PartialUser];
|
typingStart: [typing: Typing];
|
||||||
userUpdate: [oldUser: User | PartialUser, newUser: User];
|
userUpdate: [oldUser: User | PartialUser, newUser: User];
|
||||||
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
|
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
|
||||||
webhookUpdate: [channel: TextChannel];
|
webhookUpdate: [channel: TextChannel];
|
||||||
@@ -3962,14 +3973,6 @@ export type SystemChannelFlagsResolvable = BitFieldResolvable<SystemChannelFlags
|
|||||||
|
|
||||||
export type SystemMessageType = Exclude<MessageType, 'DEFAULT' | 'REPLY' | 'APPLICATION_COMMAND'>;
|
export type SystemMessageType = Exclude<MessageType, 'DEFAULT' | 'REPLY' | 'APPLICATION_COMMAND'>;
|
||||||
|
|
||||||
export interface TypingData {
|
|
||||||
user: User | PartialUser;
|
|
||||||
since: Date;
|
|
||||||
lastTimestamp: Date;
|
|
||||||
elapsedTime: number;
|
|
||||||
timeout: NodeJS.Timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StageInstanceEditOptions {
|
export interface StageInstanceEditOptions {
|
||||||
topic?: string;
|
topic?: string;
|
||||||
privacyLevel?: PrivacyLevel | number;
|
privacyLevel?: PrivacyLevel | number;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Collection,
|
Collection,
|
||||||
Constants,
|
Constants,
|
||||||
DMChannel,
|
DMChannel,
|
||||||
|
Guild,
|
||||||
GuildApplicationCommandManager,
|
GuildApplicationCommandManager,
|
||||||
GuildChannelManager,
|
GuildChannelManager,
|
||||||
GuildEmoji,
|
GuildEmoji,
|
||||||
@@ -27,7 +28,9 @@ import {
|
|||||||
MessageReaction,
|
MessageReaction,
|
||||||
NewsChannel,
|
NewsChannel,
|
||||||
Options,
|
Options,
|
||||||
|
PartialDMChannel,
|
||||||
PartialTextBasedChannelFields,
|
PartialTextBasedChannelFields,
|
||||||
|
PartialUser,
|
||||||
Permissions,
|
Permissions,
|
||||||
ReactionCollector,
|
ReactionCollector,
|
||||||
Role,
|
Role,
|
||||||
@@ -41,6 +44,7 @@ import {
|
|||||||
TextBasedChannelFields,
|
TextBasedChannelFields,
|
||||||
TextChannel,
|
TextChannel,
|
||||||
ThreadChannel,
|
ThreadChannel,
|
||||||
|
Typing,
|
||||||
User,
|
User,
|
||||||
VoiceChannel,
|
VoiceChannel,
|
||||||
} from '..';
|
} from '..';
|
||||||
@@ -607,13 +611,22 @@ assertType<Promise<Collection<Snowflake, GuildEmoji>>>(guildEmojiManager.fetch()
|
|||||||
assertType<Promise<Collection<Snowflake, GuildEmoji>>>(guildEmojiManager.fetch(undefined, {}));
|
assertType<Promise<Collection<Snowflake, GuildEmoji>>>(guildEmojiManager.fetch(undefined, {}));
|
||||||
assertType<Promise<GuildEmoji | null>>(guildEmojiManager.fetch('0'));
|
assertType<Promise<GuildEmoji | null>>(guildEmojiManager.fetch('0'));
|
||||||
|
|
||||||
// Test partials structures
|
declare const typing: Typing;
|
||||||
client.on('typingStart', (channel, user) => {
|
assertType<PartialUser>(typing.user);
|
||||||
if (channel.partial) assertType<undefined>(channel.lastMessageId);
|
if (typing.user.partial) assertType<null>(typing.user.username);
|
||||||
if (user.partial) return assertType<null>(user.username);
|
|
||||||
assertType<string>(user.username);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
assertType<TextChannel | PartialDMChannel | NewsChannel | ThreadChannel>(typing.channel);
|
||||||
|
if (typing.channel.partial) assertType<undefined>(typing.channel.lastMessageId);
|
||||||
|
|
||||||
|
assertType<GuildMember | null>(typing.member);
|
||||||
|
assertType<Guild | null>(typing.guild);
|
||||||
|
|
||||||
|
if (typing.inGuild()) {
|
||||||
|
assertType<Guild>(typing.channel.guild);
|
||||||
|
assertType<Guild>(typing.guild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test partials structures
|
||||||
client.on('guildMemberRemove', member => {
|
client.on('guildMemberRemove', member => {
|
||||||
if (member.partial) return assertType<null>(member.joinedAt);
|
if (member.partial) return assertType<null>(member.joinedAt);
|
||||||
assertType<Date | null>(member.joinedAt);
|
assertType<Date | null>(member.joinedAt);
|
||||||
|
|||||||
Reference in New Issue
Block a user