const { InteractionCollector } = require('discord.js'); const { SlashCommand, CommandOption } = require('../../../interfaces/'); class SettingCommand extends SlashCommand { constructor(client) { super(client, { name: 'setting', description: "[DEV] Invoke to display a settings menu.", module: 'administration', options: [ new CommandOption({ name: 'category', description: "Select a category to configure settings for.", type: 'STRING', choices: [ { name: 'Administration', value: 'administrator' }, { name: 'Moderation', value: 'moderation' }, { name: 'Utility', value: 'utility' } ], required: true }), new CommandOption({ name: 'view', description: "Pass this option to view the current configuration for the category", type: 'BOOLEAN' }) ], defaultPermission: false }); } async execute(wrapper, options) { const settings = this.client.registry.components .filter((c) => c._type === 'setting' && c.module.name === options.category.value); if(settings.size === 0) { return wrapper.reply({ content: "Could not find any settings in that category." }); } const viewMode = options.view?.value || false; const selectMenu = { type: 'SELECT_MENU', custom_id: 'setting', //eslint-disable-line camelcase placeholder: 'Settings', options: settings.map((s) => { return { label: s.display, value: s.name, description: s.description, emoji: s.emoji }; }) }; const message = await wrapper.reply({ content: 'Choose a setting.', components: [ { type: 'ACTION_ROW', components: [ selectMenu ] } ] }); // Hook for fishing out the collector to end it when the user swaps settings const hook = { collector: null }; new InteractionCollector(this.client, { channel: wrapper.channel, message, componentType: 'SELECT_MENU', idle: 600_000 // 10 min }).on('collect', async (interaction) => { this.client.logger.debug(`Setting interaction collected`); if (interaction.customId !== 'setting') return; if (hook.collector) { // End the collector for the previously selected setting hook.collector.stop(); hook.collector = null; } const setting = this.client.registry.components.get(`setting:${interaction.values[0]}`); if (!interaction.deferred && !interaction.replied) interaction.deferUpdate(); selectMenu.options.forEach((o) => { if (o.value === setting.name) o.default = true; else o.default = false; }); this.client.logger.debug(`Passing to setting`); try { if (!viewMode) await setting.execute(wrapper, selectMenu, hook); else await this._showSetting(wrapper, setting); } catch (err) { this.client.logger.error(`Error during setting execution:\n${err.stack || err}`); wrapper.channel.send(`Internal error while trying to process **${setting.name}** setting`); } }).on('end', () => { this.client.logger.debug(`Setting collector ended`); wrapper.editReply({ content: `Setting timed out`, components: [] }); }); } async _showSetting(wrapper, setting) { } } //module.exports = SettingCommand;