From f671aa38994080b2e44531a054093a64d5a722c7 Mon Sep 17 00:00:00 2001 From: March 7th <71698422+aiko-chan-ai@users.noreply.github.com> Date: Sun, 6 Nov 2022 12:34:25 +0700 Subject: [PATCH] feat(SelectMenu): SelectMenu v2 support channelType --- src/structures/Interaction.js | 8 +++- src/structures/Message.js | 11 ++---- src/structures/MessageSelectMenu.js | 57 ++++++++++++++++++++++++++--- typings/index.d.ts | 5 ++- 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/structures/Interaction.js b/src/structures/Interaction.js index 393fb60..c79dc3f 100644 --- a/src/structures/Interaction.js +++ b/src/structures/Interaction.js @@ -272,7 +272,13 @@ class Interaction extends Base { isSelectMenu() { return ( InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && - MessageComponentTypes[this.componentType] === MessageComponentTypes.SELECT_MENU + [ + MessageComponentTypes.STRING_SELECT, + MessageComponentTypes.USER_SELECT, + MessageComponentTypes.ROLE_SELECT, + MessageComponentTypes.MENTIONABLE_SELECT, + MessageComponentTypes.CHANNEL_SELECT, + ].includes(MessageComponentTypes[this.componentType]) ); } diff --git a/src/structures/Message.js b/src/structures/Message.js index c1bedc1..0c1d9ea 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -2,7 +2,6 @@ const process = require('node:process'); const { Collection } = require('@discordjs/collection'); -// Disable: const { findBestMatch } = require('string-similarity'); // Not check similarity const Base = require('./Base'); const BaseMessageComponent = require('./BaseMessageComponent'); const ClientApplication = require('./ClientApplication'); @@ -1074,13 +1073,9 @@ class Message extends Base { for (const row of this.components) { for (const component of row.components) { if ( - [ - 'STRING_SELECT', - 'USER_SELECT', - 'ROLE_SELECT', - 'MENTIONABLE_SELECT', - 'CHANNEL_SELECT', - ].includes(component.type) + ['STRING_SELECT', 'USER_SELECT', 'ROLE_SELECT', 'MENTIONABLE_SELECT', 'CHANNEL_SELECT'].includes( + component.type, + ) ) { menuAll.push(component); } diff --git a/src/structures/MessageSelectMenu.js b/src/structures/MessageSelectMenu.js index e617e89..ea3e851 100644 --- a/src/structures/MessageSelectMenu.js +++ b/src/structures/MessageSelectMenu.js @@ -3,7 +3,7 @@ const { setTimeout } = require('node:timers'); const BaseMessageComponent = require('./BaseMessageComponent'); const { Message } = require('./Message'); -const { MessageComponentTypes, InteractionTypes } = require('../util/Constants'); +const { MessageComponentTypes, InteractionTypes, ChannelTypes } = require('../util/Constants'); const SnowflakeUtil = require('../util/SnowflakeUtil'); const Util = require('../util/Util'); @@ -75,7 +75,7 @@ class MessageSelectMenu extends BaseMessageComponent { this.maxValues = data.max_values ?? data.maxValues ?? null; /** - * Options for the select menu + * Options for the STRING_SELECT menu * @type {MessageSelectOption[]} */ this.options = this.constructor.normalizeOptions(data.options ?? []); @@ -85,6 +85,15 @@ class MessageSelectMenu extends BaseMessageComponent { * @type {boolean} */ this.disabled = data.disabled ?? false; + + /** + * Channels that are possible to select in CHANNEL_SELECT menu + * @type {ChannelType[]} + */ + this.channelTypes = + data.channel_types?.map(channelType => + typeof channelType === 'string' ? channelType : ChannelTypes[channelType], + ) ?? []; } /** @@ -109,6 +118,36 @@ class MessageSelectMenu extends BaseMessageComponent { return this; } + /** + * Adds the channel type to the select menu + * @param {...ChannelType[]} channelType Added channel type + * @returns {MessageSelectMenu} + */ + addChannelTypes(...channelTypes) { + if (!channelTypes.every(channelType => ChannelTypes[channelType])) { + throw new TypeError('INVALID_TYPE', 'channelTypes', 'Array'); + } + 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', 'Array'); + } + 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 @@ -204,6 +243,7 @@ class MessageSelectMenu extends BaseMessageComponent { min_values: this.minValues, max_values: this.maxValues ?? (this.minValues ? this.options.length : undefined), options: this.options, + channel_types: this.channelTypes.map(type => (typeof type === 'string' ? ChannelTypes[type] : type)), type: typeof this.type === 'string' ? MessageComponentTypes[this.type] : this.type, }; } @@ -282,9 +322,16 @@ class MessageSelectMenu extends BaseMessageComponent { return mentionableId; } case 'CHANNEL_SELECT': { - const channelId = this.client.channels.resolveId(value); - if (!channelId) throw new Error('[INVALID_VALUE] Please pass a valid channel'); - return channelId; + 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})`); diff --git a/typings/index.d.ts b/typings/index.d.ts index efc9e3e..a836a99 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2257,9 +2257,12 @@ export class MessageSelectMenu extends BaseMessageComponent { public options: MessageSelectOption[]; public placeholder: string | null; public type: SelectMenuTypes; + public channelTypes: ChannelTypes[]; public addOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; public setOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; public setType(type: SelectMenuTypes): this; + public addChannelTypes(...channelTypes: ChannelTypes[]): this; + public setChannelTypes(...channelTypes: ChannelTypes[]): this; public setCustomId(customId: string): this; public setDisabled(disabled?: boolean): this; public setMaxValues(maxValues: number): this; @@ -6258,11 +6261,11 @@ export interface MessageReference { export type MessageResolvable = Message | Snowflake; export interface MessageSelectMenuOptions extends BaseMessageComponentOptions { + type?: SelectMenuTypes; customId?: string; disabled?: boolean; maxValues?: number; minValues?: number; - options?: MessageSelectOptionData[]; placeholder?: string; }