galactic-bot/archive/SettingCommand.js
Navy.gif e44eb8435e Typescript translation WIP
Co-authored-by: D3vision <info@d3vision.dev>
2023-12-03 22:12:01 +02:00

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;