From bd970a77347ff818c0640a5b842157f9b9f9a5eb Mon Sep 17 00:00:00 2001 From: "Navy.gif" Date: Thu, 13 Jan 2022 21:54:27 +0200 Subject: [PATCH] experimenting with different setting style --- .../administration/SettingsCommand.js | 175 +++++++----------- .../settings/administration/Silent.js | 57 ++++++ .../settings/moderation/MuteSetting.js | 56 +++++- 3 files changed, 176 insertions(+), 112 deletions(-) create mode 100644 src/structure/components/settings/administration/Silent.js diff --git a/src/structure/components/commands/administration/SettingsCommand.js b/src/structure/components/commands/administration/SettingsCommand.js index 982875b..132f6a5 100644 --- a/src/structure/components/commands/administration/SettingsCommand.js +++ b/src/structure/components/commands/administration/SettingsCommand.js @@ -7,117 +7,80 @@ class SettingsCommand extends SlashCommand { name: 'settings', description: "Invoke to display a settings menu.", module: 'administration', - options: [ - new CommandOption({ - name: 'moderation', - description: '', - type: 'SUB_COMMAND_GROUP', - options: [ - new CommandOption({ - name: 'wordfilter', - description: '', - type: 'SUB_COMMAND', - options: [ - new CommandOption({ - name: 'option', - description: '', - required: true, - type: 'STRING', - choices: [{ - name: 'fuzzy', value: 'fuzzy' - }, { - name: 'explicit', value: 'explicit' - }, { - name: 'regex', value: 'regex' - }] - }), - new CommandOption({ - name: 'value', - description: '', - required: true, - type: 'STRING' - }), - new CommandOption({ - name: 'method', - description: '', - required: false, - type: 'STRING', - choices: [{ - name: 'add', - value: 'add' - }, { - name: 'delete', - value: 'delete' - }, { - name: 'set', - value: 'set' - }, { - name: 'reset', - value: 'reset' - }] - }) - ] - }), - new CommandOption({ - name: 'linkfilter', - description: '', - type: 'SUB_COMMAND', - options: [ - new CommandOption({ - name: 'option', - description: '', - required: true, - type: 'STRING', - choices: [{ - name: 'fuzzy', value: 'fuzzy' - }, { - name: 'explicit', value: 'explicit' - }, { - name: 'regex', value: 'regex' - }] - }), - new CommandOption({ - name: 'method', - description: '', - required: false, - type: 'STRING', - choices: [{ - name: 'add', - value: 'add' - }, { - name: 'delete', - value: 'delete' - }, { - name: 'set', - value: 'set' - }, { - name: 'reset', - value: 'reset' - }] - }), - new CommandOption({ - name: 'value', - description: '', - required: false, - type: 'STRING' - }) - ] - }) - ] - }) - ], + options: [], guildOnly: true }); + + this.build(); + } - // /settings moderation mute method:role submethod:something more value:something - // / settings moderation mute method: length value: something - - // / settings moderation wordfilter option: fuzzy method: add value: word1 word2 word3 - - async execute(thing, options) { - + // 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) { + + const { options, guild } = interaction; + const [module] = options.data; + const [{ name: settingName, options: settingOpts }] = module.options; + + const [setting] = this.client.resolver.components(settingName, 'setting'); + if (!setting) return interaction.reply('Something went wrong, could not find setting'); + + await interaction.deferReply(); + const settings = await guild.settings(); + if (!settingOpts) return this._showSetting(interaction, setting); + + try { + // Pass settings as a param to simplify saving settings + await setting.execute(interaction, settingOpts, settings); + await guild.updateSettings(settings); + } catch (err) { + this.client.logger.error(`Error during setting execution:\n${err.stack || err}`); + await interaction.channel.send('Internal error during setting exectuion'); + } + + if (!interaction.replied && interaction.deferred) await interaction.editReply(`No response from setting handler`); + + } + + async _showSetting(interaction, setting) { + + const { guild } = interaction; + const embed = setting.usageEmbed(guild); + const dataFields = await setting.fields(guild); + embed.fields.push(...dataFields); + + await interaction.editReplyEmbed(embed); } diff --git a/src/structure/components/settings/administration/Silent.js b/src/structure/components/settings/administration/Silent.js new file mode 100644 index 0000000..9919f1c --- /dev/null +++ b/src/structure/components/settings/administration/Silent.js @@ -0,0 +1,57 @@ +const { Setting, CommandOption } = require("../../../interfaces"); + + +class SilentSetting extends Setting { + + constructor(client) { + + super(client, { + name: 'silent', + description: 'Toggle between normal and ephemeral moderation responses', + module: 'administration', + display: 'Silent', + // emoji: { + + // }, + default: { + enabled: false + }, + commandOptions: [ + new CommandOption({ + type: 'BOOLEAN', + name: 'enabled', + description: 'Toggle state' + }) + ] + }); + + } + + async execute(interaction, opts, settings) { + + for (const opt of opts) { + settings[this.name][opt.name] = opt.value; + } + await interaction.editReply({ + template: { + index: 'SETTINGS_SUCCESS', + params: { setting: this.name } + }, + emoji: 'success' + }); + + } + + fields(guild) { + return [ + { + name: guild.format('GENERAL_STATUS'), + value: guild.format('GENERAL_STATE', { bool: guild._settings[this.name].enabled }, { code: true }), + inline: true + } + ]; + } + +} + +module.exports = SilentSetting; \ No newline at end of file diff --git a/src/structure/components/settings/moderation/MuteSetting.js b/src/structure/components/settings/moderation/MuteSetting.js index 83f4199..eb4cab9 100644 --- a/src/structure/components/settings/moderation/MuteSetting.js +++ b/src/structure/components/settings/moderation/MuteSetting.js @@ -1,4 +1,4 @@ -const { Setting } = require('../../../interfaces/'); +const { Setting, CommandOption } = require('../../../interfaces/'); const { inspect } = require('util'); class MuteSetting extends Setting { @@ -19,23 +19,65 @@ class MuteSetting extends Setting { role: null, defaultDuration: 3600, allowPermanent: false - } + }, + commandOptions: [ + new CommandOption({ + type: 'ROLE', + name: 'role', + description: 'Select the role to use for mutes' + }), + new CommandOption({ + type: 'STRING', + name: 'default', + description: 'Set the default duration for mutes' + }), + new CommandOption({ + type: 'BOOLEAN', + name: 'permanent', + description: 'Whether to allow permanent mutes or fall back to default mute duration' + }), + new CommandOption({ + type: 'INTEGER', + name: 'type', + description: 'Select the type of mute behaviour, one of [0, 1, 2]', + choices: [ + { + name: 'Type 0 (Append role)', + value: 0 + }, + { + name: 'Type 1 (Replace roles)', + value: 1 + }, + { + name: 'Type 2 (Remove all roles)', + value: 2 + } + ] + }) + ] }); } + async execute() { + console.log('\n\nDINGUS\n\n'); + } + async onCollect(guild, selectMenu) { const settings = await guild.settings(); const setting = settings[this.name]; - return (interaction) => { + return async (interaction) => { if (interaction.isButton()) { if ((/^\d$/u).test(interaction.customId)) setting.type = parseInt(interaction.customId); else if (['allow_permanent', 'disallow_permanent'].includes(interaction.customId)) setting.allowPermanent = interaction.customId === 'allow_permanent'; else if ((/\d+h/u).test(interaction.customId)) setting.defaultDuration = this.client.resolver.resolveTime(interaction.customId); - } else if (interaction.customId === 'role') [setting.role] = interaction.values; - else return this.client.logger.debug(`Returned`); + } else if (interaction.customId === 'role') { + if (interaction.value === 'create') await this.createRole(); + [setting.role] = interaction.values; + } else return this.client.logger.debug(`Returned`); this.client.logger.debug(`Setting update: ${inspect(setting)}`); settings[this.name] = setting; @@ -50,12 +92,14 @@ class MuteSetting extends Setting { const typeStyle = this.buttonStyle(setting.type); const permStyle = this.buttonStyle(setting.allowPermanent); const durStyle = this.buttonStyle(setting.defaultDuration); + const roleSelect = this.roleSelectComponent(guild, false, setting.role); + roleSelect.options.unshift({ label: 'CREATE ROLE', value: 'create' }); return [ ...super.components(selectMenu), { type: 'ACTION_ROW', components: [ - this.roleSelectComponent(guild, false, setting.role) + roleSelect ] }, {