update
This commit is contained in:
parent
26c71d7777
commit
02fcfb881f
@ -1,16 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { Events } = require('../../../util/Constants');
|
const { Events, Status } = require('../../../util/Constants');
|
||||||
module.exports = (client, packet) => {
|
module.exports = (client, packet, shard) => {
|
||||||
/**
|
|
||||||
* Emitted whenever a recipient is added from a group DM.
|
|
||||||
* @event Client#channelRecipientAdd
|
|
||||||
* @param {PartialGroupDMChannel} channel Group DM channel
|
|
||||||
* @param {User} user User
|
|
||||||
*/
|
|
||||||
const channel = client.channels.cache.get(packet.d.channel_id);
|
const channel = client.channels.cache.get(packet.d.channel_id);
|
||||||
if (!channel) return;
|
if (channel) {
|
||||||
if (!channel._recipients) channel._recipients = [];
|
if (!channel._recipients) channel._recipients = [];
|
||||||
channel._recipients.push(packet.d.user);
|
channel._recipients.push(packet.d.user);
|
||||||
const user = client.users._add(packet.d.user);
|
const user = client.users._add(packet.d.user);
|
||||||
client.emit(Events.CHANNEL_RECIPIENT_ADD, channel, user);
|
if (shard.status == Status.READY) {
|
||||||
|
/**
|
||||||
|
* Emitted whenever a recipient is added from a group DM.
|
||||||
|
* @event Client#channelRecipientAdd
|
||||||
|
* @param {GroupDMChannel} channel Group DM channel
|
||||||
|
* @param {User} user User
|
||||||
|
*/
|
||||||
|
client.emit(Events.CHANNEL_RECIPIENT_ADD, channel, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { Events } = require('../../../util/Constants');
|
const { Events } = require('../../../util/Constants');
|
||||||
module.exports = (client, packet) => {
|
module.exports = (client, packet) => {
|
||||||
/**
|
|
||||||
* Emitted whenever a recipient is removed from a group DM.
|
|
||||||
* @event Client#channelRecipientRemove
|
|
||||||
* @param {PartialGroupDMChannel} channel Group DM channel
|
|
||||||
* @param {User} user User
|
|
||||||
*/
|
|
||||||
const channel = client.channels.cache.get(packet.d.channel_id);
|
const channel = client.channels.cache.get(packet.d.channel_id);
|
||||||
if (!channel) return;
|
if (channel) {
|
||||||
if (!channel._recipients) channel._recipients = [];
|
if (!channel._recipients) channel._recipients = [];
|
||||||
channel._recipients = channel._recipients.filter(r => r !== packet.d.user.id);
|
channel._recipients = channel._recipients.filter(u => u.id !== packet.d.user.id);
|
||||||
const user = client.users._add(packet.d.user);
|
/**
|
||||||
client.emit(Events.CHANNEL_RECIPIENT_REMOVE, channel, user);
|
* Emitted whenever a recipient is removed from a group DM.
|
||||||
|
* @event Client#channelRecipientRemove
|
||||||
|
* @param {GroupDMChannel} channel Group DM channel
|
||||||
|
* @param {User} user User
|
||||||
|
*/
|
||||||
|
client.emit(Events.CHANNEL_RECIPIENT_REMOVE, channel, client.users._add(packet.d.user));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const { Events } = require('../../../util/Constants');
|
|
||||||
|
|
||||||
module.exports = (client, { d: data }) => {
|
|
||||||
for (const command of data.application_commands) {
|
|
||||||
const user = client.users.cache.get(command.application_id);
|
|
||||||
if (!user || !user.bot) continue;
|
|
||||||
user.application?.commands?._add(command, true);
|
|
||||||
}
|
|
||||||
client.emit(Events.GUILD_APPLICATION_COMMANDS_UPDATE, data);
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const { Events } = require('../../../util/Constants');
|
|
||||||
|
|
||||||
module.exports = (client, { d: data }) => {
|
|
||||||
const channel = client.channels.cache.get(data.channel_id);
|
|
||||||
/**
|
|
||||||
* Emitted whenever message is acknowledged (mark read / unread)
|
|
||||||
* @event Client#messageAck
|
|
||||||
* @param {TextChannel} channel Channel
|
|
||||||
* @param {Snowflake} message_id Message ID
|
|
||||||
* @param {boolean} isRead Whether the message is read
|
|
||||||
* @param {Object} raw Raw data
|
|
||||||
*/
|
|
||||||
client.emit(Events.MESSAGE_ACK, channel, data.message_id, !data.manual, data);
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = (client, { d: data }) => {
|
module.exports = (client, { d: data }) => {
|
||||||
client.user.notes.set(data.id, data.note);
|
client.notes.cache.set(data.id, data.note);
|
||||||
};
|
};
|
||||||
|
@ -130,7 +130,7 @@ class GuildBanManager extends CachedManager {
|
|||||||
* @typedef {Object} BanOptions
|
* @typedef {Object} BanOptions
|
||||||
* @property {number} [days=0] Number of days of messages to delete, must be between 0 and 7, inclusive
|
* @property {number} [days=0] Number of days of messages to delete, must be between 0 and 7, inclusive
|
||||||
* <warn>This property is deprecated. Use `deleteMessageSeconds` instead.</warn>
|
* <warn>This property is deprecated. Use `deleteMessageSeconds` instead.</warn>
|
||||||
* @property {number} [deleteMessageSeconds=0] Number of seconds of messages to delete,
|
* @property {number} [deleteMessageSeconds] Number of seconds of messages to delete,
|
||||||
* must be between 0 and 604800 (7 days), inclusive
|
* must be between 0 and 604800 (7 days), inclusive
|
||||||
* @property {string} [reason] The reason for the ban
|
* @property {string} [reason] The reason for the ban
|
||||||
*/
|
*/
|
||||||
|
@ -89,7 +89,7 @@ class PermissionOverwriteManager extends CachedManager {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async upsert(userOrRole, options, overwriteOptions = {}, existing) {
|
async upsert(userOrRole, options, overwriteOptions = {}, existing) {
|
||||||
const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
|
let userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
|
||||||
let { type, reason } = overwriteOptions;
|
let { type, reason } = overwriteOptions;
|
||||||
if (typeof type !== 'number') {
|
if (typeof type !== 'number') {
|
||||||
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|
||||||
|
@ -179,7 +179,7 @@ class ThreadMemberManager extends CachedManager {
|
|||||||
const id = this.resolveId(member);
|
const id = this.resolveId(member);
|
||||||
return id
|
return id
|
||||||
? this._fetchOne(id, options)
|
? this._fetchOne(id, options)
|
||||||
: this._fetchMany(typeof member !== 'boolean' ? member : { ...options, cache: member });
|
: this._fetchMany(typeof member === 'boolean' ? { ...options, cache: member } : options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
const { ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
|
const { ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Role connection metadata object for an application.
|
||||||
|
*/
|
||||||
class ApplicationRoleConnectionMetadata {
|
class ApplicationRoleConnectionMetadata {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +194,7 @@ class AutoModerationRule extends Base {
|
|||||||
* @returns {Promise<AutoModerationRule>}
|
* @returns {Promise<AutoModerationRule>}
|
||||||
*/
|
*/
|
||||||
setKeywordFilter(keywordFilter, reason) {
|
setKeywordFilter(keywordFilter, reason) {
|
||||||
return this.edit({ triggerMetadata: { keywordFilter }, reason });
|
return this.edit({ triggerMetadata: { ...this.triggerMetadata, keywordFilter }, reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,7 +205,7 @@ class AutoModerationRule extends Base {
|
|||||||
* @returns {Promise<AutoModerationRule>}
|
* @returns {Promise<AutoModerationRule>}
|
||||||
*/
|
*/
|
||||||
setRegexPatterns(regexPatterns, reason) {
|
setRegexPatterns(regexPatterns, reason) {
|
||||||
return this.edit({ triggerMetadata: { regexPatterns }, reason });
|
return this.edit({ triggerMetadata: { ...this.triggerMetadata, regexPatterns }, reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,7 +215,7 @@ class AutoModerationRule extends Base {
|
|||||||
* @returns {Promise<AutoModerationRule>}
|
* @returns {Promise<AutoModerationRule>}
|
||||||
*/
|
*/
|
||||||
setPresets(presets, reason) {
|
setPresets(presets, reason) {
|
||||||
return this.edit({ triggerMetadata: { presets }, reason });
|
return this.edit({ triggerMetadata: { ...this.triggerMetadata, presets }, reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,7 +225,7 @@ class AutoModerationRule extends Base {
|
|||||||
* @returns {Promise<AutoModerationRule>}
|
* @returns {Promise<AutoModerationRule>}
|
||||||
*/
|
*/
|
||||||
setAllowList(allowList, reason) {
|
setAllowList(allowList, reason) {
|
||||||
return this.edit({ triggerMetadata: { allowList }, reason });
|
return this.edit({ triggerMetadata: { ...this.triggerMetadata, allowList }, reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,7 +235,7 @@ class AutoModerationRule extends Base {
|
|||||||
* @returns {Promise<AutoModerationRule>}
|
* @returns {Promise<AutoModerationRule>}
|
||||||
*/
|
*/
|
||||||
setMentionTotalLimit(mentionTotalLimit, reason) {
|
setMentionTotalLimit(mentionTotalLimit, reason) {
|
||||||
return this.edit({ triggerMetadata: { mentionTotalLimit }, reason });
|
return this.edit({ triggerMetadata: { ...this.triggerMetadata, mentionTotalLimit }, reason });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
|
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
|
||||||
const Interaction = require('./Interaction');
|
const Interaction = require('./Interaction');
|
||||||
|
const { Error } = require('../errors');
|
||||||
const { InteractionResponseTypes, ApplicationCommandOptionTypes } = require('../util/Constants');
|
const { InteractionResponseTypes, ApplicationCommandOptionTypes } = require('../util/Constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,7 +76,11 @@ class BaseMessageComponent {
|
|||||||
component = data instanceof MessageButton ? data : new MessageButton(data);
|
component = data instanceof MessageButton ? data : new MessageButton(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MessageComponentTypes.SELECT_MENU: {
|
case MessageComponentTypes.STRING_SELECT:
|
||||||
|
case MessageComponentTypes.USER_SELECT:
|
||||||
|
case MessageComponentTypes.ROLE_SELECT:
|
||||||
|
case MessageComponentTypes.MENTIONABLE_SELECT:
|
||||||
|
case MessageComponentTypes.CHANNEL_SELECT: {
|
||||||
const MessageSelectMenu = require('./MessageSelectMenu');
|
const MessageSelectMenu = require('./MessageSelectMenu');
|
||||||
component = data instanceof MessageSelectMenu ? data : new MessageSelectMenu(data);
|
component = data instanceof MessageSelectMenu ? data : new MessageSelectMenu(data);
|
||||||
break;
|
break;
|
||||||
|
@ -53,7 +53,6 @@ class Channel extends Base {
|
|||||||
if ('flags' in data) {
|
if ('flags' in data) {
|
||||||
/**
|
/**
|
||||||
* The flags that are applied to the channel.
|
* The flags that are applied to the channel.
|
||||||
* <info>This is only `null` in a {@link PartialGroupDMChannel}. In all other cases, it is not `null`.</info>
|
|
||||||
* @type {?Readonly<ChannelFlags>}
|
* @type {?Readonly<ChannelFlags>}
|
||||||
*/
|
*/
|
||||||
this.flags = new ChannelFlags(data.flags).freeze();
|
this.flags = new ChannelFlags(data.flags).freeze();
|
||||||
@ -203,8 +202,8 @@ class Channel extends Base {
|
|||||||
if ((data.recipients && data.type !== ChannelTypes.GROUP_DM) || data.type === ChannelTypes.DM) {
|
if ((data.recipients && data.type !== ChannelTypes.GROUP_DM) || data.type === ChannelTypes.DM) {
|
||||||
channel = new DMChannel(client, data);
|
channel = new DMChannel(client, data);
|
||||||
} else if (data.type === ChannelTypes.GROUP_DM) {
|
} else if (data.type === ChannelTypes.GROUP_DM) {
|
||||||
const PartialGroupDMChannel = require('./PartialGroupDMChannel');
|
const GroupDMChannel = require('./GroupDMChannel');
|
||||||
channel = new PartialGroupDMChannel(client, data);
|
channel = new GroupDMChannel(client, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
guild ??= client.guilds.cache.get(data.guild_id);
|
guild ??= client.guilds.cache.get(data.guild_id);
|
||||||
|
@ -22,7 +22,7 @@ class ContextMenuInteraction extends BaseCommandInteraction {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the target of the interaction
|
* The id of the target of this interaction
|
||||||
* @type {Snowflake}
|
* @type {Snowflake}
|
||||||
*/
|
*/
|
||||||
this.targetId = data.data.target_id;
|
this.targetId = data.data.target_id;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
const GuildChannel = require('./GuildChannel');
|
const GuildChannel = require('./GuildChannel');
|
||||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||||
const GuildForumThreadManager = require('../managers/GuildForumThreadManager');
|
const GuildForumThreadManager = require('../managers/GuildForumThreadManager');
|
||||||
const InteractionManager = require('../managers/InteractionManager');
|
|
||||||
const { SortOrderTypes, ForumLayoutTypes } = require('../util/Constants');
|
const { SortOrderTypes, ForumLayoutTypes } = require('../util/Constants');
|
||||||
const { transformAPIGuildForumTag, transformAPIGuildDefaultReaction } = require('../util/Util');
|
const { transformAPIGuildForumTag, transformAPIGuildDefaultReaction } = require('../util/Util');
|
||||||
|
|
||||||
@ -46,12 +45,6 @@ class ForumChannel extends GuildChannel {
|
|||||||
constructor(guild, data, client) {
|
constructor(guild, data, client) {
|
||||||
super(guild, data, client, false);
|
super(guild, data, client, false);
|
||||||
|
|
||||||
/**
|
|
||||||
* A manager of the interactions sent to this channel
|
|
||||||
* @type {InteractionManager}
|
|
||||||
*/
|
|
||||||
this.interactions = new InteractionManager(this);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A manager of the threads belonging to this channel
|
* A manager of the threads belonging to this channel
|
||||||
* @type {GuildForumThreadManager}
|
* @type {GuildForumThreadManager}
|
||||||
@ -260,12 +253,9 @@ TextBasedChannel.applyToClass(ForumChannel, true, [
|
|||||||
'send',
|
'send',
|
||||||
'lastMessage',
|
'lastMessage',
|
||||||
'lastPinAt',
|
'lastPinAt',
|
||||||
'bulkDelete',
|
|
||||||
'sendTyping',
|
'sendTyping',
|
||||||
'createMessageCollector',
|
'createMessageCollector',
|
||||||
'awaitMessages',
|
'awaitMessages',
|
||||||
'createMessageComponentCollector',
|
|
||||||
'awaitMessageComponent',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
module.exports = ForumChannel;
|
module.exports = ForumChannel;
|
||||||
|
@ -299,8 +299,6 @@ class GroupDMChannel extends Channel {
|
|||||||
sendTyping() {}
|
sendTyping() {}
|
||||||
createMessageCollector() {}
|
createMessageCollector() {}
|
||||||
awaitMessages() {}
|
awaitMessages() {}
|
||||||
createMessageComponentCollector() {}
|
|
||||||
awaitMessageComponent() {}
|
|
||||||
// Doesn't work on DM channels; setRateLimitPerUser() {}
|
// Doesn't work on DM channels; setRateLimitPerUser() {}
|
||||||
// Doesn't work on DM channels; setNSFW() {}
|
// Doesn't work on DM channels; setNSFW() {}
|
||||||
}
|
}
|
||||||
|
@ -269,71 +269,10 @@ class Interaction extends Base {
|
|||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction}.
|
* Indicates whether this interaction is a {@link SelectMenuInteraction}.
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
isAnySelectMenu() {
|
|
||||||
return InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && typeof this.values !== 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
* @deprecated Use {@link Interaction#isStringSelect()} instead
|
|
||||||
*/
|
|
||||||
isSelectMenu() {
|
isSelectMenu() {
|
||||||
return this.isStringSelect();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isStringSelect() {
|
|
||||||
return (
|
return (
|
||||||
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
||||||
MessageComponentTypes[this.componentType] === MessageComponentTypes.STRING_SELECT
|
MessageComponentTypes[this.componentType] === MessageComponentTypes.SELECT_MENU
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `USER_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isUserSelect() {
|
|
||||||
return (
|
|
||||||
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
|
||||||
MessageComponentTypes[this.componentType] === MessageComponentTypes.USER_SELECT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `ROLE_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isRoleSelect() {
|
|
||||||
return (
|
|
||||||
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
|
||||||
MessageComponentTypes[this.componentType] === MessageComponentTypes.ROLE_SELECT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `MENTIONABLE_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isMentionableSelect() {
|
|
||||||
return (
|
|
||||||
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
|
||||||
MessageComponentTypes[this.componentType] === MessageComponentTypes.MENTIONABLE_SELECT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this interaction is a {@link SelectMenuInteraction} with a `CHANNEL_SELECT` type.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isChannelSelect() {
|
|
||||||
return (
|
|
||||||
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT &&
|
|
||||||
MessageComponentTypes[this.componentType] === MessageComponentTypes.CHANNEL_SELECT
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { setTimeout } = require('node:timers');
|
|
||||||
const BaseMessageComponent = require('./BaseMessageComponent');
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
||||||
const { RangeError } = require('../errors');
|
const { RangeError } = require('../errors');
|
||||||
const { MessageButtonStyles, MessageComponentTypes, InteractionTypes } = require('../util/Constants');
|
const { MessageButtonStyles, MessageComponentTypes } = require('../util/Constants');
|
||||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
|
||||||
const Util = require('../util/Util');
|
const Util = require('../util/Util');
|
||||||
const { lazy } = require('../util/Util');
|
|
||||||
const Message = lazy(() => require('../structures/Message').Message);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a button message component.
|
* Represents a button message component.
|
||||||
@ -164,68 +160,6 @@ class MessageButton extends BaseMessageComponent {
|
|||||||
static resolveStyle(style) {
|
static resolveStyle(style) {
|
||||||
return typeof style === 'string' ? style : MessageButtonStyles[style];
|
return typeof style === 'string' ? style : MessageButtonStyles[style];
|
||||||
}
|
}
|
||||||
// Patch Click
|
|
||||||
/**
|
|
||||||
* Click the button
|
|
||||||
* @param {Message} message Discord Message
|
|
||||||
* @returns {Promise<InteractionResponse>}
|
|
||||||
*/
|
|
||||||
async click(message) {
|
|
||||||
const nonce = SnowflakeUtil.generate();
|
|
||||||
if (!(message instanceof Message())) throw new Error('[UNKNOWN_MESSAGE] Please pass a valid Message');
|
|
||||||
if (!this.customId || this.style == MessageButtonStyles.LINK || this.disabled) return false;
|
|
||||||
const data = {
|
|
||||||
type: InteractionTypes.MESSAGE_COMPONENT,
|
|
||||||
nonce,
|
|
||||||
guild_id: message.guild?.id ?? null,
|
|
||||||
channel_id: message.channel.id,
|
|
||||||
message_id: message.id,
|
|
||||||
application_id: message.applicationId ?? message.author.id,
|
|
||||||
session_id: message.client.sessionId,
|
|
||||||
message_flags: message.flags.bitfield,
|
|
||||||
data: {
|
|
||||||
component_type: MessageComponentTypes.BUTTON,
|
|
||||||
custom_id: this.customId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
await message.client.api.interactions.post({
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
message.client._interactionCache.set(nonce, {
|
|
||||||
channelId: message.channelId,
|
|
||||||
guildId: message.guildId,
|
|
||||||
metadata: data,
|
|
||||||
});
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const handler = data => {
|
|
||||||
timeout.refresh();
|
|
||||||
if (data.metadata?.nonce !== nonce) return;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
message.client.removeListener('interactionResponse', handler);
|
|
||||||
message.client.decrementMaxListeners();
|
|
||||||
if (data.status) {
|
|
||||||
resolve(data.metadata);
|
|
||||||
} else {
|
|
||||||
reject(
|
|
||||||
new Error('INTERACTION_ERROR', {
|
|
||||||
cause: data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
message.client.removeListener('interactionResponse', handler);
|
|
||||||
message.client.decrementMaxListeners();
|
|
||||||
reject(
|
|
||||||
new Error('INTERACTION_TIMEOUT', {
|
|
||||||
cause: data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}, message.client.options.interactionTimeout).unref();
|
|
||||||
message.client.incrementMaxListeners();
|
|
||||||
message.client.on('interactionResponse', handler);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = MessageButton;
|
module.exports = MessageButton;
|
||||||
|
@ -1,16 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { setTimeout } = require('node:timers');
|
|
||||||
const BaseMessageComponent = require('./BaseMessageComponent');
|
const BaseMessageComponent = require('./BaseMessageComponent');
|
||||||
const {
|
const { ChannelTypes, MessageComponentTypes } = require('../util/Constants');
|
||||||
ChannelTypes,
|
|
||||||
MessageComponentTypes,
|
|
||||||
SelectMenuComponentTypes,
|
|
||||||
InteractionTypes,
|
|
||||||
} = require('../util/Constants');
|
|
||||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
|
||||||
const { lazy } = require('../util/Util');
|
|
||||||
const Message = lazy(() => require('./Message').Message);
|
|
||||||
const Util = require('../util/Util');
|
const Util = require('../util/Util');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,130 +94,6 @@ class MessageSelectMenu extends BaseMessageComponent {
|
|||||||
) ?? [];
|
) ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the channel types to the select menu
|
|
||||||
* @param {...ChannelType[]} channelTypes Added channel types
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
addChannelTypes(...channelTypes) {
|
|
||||||
if (!channelTypes.every(channelType => ChannelTypes[channelType])) {
|
|
||||||
throw new TypeError('INVALID_TYPE', 'channelTypes', 'Rest<ChannelTypes[]>');
|
|
||||||
}
|
|
||||||
this.channelTypes.push(
|
|
||||||
...channelTypes.map(channelType => (typeof channelType === 'string' ? channelType : ChannelTypes[channelType])),
|
|
||||||
);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the channel types of the select menu
|
|
||||||
* @param {...ChannelType[]} channelTypes An array of new channel types
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setChannelTypes(...channelTypes) {
|
|
||||||
if (!channelTypes.every(channelType => ChannelTypes[channelType])) {
|
|
||||||
throw new TypeError('INVALID_TYPE', 'channelTypes', 'Rest<ChannelTypes[]>');
|
|
||||||
}
|
|
||||||
this.channelTypes = channelTypes.map(channelType =>
|
|
||||||
typeof channelType === 'string' ? channelType : ChannelTypes[channelType],
|
|
||||||
);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the custom id of this select menu
|
|
||||||
* @param {string} customId A unique string to be sent in the interaction when clicked
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setCustomId(customId) {
|
|
||||||
this.customId = Util.verifyString(customId, RangeError, 'SELECT_MENU_CUSTOM_ID');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the interactive status of the select menu
|
|
||||||
* @param {boolean} [disabled=true] Whether this select menu should be disabled
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setDisabled(disabled = true) {
|
|
||||||
this.disabled = disabled;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the maximum number of selections allowed for this select menu
|
|
||||||
* @param {number} maxValues Number of selections to be allowed
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setMaxValues(maxValues) {
|
|
||||||
this.maxValues = maxValues;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the minimum number of selections required for this select menu
|
|
||||||
* <info>This will default the maxValues to the number of options, unless manually set</info>
|
|
||||||
* @param {number} minValues Number of selections to be required
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setMinValues(minValues) {
|
|
||||||
this.minValues = minValues;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the placeholder of this select menu
|
|
||||||
* @param {string} placeholder Custom placeholder text to display when nothing is selected
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setPlaceholder(placeholder) {
|
|
||||||
this.placeholder = Util.verifyString(placeholder, RangeError, 'SELECT_MENU_PLACEHOLDER');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the select menu
|
|
||||||
* @param {SelectMenuComponentType} type Type of the select menu
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setType(type) {
|
|
||||||
if (!SelectMenuComponentTypes[type]) throw new TypeError('INVALID_TYPE', 'type', 'SelectMenuComponentType');
|
|
||||||
this.type = BaseMessageComponent.resolveType(type);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds options to the select menu.
|
|
||||||
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to add
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
addOptions(...options) {
|
|
||||||
this.options.push(...this.constructor.normalizeOptions(options));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the options of the select menu.
|
|
||||||
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to set
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
setOptions(...options) {
|
|
||||||
this.spliceOptions(0, this.options.length, options);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes, replaces, and inserts options in the select menu.
|
|
||||||
* @param {number} index The index to start at
|
|
||||||
* @param {number} deleteCount The number of options to remove
|
|
||||||
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} [options] The replacing option objects
|
|
||||||
* @returns {MessageSelectMenu}
|
|
||||||
*/
|
|
||||||
spliceOptions(index, deleteCount, ...options) {
|
|
||||||
this.options.splice(index, deleteCount, ...this.constructor.normalizeOptions(...options));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the select menu into a plain object
|
* Transforms the select menu into a plain object
|
||||||
* @returns {APIMessageSelectMenu} The raw data of this select menu
|
* @returns {APIMessageSelectMenu} The raw data of this select menu
|
||||||
@ -268,124 +135,6 @@ class MessageSelectMenu extends BaseMessageComponent {
|
|||||||
static normalizeOptions(...options) {
|
static normalizeOptions(...options) {
|
||||||
return options.flat(Infinity).map(option => this.normalizeOption(option));
|
return options.flat(Infinity).map(option => this.normalizeOption(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add
|
|
||||||
/**
|
|
||||||
* Mesage select menu
|
|
||||||
* @param {Message} message The message this select menu is for
|
|
||||||
* @param {Array<any>} values The values of the select menu
|
|
||||||
* @returns {Promise<InteractionResponse>}
|
|
||||||
*/
|
|
||||||
async select(message, values) {
|
|
||||||
if (!(message instanceof Message())) throw new Error('[UNKNOWN_MESSAGE] Please pass a valid Message');
|
|
||||||
if (!Array.isArray(values)) throw new TypeError('[INVALID_VALUES] Please pass an array of values');
|
|
||||||
if (!this.customId || this.disabled) {
|
|
||||||
throw new Error('[INVALID_MENU] Menu does not contain Id or has been disabled');
|
|
||||||
} // Disabled or null customID
|
|
||||||
if (values.length < this.minValues) {
|
|
||||||
throw new RangeError(`[SELECT_MENU_MIN_VALUES] The minimum number of values is ${this.minValues}`);
|
|
||||||
}
|
|
||||||
if (values.length > this.maxValues) {
|
|
||||||
throw new RangeError(`[SELECT_MENU_MAX_VALUES] The maximum number of values is ${this.maxValues}`);
|
|
||||||
}
|
|
||||||
const parseValues = value => {
|
|
||||||
switch (this.type) {
|
|
||||||
case 'SELECT_MENU':
|
|
||||||
case 'STRING_SELECT': {
|
|
||||||
if (typeof value !== 'string') throw new TypeError('[INVALID_VALUE] Please pass a string value');
|
|
||||||
const value_ = this.options.find(obj => obj.value === value || obj.label === value);
|
|
||||||
if (!value_) throw new Error('[INVALID_VALUE] Please pass a valid value');
|
|
||||||
return value_.value;
|
|
||||||
}
|
|
||||||
case 'USER_SELECT': {
|
|
||||||
const userId = this.client.users.resolveId(value);
|
|
||||||
if (!userId) throw new Error('[INVALID_VALUE] Please pass a valid user');
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
case 'ROLE_SELECT': {
|
|
||||||
const roleId = this.client.roles.resolveId(value);
|
|
||||||
if (!roleId) throw new Error('[INVALID_VALUE] Please pass a valid role');
|
|
||||||
return roleId;
|
|
||||||
}
|
|
||||||
case 'MENTIONABLE_SELECT': {
|
|
||||||
const mentionableId = this.client.users.resolveId(value) || this.client.roles.resolveId(value);
|
|
||||||
if (!mentionableId) throw new Error('[INVALID_VALUE] Please pass a valid mentionable');
|
|
||||||
return mentionableId;
|
|
||||||
}
|
|
||||||
case 'CHANNEL_SELECT': {
|
|
||||||
const channel = this.client.channels.resolve(value);
|
|
||||||
if (!channel) throw new Error('[INVALID_VALUE] Please pass a valid channel');
|
|
||||||
if (!this.channelTypes.includes(channel.type)) {
|
|
||||||
throw new Error(
|
|
||||||
`[INVALID_VALUE] Please pass a valid channel type (Got: ${channel.type}, allow: ${this.channelTypes.join(
|
|
||||||
', ',
|
|
||||||
)})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return channel.id;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
throw new Error(`[INVALID_TYPE] Please pass a valid select menu type (Got ${this.type})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const nonce = SnowflakeUtil.generate();
|
|
||||||
const data = {
|
|
||||||
type: InteractionTypes.MESSAGE_COMPONENT,
|
|
||||||
guild_id: message.guild?.id ?? null,
|
|
||||||
channel_id: message.channel.id,
|
|
||||||
message_id: message.id,
|
|
||||||
application_id: message.applicationId ?? message.author.id,
|
|
||||||
session_id: message.client.sessionId,
|
|
||||||
message_flags: message.flags.bitfield,
|
|
||||||
data: {
|
|
||||||
component_type: MessageComponentTypes[this.type],
|
|
||||||
custom_id: this.customId,
|
|
||||||
type: MessageComponentTypes[this.type],
|
|
||||||
values: values?.length ? values.map(parseValues) : [],
|
|
||||||
},
|
|
||||||
nonce,
|
|
||||||
};
|
|
||||||
|
|
||||||
await message.client.api.interactions.post({
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
message.client._interactionCache.set(nonce, {
|
|
||||||
channelId: message.channelId,
|
|
||||||
guildId: message.guildId,
|
|
||||||
metadata: data,
|
|
||||||
});
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const handler = data => {
|
|
||||||
timeout.refresh();
|
|
||||||
if (data.metadata?.nonce !== nonce) return;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
message.client.removeListener('interactionResponse', handler);
|
|
||||||
message.client.decrementMaxListeners();
|
|
||||||
if (data.status) {
|
|
||||||
resolve(data.metadata);
|
|
||||||
} else {
|
|
||||||
reject(
|
|
||||||
new Error('INTERACTION_ERROR', {
|
|
||||||
cause: data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
message.client.removeListener('interactionResponse', handler);
|
|
||||||
message.client.decrementMaxListeners();
|
|
||||||
reject(
|
|
||||||
new Error('INTERACTION_TIMEOUT', {
|
|
||||||
cause: data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}, message.client.options.interactionTimeout).unref();
|
|
||||||
message.client.incrementMaxListeners();
|
|
||||||
message.client.on('interactionResponse', handler);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = MessageSelectMenu;
|
module.exports = MessageSelectMenu;
|
||||||
|
@ -138,7 +138,7 @@ class Modal {
|
|||||||
data: postData,
|
data: postData,
|
||||||
});
|
});
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timeoutMs = 15_000;
|
const timeoutMs = 5_000;
|
||||||
// Waiting for MsgCreate / ModalCreate
|
// Waiting for MsgCreate / ModalCreate
|
||||||
const handler = data => {
|
const handler = data => {
|
||||||
if (data.nonce !== nonce) return;
|
if (data.nonce !== nonce) return;
|
||||||
|
@ -82,76 +82,6 @@ class TextInputComponent extends BaseMessageComponent {
|
|||||||
this.value = data.value ?? null;
|
this.value = data.value ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the custom id of this text input component
|
|
||||||
* @param {string} customId A unique string to be sent in the interaction when submitted
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setCustomId(customId) {
|
|
||||||
this.customId = Util.verifyString(customId, RangeError, 'TEXT_INPUT_CUSTOM_ID');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the label of this text input component
|
|
||||||
* @param {string} label The text to be displayed above this text input component
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setLabel(label) {
|
|
||||||
this.label = Util.verifyString(label, RangeError, 'TEXT_INPUT_LABEL');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the text input component to be required for modal submission
|
|
||||||
* @param {boolean} [required=true] Whether this text input component is required
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setRequired(required = true) {
|
|
||||||
this.required = required;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the maximum length of text input required in this text input component
|
|
||||||
* @param {number} maxLength Maximum length of text to be required
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setMaxLength(maxLength) {
|
|
||||||
this.maxLength = maxLength;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the minimum length of text input required in this text input component
|
|
||||||
* @param {number} minLength Minimum length of text to be required
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setMinLength(minLength) {
|
|
||||||
this.minLength = minLength;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the placeholder of this text input component
|
|
||||||
* @param {string} placeholder Custom placeholder text to display when no text is entered
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setPlaceholder(placeholder) {
|
|
||||||
this.placeholder = Util.verifyString(placeholder, RangeError, 'TEXT_INPUT_PLACEHOLDER');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the style of this text input component
|
|
||||||
* @param {TextInputStyleResolvable} style The style of this text input component
|
|
||||||
* @returns {TextInputComponent}
|
|
||||||
*/
|
|
||||||
setStyle(style) {
|
|
||||||
this.style = TextInputComponent.resolveStyle(style);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of this text input component
|
* Sets the value of this text input component
|
||||||
* @param {string} value Value of this text input component
|
* @param {string} value Value of this text input component
|
||||||
|
Loading…
Reference in New Issue
Block a user