feat(SelectMenu): SelectMenu v2

support channelType
This commit is contained in:
March 7th 2022-11-06 12:34:25 +07:00
parent 0975224da0
commit f671aa3899
4 changed files with 66 additions and 15 deletions

View File

@ -272,7 +272,13 @@ class Interaction extends Base {
isSelectMenu() { isSelectMenu() {
return ( return (
InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && 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])
); );
} }

View File

@ -2,7 +2,6 @@
const process = require('node:process'); const process = require('node:process');
const { Collection } = require('@discordjs/collection'); const { Collection } = require('@discordjs/collection');
// Disable: const { findBestMatch } = require('string-similarity'); // Not check similarity
const Base = require('./Base'); const Base = require('./Base');
const BaseMessageComponent = require('./BaseMessageComponent'); const BaseMessageComponent = require('./BaseMessageComponent');
const ClientApplication = require('./ClientApplication'); const ClientApplication = require('./ClientApplication');
@ -1074,13 +1073,9 @@ class Message extends Base {
for (const row of this.components) { for (const row of this.components) {
for (const component of row.components) { for (const component of row.components) {
if ( if (
[ ['STRING_SELECT', 'USER_SELECT', 'ROLE_SELECT', 'MENTIONABLE_SELECT', 'CHANNEL_SELECT'].includes(
'STRING_SELECT', component.type,
'USER_SELECT', )
'ROLE_SELECT',
'MENTIONABLE_SELECT',
'CHANNEL_SELECT',
].includes(component.type)
) { ) {
menuAll.push(component); menuAll.push(component);
} }

View File

@ -3,7 +3,7 @@
const { setTimeout } = require('node:timers'); const { setTimeout } = require('node:timers');
const BaseMessageComponent = require('./BaseMessageComponent'); const BaseMessageComponent = require('./BaseMessageComponent');
const { Message } = require('./Message'); const { Message } = require('./Message');
const { MessageComponentTypes, InteractionTypes } = require('../util/Constants'); const { MessageComponentTypes, InteractionTypes, ChannelTypes } = require('../util/Constants');
const SnowflakeUtil = require('../util/SnowflakeUtil'); const SnowflakeUtil = require('../util/SnowflakeUtil');
const Util = require('../util/Util'); const Util = require('../util/Util');
@ -75,7 +75,7 @@ class MessageSelectMenu extends BaseMessageComponent {
this.maxValues = data.max_values ?? data.maxValues ?? null; this.maxValues = data.max_values ?? data.maxValues ?? null;
/** /**
* Options for the select menu * Options for the STRING_SELECT menu
* @type {MessageSelectOption[]} * @type {MessageSelectOption[]}
*/ */
this.options = this.constructor.normalizeOptions(data.options ?? []); this.options = this.constructor.normalizeOptions(data.options ?? []);
@ -85,6 +85,15 @@ class MessageSelectMenu extends BaseMessageComponent {
* @type {boolean} * @type {boolean}
*/ */
this.disabled = data.disabled ?? false; 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; 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<ChannelType>');
}
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<ChannelType>');
}
this.channelTypes = channelTypes.map(channelType =>
typeof channelType === 'string' ? channelType : ChannelTypes[channelType],
);
return this;
}
/** /**
* Sets the custom id of this select menu * Sets the custom id of this select menu
* @param {string} customId A unique string to be sent in the interaction when clicked * @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, min_values: this.minValues,
max_values: this.maxValues ?? (this.minValues ? this.options.length : undefined), max_values: this.maxValues ?? (this.minValues ? this.options.length : undefined),
options: this.options, 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, type: typeof this.type === 'string' ? MessageComponentTypes[this.type] : this.type,
}; };
} }
@ -282,9 +322,16 @@ class MessageSelectMenu extends BaseMessageComponent {
return mentionableId; return mentionableId;
} }
case 'CHANNEL_SELECT': { case 'CHANNEL_SELECT': {
const channelId = this.client.channels.resolveId(value); const channel = this.client.channels.resolve(value);
if (!channelId) throw new Error('[INVALID_VALUE] Please pass a valid channel'); if (!channel) throw new Error('[INVALID_VALUE] Please pass a valid channel');
return channelId; 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: { default: {
throw new Error(`[INVALID_TYPE] Please pass a valid select menu type (Got ${this.type})`); throw new Error(`[INVALID_TYPE] Please pass a valid select menu type (Got ${this.type})`);

5
typings/index.d.ts vendored
View File

@ -2257,9 +2257,12 @@ export class MessageSelectMenu extends BaseMessageComponent {
public options: MessageSelectOption[]; public options: MessageSelectOption[];
public placeholder: string | null; public placeholder: string | null;
public type: SelectMenuTypes; public type: SelectMenuTypes;
public channelTypes: ChannelTypes[];
public addOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; public addOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this;
public setOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; public setOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this;
public setType(type: SelectMenuTypes): this; public setType(type: SelectMenuTypes): this;
public addChannelTypes(...channelTypes: ChannelTypes[]): this;
public setChannelTypes(...channelTypes: ChannelTypes[]): this;
public setCustomId(customId: string): this; public setCustomId(customId: string): this;
public setDisabled(disabled?: boolean): this; public setDisabled(disabled?: boolean): this;
public setMaxValues(maxValues: number): this; public setMaxValues(maxValues: number): this;
@ -6258,11 +6261,11 @@ export interface MessageReference {
export type MessageResolvable = Message | Snowflake; export type MessageResolvable = Message | Snowflake;
export interface MessageSelectMenuOptions extends BaseMessageComponentOptions { export interface MessageSelectMenuOptions extends BaseMessageComponentOptions {
type?: SelectMenuTypes;
customId?: string; customId?: string;
disabled?: boolean; disabled?: boolean;
maxValues?: number; maxValues?: number;
minValues?: number; minValues?: number;
options?: MessageSelectOptionData[];
placeholder?: string; placeholder?: string;
} }