From c9ff3cc83ea2a105a1aa4bc5b2b0290b4e86f307 Mon Sep 17 00:00:00 2001 From: cirroskais Date: Tue, 5 Mar 2024 23:07:54 -0500 Subject: [PATCH] Modal handler :D --- src/interactions/ping.ts | 43 ++++++++++++--------- src/lib/handlers/InteractionHandler.ts | 9 +---- src/lib/handlers/ModalHandler.ts | 52 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 24 deletions(-) diff --git a/src/interactions/ping.ts b/src/interactions/ping.ts index f335c0c..799c563 100644 --- a/src/interactions/ping.ts +++ b/src/interactions/ping.ts @@ -1,7 +1,8 @@ import type { Command } from "../lib/types/command"; -import { MessageComponentTypes, TextStyles } from "@discordeno/bot"; +import { MessageComponentTypes, TextStyles, type Interaction } from "@discordeno/bot"; import SlashCommand from "../lib/classes/SlashCommand"; import Modal from "../lib/classes/Modal"; +import { collectModal } from "../lib/handlers/ModalHandler"; export default class extends SlashCommand implements Command { static name = "ping"; @@ -13,21 +14,29 @@ export default class extends SlashCommand implements Command { } async run() { - return new Modal() - .setTitle("dope") - .setId("dope") - .setComponents([ - { - type: MessageComponentTypes.ActionRow, - components: [ - { - type: MessageComponentTypes.InputText, - customId: "dope", - style: TextStyles.Short, - label: "dope", - }, - ], - }, - ]); + const modal = new Modal().setTitle("dope").setComponents([ + { + type: MessageComponentTypes.ActionRow, + components: [ + { + type: MessageComponentTypes.InputText, + customId: "dope", + style: TextStyles.Short, + label: "dope", + }, + ], + }, + ]); + + collectModal(modal) + .then(({ interaction, values }) => { + if (!interaction.data?.components) return; + interaction.respond("dope: " + values.get("dope")); + }) + .catch((_) => { + //whatever bro dont respond to my modal 🙄 + }); + + return modal; } } diff --git a/src/lib/handlers/InteractionHandler.ts b/src/lib/handlers/InteractionHandler.ts index def67af..776422a 100644 --- a/src/lib/handlers/InteractionHandler.ts +++ b/src/lib/handlers/InteractionHandler.ts @@ -3,6 +3,7 @@ import { readdir } from "node:fs/promises"; import REST from "./RESTHandler"; import * as CommandHandler from "./CommandHandler"; +import * as ModalHandler from "./ModalHandler"; export const interactions = new Map(); @@ -39,12 +40,6 @@ export function handle(interaction: Interaction) { }, }); } else if (type == InteractionTypes.ModalSubmit) { - REST.sendInteractionResponse(interaction.id, interaction.token, { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: "Not Implemented", - flags: 64, - }, - }); + ModalHandler.handle(interaction); } } diff --git a/src/lib/handlers/ModalHandler.ts b/src/lib/handlers/ModalHandler.ts index e69de29..a53d862 100644 --- a/src/lib/handlers/ModalHandler.ts +++ b/src/lib/handlers/ModalHandler.ts @@ -0,0 +1,52 @@ +import { randomUUID } from "node:crypto"; +import Modal from "../classes/Modal"; +import { InteractionResponseTypes, type Interaction, type Component } from "@discordeno/bot"; +import REST from "./RESTHandler"; + +const modals = new Map(); + +type ModalResponse = { + interaction: Interaction; + values: Map; +}; + +function getModalValues(interaction: Interaction): Map { + const values = new Map(); + if (!interaction.data?.components) return values; + + const actionRow: Component = interaction.data?.components[0]; + if (actionRow.components?.length) { + actionRow.components.forEach((value, index) => { + values.set(value.customId, value.value); + }); + } + + return values; +} + +export function collectModal(modal: Modal): Promise { + return new Promise((resolve, reject) => { + const id = randomUUID(); + modal.setId(id); + modals.set(id, resolve); + + setTimeout(() => reject(new Error("Modal timeout")), 1000 * 30); //, 1000 * 60 * 30); + }); +} + +export function handle(interaction: Interaction) { + if (!interaction.data) return; + const { customId } = interaction.data; + + const modal = modals.get(customId); + if (!modal) + return REST.sendInteractionResponse(interaction.id, interaction.token, { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + content: "Internal Error: MODAL_NOT_FOUND", + flags: 64, + }, + }); + + return modal({ interaction, values: getModalValues(interaction) }); +}