diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index 4ac0ac500..2638f3753 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -63,7 +63,19 @@ class DMChannel extends Channel { return; } - setTyping() { + startTyping() { + return; + } + + stopTyping() { + return; + } + + get typing() { + return; + } + + get typingCount() { return; } diff --git a/src/structures/GroupDMChannel.js b/src/structures/GroupDMChannel.js index a964120a8..6291e6545 100644 --- a/src/structures/GroupDMChannel.js +++ b/src/structures/GroupDMChannel.js @@ -140,7 +140,19 @@ class GroupDMChannel extends Channel { return; } - setTyping() { + startTyping() { + return; + } + + stopTyping() { + return; + } + + get typing() { + return; + } + + get typingCount() { return; } diff --git a/src/structures/TextChannel.js b/src/structures/TextChannel.js index da6218abd..f8057bc08 100644 --- a/src/structures/TextChannel.js +++ b/src/structures/TextChannel.js @@ -48,7 +48,19 @@ class TextChannel extends GuildChannel { return; } - setTyping() { + startTyping() { + return; + } + + stopTyping() { + return; + } + + get typing() { + return; + } + + get typingCount() { return; } diff --git a/src/structures/interface/TextBasedChannel.js b/src/structures/interface/TextBasedChannel.js index 2adb5b72b..2f70ffdcd 100644 --- a/src/structures/interface/TextBasedChannel.js +++ b/src/structures/interface/TextBasedChannel.js @@ -256,27 +256,70 @@ class TextBasedChannel { } /** - * Starts or stops a typing indicator in the channel. - * It can take a few seconds for the Client User to stop typing. - * @param {Boolean} typing whether or not the client user should be typing + * Starts a typing indicator in the channel. + * @param {Number} [count] The number of times startTyping should be considered to have been called * @returns {null} * @example * // start typing in a channel - * channel.setTyping(true); + * channel.startTyping(); + */ + startTyping(count) { + if (typeof count !== 'undefined' && count < 1) throw new RangeError('count must be at least 1'); + if (!this.client.user._typing.has(this.id)) { + this.client.user._typing.set(this.id, { + count: count || 1, + interval: this.client.setInterval(() => { + this.client.rest.methods.sendTyping(this.id); + }, 4000), + }); + this.client.rest.methods.sendTyping(this.id); + } else { + const entry = this.client.user._typing.get(this.id); + entry.count = count || entry.count + 1; + } + } + + /** + * Stops the typing indicator in the channel. + * The indicator will only stop if this is called as many times as startTyping(). + * It can take a few seconds for the Client User to stop typing. + * @param {Boolean} [force=false] whether or not to force the indicator to stop regardless of call count + * @returns {null} * @example * // stop typing in a channel - * channel.setTyping(false); + * channel.stopTyping(); + * @example + * // force typing to fully stop in a channel + * channel.stopTyping(true); */ - setTyping(typing) { - clearInterval(this.client.user._typing.get(this.id)); - if (typing) { - this.client.user._typing.set(this.id, this.client.setInterval(() => { - this.client.rest.methods.sendTyping(this.id); - }, 4000)); - this.client.rest.methods.sendTyping(this.id); + 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) { + clearInterval(entry.interval); + this.client.user._typing.delete(this.id); + } } } + /** + * Whether or not the typing indicator is being shown in the channel. + * @type {Boolean} + */ + get typing() { + return this.client.user._typing.has(this.id); + } + + /** + * Number of times `startTyping` has been called. + * @type {Number} + */ + get typingCount() { + if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count; + return 0; + } + /** * Creates a Message Collector * @param {CollectorFilterFunction} filter the filter to create the collector with @@ -371,7 +414,7 @@ class TextBasedChannel { } function applyProp(structure, prop) { - structure.prototype[prop] = TextBasedChannel.prototype[prop]; + Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop)); } exports.applyToClass = (structure, full = false) => { @@ -380,7 +423,10 @@ exports.applyToClass = (structure, full = false) => { props.push('_cacheMessage'); props.push('fetchMessages'); props.push('bulkDelete'); - props.push('setTyping'); + props.push('startTyping'); + props.push('stopTyping'); + props.push('typing'); + props.push('typingCount'); props.push('fetchPinnedMessages'); props.push('createCollector'); props.push('awaitMessages');