148 lines
4.5 KiB
JavaScript
148 lines
4.5 KiB
JavaScript
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;
|