Compare commits
2 Commits
c76680293e
...
dafa81e2a6
| Author | SHA1 | Date | |
|---|---|---|---|
| dafa81e2a6 | |||
| 9e94e99874 |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1,300 @@
|
|||||||
|
const {
|
||||||
|
SlashCommandBuilder,
|
||||||
|
ModalBuilder,
|
||||||
|
TextInputBuilder,
|
||||||
|
TextInputStyle,
|
||||||
|
ActionRowBuilder
|
||||||
|
} = require("discord.js");
|
||||||
|
|
||||||
|
const { ObjectId } = require("mongodb");
|
||||||
|
const { mClient } = require("../..");
|
||||||
|
|
||||||
|
|
||||||
|
const DATABASE = "neo-db";
|
||||||
|
const DUTY_COLLECTION = "items_duties";
|
||||||
|
|
||||||
|
|
||||||
|
const RAID_TYPES = [
|
||||||
|
"Trial",
|
||||||
|
"Raid",
|
||||||
|
"AllianceRaid"
|
||||||
|
];
|
||||||
|
|
||||||
|
const RAID_DIFFICULTIES = [
|
||||||
|
"Extreme",
|
||||||
|
"Unreal",
|
||||||
|
"Savage",
|
||||||
|
"Ultimate",
|
||||||
|
"Chaotic"
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("raid")
|
||||||
|
.setDescription("Raid planning commands.")
|
||||||
|
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName("plan")
|
||||||
|
.setDescription("Create a new raid event.")
|
||||||
|
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName("duty")
|
||||||
|
.setDescription("Select the duty you want to run.")
|
||||||
|
.setRequired(true)
|
||||||
|
.setAutocomplete(true)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
switch (interaction.options.getSubcommand()) {
|
||||||
|
case "plan":
|
||||||
|
return planRaid(interaction);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
async autocomplete(interaction) {
|
||||||
|
return autocompleteDuty(interaction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
async function autocompleteDuty(interaction) {
|
||||||
|
const focused =
|
||||||
|
interaction.options.getFocused();
|
||||||
|
|
||||||
|
const collection = mClient
|
||||||
|
.db(DATABASE)
|
||||||
|
.collection(DUTY_COLLECTION);
|
||||||
|
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
Type: {
|
||||||
|
$in: RAID_TYPES
|
||||||
|
},
|
||||||
|
|
||||||
|
Difficulty: {
|
||||||
|
$in: RAID_DIFFICULTIES
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (focused) {
|
||||||
|
query.Name = {
|
||||||
|
$regex: escapeRegex(focused),
|
||||||
|
$options: "i"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const duties = await collection
|
||||||
|
.find(query)
|
||||||
|
.sort({
|
||||||
|
Name: 1
|
||||||
|
})
|
||||||
|
.limit(25)
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
|
||||||
|
return interaction.respond(
|
||||||
|
duties.map(duty => ({
|
||||||
|
name: buildAutocompleteName(duty),
|
||||||
|
value: duty._id.toString()
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function planRaid(interaction) {
|
||||||
|
const dutyId =
|
||||||
|
interaction.options.getString(
|
||||||
|
"duty",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!ObjectId.isValid(dutyId)) {
|
||||||
|
return interaction.reply({
|
||||||
|
content:
|
||||||
|
"Please select a duty from the autocomplete results.",
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const collection = mClient
|
||||||
|
.db(DATABASE)
|
||||||
|
.collection(DUTY_COLLECTION);
|
||||||
|
|
||||||
|
|
||||||
|
const duty = await collection.findOne({
|
||||||
|
_id: new ObjectId(dutyId),
|
||||||
|
|
||||||
|
Type: {
|
||||||
|
$in: RAID_TYPES
|
||||||
|
},
|
||||||
|
|
||||||
|
Difficulty: {
|
||||||
|
$in: RAID_DIFFICULTIES
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (!duty) {
|
||||||
|
return interaction.reply({
|
||||||
|
content:
|
||||||
|
"That duty could not be found or is not eligible for raid planning.",
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The duty ObjectId is embedded in the modal customId.
|
||||||
|
*
|
||||||
|
* The modal handler can then retrieve the selected duty
|
||||||
|
* without trusting editable modal input.
|
||||||
|
*/
|
||||||
|
const modal =
|
||||||
|
buildRaidModal(duty);
|
||||||
|
|
||||||
|
|
||||||
|
return interaction.showModal(modal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function buildRaidModal(duty) {
|
||||||
|
const modal =
|
||||||
|
new ModalBuilder()
|
||||||
|
.setCustomId(
|
||||||
|
`raidPlan:${duty._id}`
|
||||||
|
)
|
||||||
|
.setTitle(
|
||||||
|
"Shaiwase Raid Planner"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const nameInput =
|
||||||
|
new TextInputBuilder()
|
||||||
|
.setCustomId("raid-name")
|
||||||
|
.setLabel("Name")
|
||||||
|
.setPlaceholder(
|
||||||
|
"Friday Savage Prog"
|
||||||
|
)
|
||||||
|
.setStyle(
|
||||||
|
TextInputStyle.Short
|
||||||
|
)
|
||||||
|
.setMinLength(1)
|
||||||
|
.setMaxLength(100)
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
|
||||||
|
const descriptionInput =
|
||||||
|
new TextInputBuilder()
|
||||||
|
.setCustomId(
|
||||||
|
"raid-description"
|
||||||
|
)
|
||||||
|
.setLabel("Description")
|
||||||
|
.setPlaceholder(
|
||||||
|
"What are we doing? Any requirements?"
|
||||||
|
)
|
||||||
|
.setStyle(
|
||||||
|
TextInputStyle.Paragraph
|
||||||
|
)
|
||||||
|
.setMaxLength(1000)
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display only.
|
||||||
|
*
|
||||||
|
* We don't use this field to identify the duty.
|
||||||
|
* The ObjectId in the modal customId is authoritative.
|
||||||
|
*/
|
||||||
|
const dutyInput =
|
||||||
|
new TextInputBuilder()
|
||||||
|
.setCustomId("raid-duty")
|
||||||
|
.setLabel("Duty")
|
||||||
|
.setValue(duty.Name)
|
||||||
|
.setStyle(
|
||||||
|
TextInputStyle.Short
|
||||||
|
)
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
|
||||||
|
const dateInput =
|
||||||
|
new TextInputBuilder()
|
||||||
|
.setCustomId("raid-date")
|
||||||
|
.setLabel("Date")
|
||||||
|
.setPlaceholder("DD-MM-YYYY")
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setMinLength(10)
|
||||||
|
.setMaxLength(10)
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
|
||||||
|
const timeInput =
|
||||||
|
new TextInputBuilder()
|
||||||
|
.setCustomId("raid-time")
|
||||||
|
.setLabel("Start - End (24h clock)")
|
||||||
|
.setPlaceholder("20:00 - 23:00")
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setMinLength(13)
|
||||||
|
.setMaxLength(13)
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
|
||||||
|
modal.addComponents(
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(nameInput),
|
||||||
|
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(descriptionInput),
|
||||||
|
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(dutyInput),
|
||||||
|
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(dateInput),
|
||||||
|
|
||||||
|
new ActionRowBuilder()
|
||||||
|
.addComponents(timeInput)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return modal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function buildAutocompleteName(duty) {
|
||||||
|
const label =
|
||||||
|
`${duty.Name} — ${formatDutyType(duty.Type)} / ${duty.Difficulty}`;
|
||||||
|
|
||||||
|
return label.slice(
|
||||||
|
0,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function formatDutyType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case "AllianceRaid":
|
||||||
|
return "Alliance Raid";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function escapeRegex(value) {
|
||||||
|
return value.replace(
|
||||||
|
/[.*+?^${}()|[\]\\]/g,
|
||||||
|
"\\$&"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,97 +1,267 @@
|
|||||||
const { Events, MessageFlags, Message } = require('discord.js')
|
const {
|
||||||
const { mClient } = require('../index')
|
Events,
|
||||||
require('dotenv').config()
|
MessageFlags
|
||||||
|
} = require("discord.js");
|
||||||
|
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: Events.InteractionCreate,
|
name: Events.InteractionCreate,
|
||||||
once: false,
|
once: false,
|
||||||
async execute(interaction) {
|
|
||||||
if (interaction.isChatInputCommand()) { commandHandler(interaction) }
|
|
||||||
if (interaction.isButton()) { buttonHandler(interaction) }
|
|
||||||
if (interaction.isMentionableSelectMenu()) { selectMenuHandler(interaction) }
|
|
||||||
if (interaction.isUserSelectMenu()) { selectMenuHandler(interaction) }
|
|
||||||
if (interaction.isModalSubmit()) { modalHandler(interaction) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function commandHandler(interaction) {
|
|
||||||
const command = interaction.client.commands.get(interaction.commandName);
|
|
||||||
|
|
||||||
if (!command) { return console.error(`No command matching ${interaction.commandName} was found.`) }
|
async execute(interaction) {
|
||||||
|
if (interaction.isAutocomplete()) {
|
||||||
|
return autocompleteHandler(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
return commandHandler(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isButton()) {
|
||||||
|
return buttonHandler(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
interaction.isMentionableSelectMenu() ||
|
||||||
|
interaction.isUserSelectMenu()
|
||||||
|
) {
|
||||||
|
return selectMenuHandler(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isModalSubmit()) {
|
||||||
|
return modalHandler(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
async function autocompleteHandler(interaction) {
|
||||||
|
const command =
|
||||||
|
interaction.client.commands.get(
|
||||||
|
interaction.commandName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
return console.error(
|
||||||
|
`No command matching ${interaction.commandName} was found.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof command.autocomplete !==
|
||||||
|
"function"
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await command.execute(interaction);
|
await command.autocomplete(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
`Autocomplete error for /${interaction.commandName}:`,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Autocomplete cannot use normal interaction.reply().
|
||||||
|
* If something failed, send an empty set so Discord
|
||||||
|
* stops waiting.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
await interaction.respond([]);
|
||||||
|
} catch {
|
||||||
|
// Interaction may already be acknowledged or expired.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function commandHandler(interaction) {
|
||||||
|
const command =
|
||||||
|
interaction.client.commands.get(
|
||||||
|
interaction.commandName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
return console.error(
|
||||||
|
`No command matching ${interaction.commandName} was found.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
await command.execute(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (interaction.replied || interaction.deferred) {
|
|
||||||
|
if (
|
||||||
|
interaction.replied ||
|
||||||
|
interaction.deferred
|
||||||
|
) {
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this command!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this command!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function buttonHandler(interaction) {
|
async function buttonHandler(interaction) {
|
||||||
const button = interaction.client.buttons.get(interaction.customId)
|
const button =
|
||||||
if (!button) { return console.error(`No button registered matching ${interaction.customId}.`) }
|
interaction.client.buttons.get(
|
||||||
|
interaction.customId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!button) {
|
||||||
|
return console.error(
|
||||||
|
`No button registered matching ${interaction.customId}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await button.execute(interaction);
|
await button.execute(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (interaction.replied || interaction.deferred) {
|
|
||||||
|
if (
|
||||||
|
interaction.replied ||
|
||||||
|
interaction.deferred
|
||||||
|
) {
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this button!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this button!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function selectMenuHandler(interaction) {
|
async function selectMenuHandler(interaction) {
|
||||||
const selectMenu = interaction.client.selectMenus.get(interaction.customId)
|
const selectMenu =
|
||||||
if (!selectMenu) { return console.error(`No Select Menu registered matching ${interaction.customId}.`) }
|
interaction.client.selectMenus.get(
|
||||||
|
interaction.customId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!selectMenu) {
|
||||||
|
return console.error(
|
||||||
|
`No Select Menu registered matching ${interaction.customId}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await selectMenu.execute(interaction);
|
await selectMenu.execute(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (interaction.replied || interaction.deferred) {
|
|
||||||
|
if (
|
||||||
|
interaction.replied ||
|
||||||
|
interaction.deferred
|
||||||
|
) {
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this select menu!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: 'There was an error while executing this command!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this select menu!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function modalHandler(interaction) {
|
async function modalHandler(interaction) {
|
||||||
const modal = interaction.client.modals.get(interaction.customId);
|
const baseCustomId =
|
||||||
if (!modal) { return console.error(`No Modal registered matching ${interaction.customId}.`); }
|
interaction.customId.split(":")[0];
|
||||||
|
|
||||||
|
const modal =
|
||||||
|
interaction.client.modals.get(
|
||||||
|
baseCustomId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (!modal) {
|
||||||
|
return console.error(
|
||||||
|
`No Modal registered matching ${interaction.customId}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await modal.execute(interaction);
|
await modal.execute(
|
||||||
|
interaction
|
||||||
|
);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
||||||
if (interaction.replied || interaction.deferred) {
|
if (
|
||||||
|
interaction.replied ||
|
||||||
|
interaction.deferred
|
||||||
|
) {
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: 'There was an error while executing this modal!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this modal!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: 'There was an error while executing this modal!',
|
content:
|
||||||
flags: MessageFlags.Ephemeral
|
"There was an error while executing this modal!",
|
||||||
|
flags:
|
||||||
|
MessageFlags.Ephemeral
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
const fs = require("node:fs");
|
||||||
|
const path = require("node:path");
|
||||||
|
|
||||||
|
module.exports = (client) => {
|
||||||
|
const modalsPath = path.join(
|
||||||
|
__dirname,
|
||||||
|
"../modals"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!fs.existsSync(modalsPath)) {
|
||||||
|
console.log(
|
||||||
|
`[WARNING] Modal directory not found: ${modalsPath}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const modalFiles = fs
|
||||||
|
.readdirSync(modalsPath)
|
||||||
|
.filter(file =>
|
||||||
|
file.endsWith(".js")
|
||||||
|
);
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
for (const file of modalFiles) {
|
||||||
|
const filePath = path.join(
|
||||||
|
modalsPath,
|
||||||
|
file
|
||||||
|
);
|
||||||
|
|
||||||
|
const modal = require(filePath);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!modal.customId ||
|
||||||
|
typeof modal.execute !== "function"
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
`[WARNING] Modal ${file} is missing "customId" or "execute".`
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.modals.set(
|
||||||
|
modal.customId,
|
||||||
|
modal
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[MODAL] Registered "${modal.customId}" from ${file}`
|
||||||
|
);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[${count}] Modal(s) initialized`
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@ client.legacyCommands = new Collection() // legacy commands collection
|
|||||||
client.aliases = new Collection() // list of command aliases
|
client.aliases = new Collection() // list of command aliases
|
||||||
client.buttons = new Collection() // list of buttons
|
client.buttons = new Collection() // list of buttons
|
||||||
client.selectMenus = new Collection() // list of selectMenus
|
client.selectMenus = new Collection() // list of selectMenus
|
||||||
|
client.modals = new Collection();
|
||||||
|
|
||||||
fs.readdirSync('./handlers').forEach((handler) => {
|
fs.readdirSync('./handlers').forEach((handler) => {
|
||||||
require(`./handlers/${handler}`)(client)
|
require(`./handlers/${handler}`)(client)
|
||||||
|
|||||||