Skip to content

Commit c4f1c75

Browse files
authored
feat: general component improvements (#5787)
1 parent 0156f69 commit c4f1c75

18 files changed

Lines changed: 111 additions & 48 deletions
Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
'use strict';
22

3-
const { Events, InteractionTypes } = require('../../../util/Constants');
3+
const { Events, InteractionTypes, MessageComponentTypes } = require('../../../util/Constants');
44
const Structures = require('../../../util/Structures');
55

66
module.exports = (client, { d: data }) => {
7-
let interaction;
7+
let InteractionType;
88
switch (data.type) {
9-
case InteractionTypes.APPLICATION_COMMAND: {
10-
const CommandInteraction = Structures.get('CommandInteraction');
11-
interaction = new CommandInteraction(client, data);
9+
case InteractionTypes.APPLICATION_COMMAND:
10+
InteractionType = Structures.get('CommandInteraction');
1211
break;
13-
}
14-
case InteractionTypes.MESSAGE_COMPONENT: {
15-
const MessageComponentInteraction = Structures.get('MessageComponentInteraction');
16-
interaction = new MessageComponentInteraction(client, data);
12+
case InteractionTypes.MESSAGE_COMPONENT:
13+
switch (data.data.component_type) {
14+
case MessageComponentTypes.BUTTON:
15+
InteractionType = Structures.get('ButtonInteraction');
16+
break;
17+
default:
18+
client.emit(
19+
Events.DEBUG,
20+
`[INTERACTION] Received component interaction with unknown type: ${data.data.component_type}`,
21+
);
22+
return;
23+
}
1724
break;
18-
}
1925
default:
2026
client.emit(Events.DEBUG, `[INTERACTION] Received interaction with unknown type: ${data.type}`);
2127
return;
@@ -26,5 +32,5 @@ module.exports = (client, { d: data }) => {
2632
* @event Client#interaction
2733
* @param {Interaction} interaction The interaction which was created
2834
*/
29-
client.emit(Events.INTERACTION_CREATE, interaction);
35+
client.emit(Events.INTERACTION_CREATE, new InteractionType(client, data));
3036
};

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ module.exports = {
7070
BaseGuildEmoji: require('./structures/BaseGuildEmoji'),
7171
BaseGuildVoiceChannel: require('./structures/BaseGuildVoiceChannel'),
7272
BaseMessageComponent: require('./structures/BaseMessageComponent'),
73+
ButtonInteraction: require('./structures/ButtonInteraction'),
7374
CategoryChannel: require('./structures/CategoryChannel'),
7475
Channel: require('./structures/Channel'),
7576
ClientApplication: require('./structures/ClientApplication'),

src/structures/APIMessage.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const BaseMessageComponent = require('./BaseMessageComponent');
44
const MessageEmbed = require('./MessageEmbed');
55
const { RangeError } = require('../errors');
6+
const { MessageComponentTypes } = require('../util/Constants');
67
const DataResolver = require('../util/DataResolver');
78
const MessageFlags = require('../util/MessageFlags');
89
const Util = require('../util/Util');
@@ -152,7 +153,11 @@ class APIMessage {
152153
}
153154
const embeds = embedLikes.map(e => new MessageEmbed(e).toJSON());
154155

155-
const components = this.options.components?.map(c => BaseMessageComponent.create(c).toJSON());
156+
const components = this.options.components?.map(c =>
157+
BaseMessageComponent.create(
158+
Array.isArray(c) ? { type: MessageComponentTypes.ACTION_ROW, components: c } : c,
159+
).toJSON(),
160+
);
156161

157162
let username;
158163
let avatarURL;

src/structures/BaseMessageComponent.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ class BaseMessageComponent {
2222
*/
2323

2424
/**
25-
* Components that can be sent in a message
25+
* Components that can be sent in a message. This can be:
26+
* * MessageActionRow
27+
* * MessageButton
2628
* @typedef {MessageActionRow|MessageButton} MessageComponent
2729
*/
2830

2931
/**
3032
* Data that can be resolved to a MessageComponentType. This can be:
31-
* * {@link MessageComponentType}
33+
* * MessageComponentType
3234
* * string
3335
* * number
3436
* @typedef {string|number|MessageComponentType} MessageComponentTypeResolvable
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
const MessageComponentInteraction = require('./MessageComponentInteraction');
4+
5+
/**
6+
* Represents a button interaction.
7+
* @exxtends {MessageComponentInteraction}
8+
*/
9+
class ButtonInteraction extends MessageComponentInteraction {}
10+
11+
module.exports = ButtonInteraction;

src/structures/Emoji.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
const Base = require('./Base');
44
const SnowflakeUtil = require('../util/SnowflakeUtil');
55

6+
/**
7+
* Represents raw emoji data from the API
8+
* @typedef {Object} RawEmoji
9+
* @property {?Snowflake} id ID of this emoji
10+
* @property {?string} name Name of this emoji
11+
* @property {?boolean} animated Whether this emoji is animated
12+
*/
13+
614
/**
715
* Represents an emoji, see {@link GuildEmoji} and {@link ReactionEmoji}.
816
* @extends {Base}

src/structures/Interaction.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ class Interaction extends Base {
120120
isMessageComponent() {
121121
return InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT;
122122
}
123+
124+
/**
125+
* Indicates whether this interaction is a button interaction.
126+
* @returns {boolean}
127+
*/
128+
isButton() {
129+
return InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && this.componentType === 'BUTTON';
130+
}
123131
}
124132

125133
module.exports = Interaction;

src/structures/Message.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ class Message extends Base {
538538
* @property {MessageAttachment[]} [attachments] An array of attachments to keep,
539539
* all attachments will be kept if omitted
540540
* @property {FileOptions[]|BufferResolvable[]|MessageAttachment[]} [files] Files to add to the message
541-
* @property {MessageActionRow[]} [components] Action rows containing interactive components for the message
542-
* (buttons, select menus)
541+
* @property {MessageActionRow[]|MessageActionRowOptions[]|MessageActionRowComponentResolvable[][]} [components]
542+
* Action rows containing interactive components for the message (buttons, select menus)
543543
*/
544544

545545
/**

src/structures/MessageActionRow.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@ const BaseMessageComponent = require('./BaseMessageComponent');
44
const { MessageComponentTypes } = require('../util/Constants');
55

66
/**
7-
* Represents an ActionRow containing message components.
7+
* Represents an action row containing message components.
88
* @extends {BaseMessageComponent}
99
*/
1010
class MessageActionRow extends BaseMessageComponent {
1111
/**
12-
* Components that can be placed in a MessageActionRow
12+
* Components that can be placed in an action row
1313
* * MessageButton
1414
* @typedef {MessageButton} MessageActionRowComponent
1515
*/
1616

1717
/**
18-
* Options for components that can be placed in a MessageActionRow
18+
* Options for components that can be placed in an action row
1919
* * MessageButtonOptions
2020
* @typedef {MessageButtonOptions} MessageActionRowComponentOptions
2121
*/
2222

2323
/**
24-
* Data that can be resolved into a components that can be placed in a MessageActionRow
24+
* Data that can be resolved into a components that can be placed in an action row
2525
* * MessageActionRowComponent
2626
* * MessageActionRowComponentOptions
2727
* @typedef {MessageActionRowComponent|MessageActionRowComponentOptions} MessageActionRowComponentResolvable
@@ -30,7 +30,7 @@ class MessageActionRow extends BaseMessageComponent {
3030
/**
3131
* @typedef {BaseMessageComponentOptions} MessageActionRowOptions
3232
* @property {MessageActionRowComponentResolvable[]} [components]
33-
* The components to place in this ActionRow
33+
* The components to place in this action row
3434
*/
3535

3636
/**
@@ -40,14 +40,14 @@ class MessageActionRow extends BaseMessageComponent {
4040
super({ type: 'ACTION_ROW' });
4141

4242
/**
43-
* The components in this MessageActionRow
43+
* The components in this action row
4444
* @type {MessageActionRowComponent[]}
4545
*/
4646
this.components = (data.components ?? []).map(c => BaseMessageComponent.create(c, null, true));
4747
}
4848

4949
/**
50-
* Adds components to the row.
50+
* Adds components to the action row.
5151
* @param {...MessageActionRowComponentResolvable[]} components The components to add
5252
* @returns {MessageActionRow}
5353
*/

src/structures/MessageButton.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const { MessageButtonStyles, MessageComponentTypes } = require('../util/Constant
66
const Util = require('../util/Util');
77

88
/**
9-
* Represents a Button message component.
9+
* Represents a button message component.
1010
* @extends {BaseMessageComponent}
1111
*/
1212
class MessageButton extends BaseMessageComponent {
@@ -15,7 +15,7 @@ class MessageButton extends BaseMessageComponent {
1515
* @property {string} [label] The text to be displayed on this button
1616
* @property {string} [customID] A unique string to be sent in the interaction when clicked
1717
* @property {MessageButtonStyleResolvable} [style] The style of this button
18-
* @property {Emoji} [emoji] The emoji to be displayed to the left of the text
18+
* @property {EmojiIdentifierResolvable} [emoji] The emoji to be displayed to the left of the text
1919
* @property {string} [url] Optional URL for link-style buttons
2020
* @property {boolean} [disabled=false] Disables the button to prevent interactions
2121
*/
@@ -50,9 +50,9 @@ class MessageButton extends BaseMessageComponent {
5050

5151
/**
5252
* Emoji for this button
53-
* @type {?Emoji|string}
53+
* @type {?RawEmoji}
5454
*/
55-
this.emoji = data.emoji ?? null;
55+
this.emoji = data.emoji ? Util.resolvePartialEmoji(data.emoji) : null;
5656

5757
/**
5858
* The URL this button links to, if it is a Link style button
@@ -93,8 +93,7 @@ class MessageButton extends BaseMessageComponent {
9393
* @returns {MessageButton}
9494
*/
9595
setEmoji(emoji) {
96-
if (/^\d{17,19}$/.test(emoji)) this.emoji = { id: emoji };
97-
else this.emoji = Util.parseEmoji(`${emoji}`);
96+
this.emoji = Util.resolvePartialEmoji(emoji);
9897
return this;
9998
}
10099

@@ -119,7 +118,8 @@ class MessageButton extends BaseMessageComponent {
119118
}
120119

121120
/**
122-
* Sets the URL of this button. MessageButton#style should be LINK
121+
* Sets the URL of this button.
122+
* <note>MessageButton#style must be LINK when setting a URL</note>
123123
* @param {string} url The URL of this button
124124
* @returns {MessageButton}
125125
*/
@@ -146,14 +146,14 @@ class MessageButton extends BaseMessageComponent {
146146

147147
/**
148148
* Data that can be resolved to a MessageButtonStyle. This can be
149-
* * {@link MessageButtonStyle}
149+
* * MessageButtonStyle
150150
* * string
151151
* * number
152152
* @typedef {string|number|MessageButtonStyle} MessageButtonStyleResolvable
153153
*/
154154

155155
/**
156-
* Resolves the style of a MessageButton
156+
* Resolves the style of a button
157157
* @param {MessageButtonStyleResolvable} style The style to resolve
158158
* @returns {MessageButtonStyle}
159159
* @private

0 commit comments

Comments
 (0)