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;