From 75f263f88c9e9481fa72a0d2838d9453f5c05167 Mon Sep 17 00:00:00 2001 From: ION606 Date: Tue, 25 Apr 2023 17:34:01 -0400 Subject: [PATCH] Last 2023 Spring RCOS push --- structures/client/client.js | 3 +- structures/guilds/guild.js | 8 ++ structures/interactions/Modal.js | 83 +++++++++++++++++++- structures/interactions/createInteraction.js | 3 +- structures/interactions/interaction.js | 15 +++- tests/interactionTests.js | 17 ++++ 6 files changed, 125 insertions(+), 4 deletions(-) diff --git a/structures/client/client.js b/structures/client/client.js index ec4b717..820628b 100644 --- a/structures/client/client.js +++ b/structures/client/client.js @@ -162,7 +162,8 @@ export class Client extends EventEmitter { this.axiosCustom.interceptors.response.use((response) => { return response; }, function (err) { - throw `REQUEST FAILED WITH STATUS CODE ${err.response.status} AND REASON "${err.response.data.message}"`; + console.log(err.response.data); + throw `REQUEST FAILED WITH STATUS CODE ${err.response.status} AND REASON "${JSON.stringify(err.response.data)}"`; }); return new Promise((resolve, reject) => { diff --git a/structures/guilds/guild.js b/structures/guilds/guild.js index 1a429ae..755e752 100644 --- a/structures/guilds/guild.js +++ b/structures/guilds/guild.js @@ -8,6 +8,7 @@ import { GuildChannelManager } from './GuildChannelManager.js'; import { Channel } from './Channel.js'; import { ThreadManager } from './ThreadManager.js'; import { DataManager } from '../DataManager.js'; +// import { inspect } from 'util'; //See https://discord.com/developers/docs/resources/guild @@ -185,6 +186,7 @@ export default class Guild extends DataManager { } } + /** * @returns {Promise} */ @@ -200,6 +202,12 @@ export default class Guild extends DataManager { }); } + + // toString() { + // return inspect(this, false, 1); + // } + + /** * @param {Object} o * @param {String} token diff --git a/structures/interactions/Modal.js b/structures/interactions/Modal.js index 27bbacc..6e56637 100644 --- a/structures/interactions/Modal.js +++ b/structures/interactions/Modal.js @@ -1,9 +1,90 @@ import { Interaction } from "./interaction.js"; +/** @enum {number} */ +export const textInputStyle = Object.freeze({ + Short: 1, + paragraph: 2 +}); + +export class ModalComponent { + /** @type {String} */ + custom_id; + + /** @type {String} */ + label; + + /** @type {Boolean} */ + required; + + /** @type {number} */ + min_length; + + /** @type {number} */ + max_length; + + /** @type {textInputStyle} */ + style; + + /** @type {String} */ + value; + + /** @type {String} */ + placeholder; + + toObj() { + if (this.style != 1 && this.style != 2) throw `MODAL TEXT INPUT STYLE MUST BE 1 OR 2 BUT WAS '${this.style}'`; + const obj = {type: 4}; + for (const k in this) { + if (this[k]) obj[k] = this[k]; + } + return obj; + } + + constructor(obj) { + for (const k in this) { + if (obj[k] != undefined) { + this[k] = obj[k]; + } + } + } +} + export class Modal extends Interaction { + /** @type {String} */ + title; + + /** @type {String} */ + custom_id; + + /** @type {ModalComponent[]} */ + components; + + /** + * @param {ModalComponent} c + */ + addComponent(c) { + this.components.push(c); + } + + toObj() { + const obj = {title: this.title, custom_id: this.custom_id, components: []}; + for (const comp of this.components) { + obj.components.push(comp.toObj()); + } + return obj; + } + constructor(intRaw, client) { super(intRaw, client); - console.log(intRaw); + this.components = []; + + if (!intRaw) return; + + // [ { value: 'nnnnnnnnnnnnn', type: 4, custom_id: 'nonononononono' } ] + for (const opt of intRaw.data.components) { + //These are nested + // this.components.push(new ModalComponent()); + } } } \ No newline at end of file diff --git a/structures/interactions/createInteraction.js b/structures/interactions/createInteraction.js index b288259..587e59b 100644 --- a/structures/interactions/createInteraction.js +++ b/structures/interactions/createInteraction.js @@ -50,7 +50,8 @@ export function createInteraction(intRaw, client) { return createSelectMenu(intRaw, client); case interactionTypes.ModalSubmit: - return new Modal(intRaw, client); + return console.log("MODALS NOT FULLY IMPLEMENTED!"); + // return new Modal(intRaw, client); case interactionTypes.Ping: console.log("pong"); diff --git a/structures/interactions/interaction.js b/structures/interactions/interaction.js index caf94de..0957508 100644 --- a/structures/interactions/interaction.js +++ b/structures/interactions/interaction.js @@ -5,6 +5,8 @@ import { Channel } from '../guilds/Channel.js'; import {Embed} from '../messages/embed.js'; import Guild from '../guilds/Guild.js'; import { DataManager } from '../DataManager.js'; +import { Modal, ModalComponent } from './Modal.js'; +import { MessageActionRow } from '../messages/MessageActionRow.js'; class interactionOptions { @@ -21,7 +23,6 @@ class interactionOptions { focused; constructor(o) { - console.log(o); for (const k in this) { if (o[k]) this[k] = o[k]; } @@ -59,12 +60,22 @@ export class Interaction extends DataManager { /** @type {interactionOptions} */ data; + /** + * @param {Modal} m + */ + async #sendModal(m) { + const response = await this.client.axiosCustom.post(`/interactions/${this.id}/${this.#token}/callback`, {type: 9, data: m.toObj()}); + return response.data; + } /** * @param {{content: String, ephemeral?: Boolean, embeds: [Embed]} | String} inp * @returns {Promise} */ async reply(inp) { + //Check for action row + if (inp instanceof Modal) return await this.#sendModal(inp); + return new Promise(async (resolve, reject) => { const toSend = (typeof inp == 'string') ? inp : inp.content; @@ -173,7 +184,9 @@ export class Interaction extends DataManager { */ constructor(intRaw, client) { super(client); + Object.defineProperty(this, 'guild', { enumerable: false }); + if (!intRaw) return; this.#token = intRaw["token"]; for (const k in this) { diff --git a/tests/interactionTests.js b/tests/interactionTests.js index cbd0f24..2d1654f 100644 --- a/tests/interactionTests.js +++ b/tests/interactionTests.js @@ -1,11 +1,28 @@ import { interactionTypes } from '../structures/interactions/interactionTypes.js'; import { Interaction } from '../structures/types.js'; +import { Modal, ModalComponent } from '../structures/interactions/Modal.js'; +import { MessageActionRow } from '../structures/messages/MessageActionRow.js'; const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); /** @param {Interaction} interaction */ export default async (interaction) => { if (interaction.type == interactionTypes.ApplicationCommand) { console.log(interaction.data); + + const m = new Modal(null, interaction.client); + const c = new ModalComponent(); + c.custom_id = 'nonononononono'; + c.label = "hi"; + c.style = 1; + m.custom_id = "temp"; + m.title = "TITLE HERE"; + + const a = new MessageActionRow(); + a.addComponent(c); + m.addComponent(a); + interaction.reply(m); + return; + interaction.reply({content: "HELLO WORLD", ephemeral: true}); await delay(3000); interaction.update({content: "NOOOOOOOOOOOOOOOOOO"});