diff --git a/archive/SettingsCommand.js b/archive/SettingsCommand.js new file mode 100644 index 0000000..4e573d1 --- /dev/null +++ b/archive/SettingsCommand.js @@ -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; \ No newline at end of file