Skip to content

Commit

Permalink
feat: make components automatically registered
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilloftheshadow committed Sep 4, 2024
1 parent a1ad01c commit 9e93027
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-dots-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@buape/carbon": patch
---

feat: make components automatically registered
1 change: 0 additions & 1 deletion apps/cloudo/src/commands/testing/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default class ButtonCommand extends Command {
name = "button"
description = "A simple command with a button!"
defer = true
components = [new PingButton(), new Link()]

async run(interaction: CommandInteraction) {
await interaction.reply({
Expand Down
7 changes: 0 additions & 7 deletions apps/cloudo/src/commands/testing/every_select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ export default class SelectCommand extends Command {
name = "every_select"
description = "Send every select menu"
defer = true
components = [
new StringSelect(),
new RoleSelect(),
new MentionableSelect(),
new ChannelSelect(),
new UserSelect()
]

async run(interaction: CommandInteraction) {
interaction.reply({
Expand Down
1 change: 0 additions & 1 deletion apps/rocko/src/commands/testing/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default class ButtonCommand extends Command {
name = "button"
description = "A simple command with a button!"
defer = true
components = [new PingButton(), new Link()]

async run(interaction: CommandInteraction) {
await interaction.reply({
Expand Down
22 changes: 8 additions & 14 deletions apps/rocko/src/commands/testing/every_select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,18 @@ export default class SelectCommand extends Command {
name = "every_select"
description = "Send every select menu"
defer = true
components = [
new StringSelect(),
new RoleSelect(),
new MentionableSelect(),
new ChannelSelect(),
new UserSelect()
]

async run(interaction: CommandInteraction) {
const row = new Row()
row.addComponent(new StringSelect())
row.addComponent(new RoleSelect())
row.addComponent(new MentionableSelect())
row.addComponent(new ChannelSelect())
row.addComponent(new UserSelect())

interaction.reply({
content: "Select menus! <:caughtIn4k:1145473115703496816>",
components: [
new Row([new StringSelect()]),
new Row([new RoleSelect()]),
new Row([new MentionableSelect()]),
new Row([new ChannelSelect()]),
new Row([new UserSelect()])
]
components: [row]
})
}
}
Expand Down
12 changes: 1 addition & 11 deletions packages/carbon/src/abstracts/BaseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import {
ApplicationCommandType,
type RESTPostAPIApplicationCommandsJSONBody
} from "discord-api-types/v10"
import {
ApplicationIntegrationType,
type BaseComponent,
InteractionContextType
} from "../index.js"
import { ApplicationIntegrationType, InteractionContextType } from "../index.js"

/**
* Represents the base data of a command that the user creates
Expand Down Expand Up @@ -50,12 +46,6 @@ export abstract class BaseCommand {
InteractionContextType.PrivateChannel
]

/**
* All the components that the command is able to use.
* You mount these here so the handler can access them
*/
components?: BaseComponent[] = []

/**
* All the paginators that the command is able to use.
* You mount these here so the handler can access them
Expand Down
20 changes: 17 additions & 3 deletions packages/carbon/src/abstracts/BaseInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export type InteractionReplyOptions = {
* The files to send in the interaction
*/
files?: InteractionFileData[]
/**
* Whether the interaction should be ephemeral
*/
ephemeral?: boolean
}

/**
Expand Down Expand Up @@ -80,12 +84,15 @@ export abstract class BaseInteraction<T extends APIInteraction> extends Base {
*/
_deferred = false

constructor(client: Client, data: T) {
private defaultEphemeral = false

constructor(client: Client, data: T, defaults: { ephemeral?: boolean } = {}) {
super(client)
this.rawData = data
this.type = data.type
this.userId =
this.rawData.user?.id || this.rawData.member?.user.id || undefined
if (defaults.ephemeral) this.defaultEphemeral = defaults.ephemeral
}

get message(): Message | null {
Expand Down Expand Up @@ -125,6 +132,11 @@ export abstract class BaseInteraction<T extends APIInteraction> extends Base {
data: InteractionReplyData,
options: InteractionReplyOptions = {}
) {
data.components?.map((row) => {
row.components.map((component) => {
this.client.componentHandler.registerComponent(component)
})
})
if (this._deferred) {
await this.client.rest.patch(
Routes.webhookMessage(
Expand All @@ -148,7 +160,8 @@ export abstract class BaseInteraction<T extends APIInteraction> extends Base {
type: InteractionResponseType.ChannelMessageWithSource,
data: {
...data,
components: data.components?.map((row) => row.serialize())
components: data.components?.map((row) => row.serialize()),
ephemeral: options.ephemeral ?? this.defaultEphemeral
}
},
files: options.files
Expand All @@ -169,7 +182,8 @@ export abstract class BaseInteraction<T extends APIInteraction> extends Base {
Routes.interactionCallback(this.rawData.id, this.rawData.token),
{
body: {
type: InteractionResponseType.DeferredChannelMessageWithSource
type: InteractionResponseType.DeferredChannelMessageWithSource,
ephemeral: this.defaultEphemeral
}
}
)
Expand Down
6 changes: 3 additions & 3 deletions packages/carbon/src/classes/Row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export class Row {
/**
* The components in the action row
*/
components: BaseComponent[]
components: BaseComponent[] = []

constructor(components: BaseComponent[]) {
this.components = components
constructor(components?: BaseComponent[]) {
if (components) this.components = components
}

/**
Expand Down
4 changes: 4 additions & 0 deletions packages/carbon/src/internals/CommandHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export class CommandHandler extends Base {

throw new Error("Command is not a valid command type")
}
/**
* Handle a command interaction
* @internal
*/
async handleCommandInteraction(
rawInteraction: APIApplicationCommandInteraction
) {
Expand Down
19 changes: 15 additions & 4 deletions packages/carbon/src/internals/ComponentHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,22 @@ import { StringSelectMenuInteraction } from "./StringSelectMenuInteraction.js"
import { UserSelectMenuInteraction } from "./UserSelectMenuInteraction.js"

export class ComponentHandler extends Base {
components: BaseComponent[] = []
/**
* Register a component with the handler
* @internal
*/
registerComponent(component: BaseComponent) {
if (!this.components.find((x) => x.customId === component.customId)) {
this.components.push(component)
}
}
/**
* Handle an interaction
* @internal
*/
async handleInteraction(data: APIMessageComponentInteraction) {
const allComponents = this.client.commands
.filter((x) => x.components && x.components.length > 0)
.flatMap((x) => x.components) as BaseComponent[]
const component = allComponents.find(
const component = this.components.find(
(x) =>
x.customId === data.data.custom_id &&
x.type === data.data.component_type
Expand Down

0 comments on commit 9e93027

Please sign in to comment.