managers_interaction_ButtonInteractionManager.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 button interaction manager.
* @class
*/
class ButtonInteractionManager {
constructor(client, interactionManager) {
/**
* The cache with all button interactions
* @type {Collection<String, ButtonInteraction>}
* @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 button interaction
* @param {String} path The path to the button interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
load(path) {
return new Promise((resolve, reject) => {
try {
/** @type {ButtonInteraction} */
const buttonInteraction = new (require(path))(this.client, this.manager);
if (!buttonInteraction.enabled) return;
buttonInteraction.location = path;
if (buttonInteraction.init && typeof buttonInteraction.init === 'function') buttonInteraction.init();
if (!buttonInteraction.execute || typeof buttonInteraction.execute !== 'function') reject(new DisGroupDevError(Messages.INVALID_EXECUTE(buttonInteraction.name)));
this.cache.set(buttonInteraction.name, buttonInteraction);
/**
* Emitted when a button interaction is loaded.
* @event InteractionManager#buttonInteractionLoad
* @param {ButtonInteraction} buttonInteraction The button interaction
* @public
*/
this.manager.emit('buttonInteractionLoad', buttonInteraction);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Loads all button interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
loadAll() {
return new Promise(async resolve => {
try {
const buttonInteractionDirectory = await readDirectory(this.manager.options.locationButtonInteractions);
for (const buttonInteractionDirectoryCategoryOrFile of buttonInteractionDirectory) {
const buttonInteractionDirectoryStat = await statDirectory(require('node:path').resolve(this.manager.options.locationButtonInteractions, buttonInteractionDirectoryCategoryOrFile));
if (buttonInteractionDirectoryStat.isDirectory()) {
const buttonInteractionDirectoryCategory = await readDirectory(require('node:path').resolve(this.manager.options.locationButtonInteractions, buttonInteractionDirectoryCategoryOrFile));
for (const buttonInteractionDirectoryCategoryFile of buttonInteractionDirectoryCategory) {
await this.load(`${this.manager.options.locationButtonInteractions}/${buttonInteractionDirectoryCategoryOrFile}/${buttonInteractionDirectoryCategoryFile}`);
}
} else if (buttonInteractionDirectoryStat.isFile()) {
await this.load(`${this.manager.options.locationButtonInteractions}/${buttonInteractionDirectoryCategoryOrFile}`);
}
}
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Reloads one specific button interaction
* @param {String} name The name of the button interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
reload(name) {
return new Promise(async (resolve, reject) => {
if (!this.cache.has(name)) reject(new DisGroupDevError(Messages.BUTTON_INTERACTION_NOT_FOUND(name)));
const { location } = require(this.cache.get(name));
try {
await this.unload(name);
await this.load(location);
const buttonInteraction = this.cache.get(name);
/**
* Emitted when a button interaction is reloaded.
* @event InteractionManager#buttonInteractionReload
* @param {ButtonInteraction} buttonInteraction The button interaction
* @public
*/
this.manager.emit('buttonInteractionReload', buttonInteraction);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Reloads all button interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
reloadAll() {
return new Promise(async resolve => {
try {
for (const buttonInteraction of this.cache) {
await this.unload(buttonInteraction[1].name);
}
await this.loadAll();
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Unloads one specific button interaction
* @param {String} name The name of the button interaction
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
unload(name) {
return new Promise((resolve, reject) => {
if (!this.cache.has(name)) reject(new DisGroupDevError(Messages.BUTTON_INTERACTION_NOT_FOUND(name)));
try {
delete require.cache[require.resolve(this.cache.get(name).location)];
this.cache.delete(name);
/**
* Emitted when a button interaction is unloaded.
* @event InteractionManager#buttonInteractionUnload
* @param {String} name The name of the button interaction
* @public
*/
this.manager.emit('buttonInteractionUnload', name);
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
/**
* Unloads all button interactions
* @returns {Promise<Boolean|DisGroupDevError>}
* @public
*/
unloadAll() {
return new Promise(async resolve => {
try {
for (const buttonInteraction of this.cache) {
await this.unload(buttonInteraction[1].name);
}
resolve(true);
} catch (e) {
throw new DisGroupDevError(e);
}
});
}
}
module.exports = ButtonInteractionManager;