managers_interaction_ModalInteractionManager.js
'use strict';
const readDirectory = require('node:util').promisify(require('node:fs').readdir);
const statDirectory = require('node:util').promisify(require('node:fs').stat);
const { Collection } = require('discord.js');
const { DisGroupDevError, Messages } = require('../../errors/DisGroupDevError');
/**
* The modal interaction manager.
* @class
*/
class ModalInteractionManager {
/**
* The constructor of the modal interaction manager class.
* @param {Client} client The client
* @param {InteractionManager} interactionManager The interaction manager
*/
constructor(client, interactionManager) {
/**
* The cache with all modal interactions
* @type {Collection<String, ModalInteraction>}
* @public
*/
this.cache = new Collection();
/**
* The client
* @type {Client}
* @public
*/
this.client = client;
/**
* The interaction manager
* @type {InteractionManager}
* @public
*/
this.manager = interactionManager;
}
/**
* Loads one specific modal interaction
* @param {String} path The path to the modal interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
load(path) {
return new Promise((resolve, reject) => {
try {
/** @type {ModalInteraction} */
const modalInteraction = new (require(path))(this.client, this.manager);
if (!modalInteraction.enabled) return;
modalInteraction.location = path;
if (modalInteraction.init && typeof modalInteraction.init === 'function') modalInteraction.init();
if (!modalInteraction.execute || typeof modalInteraction.execute !== 'function') reject(new DisGroupDevError(Messages.INVALID_EXECUTE(modalInteraction.name)));
this.cache.set(modalInteraction.name, modalInteraction);
/**
* Emitted when a modal interaction is loaded.
* @event InteractionManager#modalInteractionLoad
* @param {ModalInteraction} modalInteraction The modal interaction
* @public
*/
this.manager.emit('modalInteractionLoad', modalInteraction);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Loads all modal interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
loadAll() {
return new Promise(async resolve => {
try {
const modalInteractionDirectory = await readDirectory(this.manager.options.locationModalInteractions);
for (const modalInteractionDirectoryCategoryOrFile of modalInteractionDirectory) {
const modalInteractionDirectoryStat = await statDirectory(require('node:path').resolve(this.manager.options.locationModalInteractions, modalInteractionDirectoryCategoryOrFile));
if (modalInteractionDirectoryStat.isDirectory()) {
const modalInteractionDirectoryCategory = await readDirectory(require('node:path').resolve(this.manager.options.locationModalInteractions, modalInteractionDirectoryCategoryOrFile));
for (const modalInteractionDirectoryCategoryFile of modalInteractionDirectoryCategory) {
await this.load(`${this.manager.options.locationModalInteractions}/${modalInteractionDirectoryCategoryOrFile}/${modalInteractionDirectoryCategoryFile}`);
}
} else if (modalInteractionDirectoryStat.isFile()) {
await this.load(`${this.manager.options.locationModalInteractions}/${modalInteractionDirectoryCategoryOrFile}`);
}
}
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Reloads one specific modal interaction
* @param {String} name The name of the modal interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
reload(name) {
return new Promise(async (resolve, reject) => {
if (!this.cache.has(name)) reject(new DisGroupDevError(Messages.MODAL_INTERACTION_NOT_FOUND(name)));
const { location } = require(this.cache.get(name));
try {
await this.unload(name);
await this.load(location);
const modalInteraction = this.cache.get(name);
/**
* Emitted when a modal interaction is reloaded.
* @event InteractionManager#modalInteractionReload
* @param {ModalInteraction} modalInteraction The modal interaction
* @public
*/
this.manager.emit('modalInteractionReload', modalInteraction);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Reloads all modal interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
reloadAll() {
return new Promise(async resolve => {
try {
for (const modalInteraction of this.cache) {
await this.unload(modalInteraction[1].name);
}
await this.loadAll();
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Unloads one specific modal interaction
* @param {String} name The name of the modal interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
unload(name) {
return new Promise((resolve, reject) => {
if (!this.cache.has(name)) reject(new DisGroupDevError(Messages.MODAL_INTERACTION_NOT_FOUND(name)));
try {
delete require.cache[require.resolve(this.cache.get(name).location)];
this.cache.delete(name);
/**
* Emitted when a modal interaction is unloaded.
* @event InteractionManager#modalInteractionUnload
* @param {String} name The name of the modal interaction
* @public
*/
this.manager.emit('modalInteractionUnload', name);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Unloads all modal interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
unloadAll() {
return new Promise(async resolve => {
try {
for (const modalInteraction of this.cache) {
await this.unload(modalInteraction[1].name);
}
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
}
module.exports = ModalInteractionManager;