This commit is contained in:
Erik 2022-03-26 22:05:09 +02:00
parent 06e0d459c2
commit 95a7fe9f5f
No known key found for this signature in database
GPG Key ID: FEFF4B220DDF5589

162
archive/SettingsCommand.js Normal file
View File

@ -0,0 +1,162 @@
const { SlashCommand, CommandOption } = require("../../../interfaces");
const { Constants: { PermissionNames } } = require('../../../../constants');
const Util = require('../../../../Util.js');
class SettingsCommand extends SlashCommand {
constructor(client) {
super(client, {
name: 'settings',
description: "Configure the bot's behaviour in your server",
module: 'administration',
options: [
new CommandOption({
type: 'SUB_COMMAND',
name: 'list',
description: 'List available settings'
})
],
guildOnly: true
});
this.build();
}
// Constructs the command tree for settings
// Idk if this is where we want this functionality to be
build() {
const allSettings = this.client.registry.components
.filter((c) => c._type === 'setting');
// Organise modules into subcommand groups
const modules = new Set(allSettings.map((set) => set.module.name));
for (const module of modules) {
const settingsModule = allSettings.filter((s) => s.module.name === module);
// /settings moderation
const moduleSubcommand = new CommandOption({
name: module,
description: `Configure ${module} settings`,
type: 'SUB_COMMAND_GROUP'
});
for (const setting of settingsModule.values()) {
// Each setting becomes its own subcommand with options defined in the settings
// /settings moderation mute role:@muted permanent:false default:1h type:1
const settingSubcommand = new CommandOption({
name: setting.name,
description: setting.description,
type: 'SUB_COMMAND',
options: setting.commandOptions
});
moduleSubcommand.options.push(settingSubcommand);
}
this.options.push(moduleSubcommand);
}
}
async execute(interaction, opts) {
const { guild } = interaction;
const settingName = interaction.subcommand.name;
if (settingName === 'list') return this._listSettings(interaction);
const [setting] = this.client.resolver.components(settingName, 'setting');
if (!setting) return interaction.reply('Something went wrong, could not find setting');
if (setting.clientPermissions.length) {
const missing = guild.me.permissions.missing(setting.clientPermissions);
if (missing.length) return interaction.reply({
emoji: 'failure',
index: 'SETTING_MISSINGCLIENTPERMISSIONS',
params: { permissions: missing.map((m) => `\`${PermissionNames[m]}\``).join(', ') }
});
}
await interaction.deferReply();
const settings = await guild.settings();
if (!Object.keys(opts).length) return this._showSetting(interaction, setting);
try {
// Pass setting values copy so the changes don't persist unless successful and actually saved
const _setting = { ...settings[setting.name] };
const result = await setting.execute(interaction, opts, _setting);
if (result) {
const obj = { components: [], params: {}, ...result };
obj.params.setting = setting.name;
if (!result.error) {
settings[setting.name] = _setting;
await guild.updateSettings(settings);
await interaction.reply({ ...obj, emoji: 'success', _edit: interaction.replied });
} else {
await interaction.reply({ ...obj, emoji: 'failure', _edit: interaction.replied });
}
}
} catch (err) {
this.client.logger.error(`Error during setting execution:\n${err.stack || err}`);
await interaction.editReply({
index: 'SETTINGS_ERROR',
params: { resolveable: setting.resolveable },
emoji: 'failure'
});
}
if (!interaction.replied) await interaction.reply({
index: 'SETTINGS_NO_REPLY',
params: { resolveable: setting.resolveable }
});
}
async _listSettings(interaction) {
const { settings } = this.client.registry;
const modules = settings.reduce((acc, setting) => {
const { name } = setting.module;
if (!acc[name]) acc[name] = [];
acc[name].push(setting.name);
return acc;
}, {});
const { guild } = interaction;
const embed = {
title: 'Settings',
description: guild.format('SETTINGS_LIST'),
fields: []
};
const entries = Object.entries(modules);
for (const [module, values] of entries)
embed.fields.push({
name: Util.capitalise(module),
value: `\`${values.join('`\n`')}\``,
inline: true
});
return interaction.reply({ embeds: [embed] });
}
async _showSetting(interaction, setting) {
const { guild } = interaction;
const embed = setting.usageEmbed(guild);
const dataFields = await setting.fields(guild);
// eslint-disable-next-line no-return-assign
dataFields.forEach((field) => {
if (field.name.length > 1) field.name = guild.format(field.name);
});
embed.fields.push(...dataFields);
await interaction.editReply({ embeds: [embed] }).catch((error) => {
this.client.logger.error(`${error.stack || error}\nError context: ${JSON.stringify(embed)}`);
});
}
}
module.exports = SettingsCommand;