experimenting with different setting style

This commit is contained in:
Erik 2022-01-13 21:54:27 +02:00
parent 8c5f975260
commit bd970a7734
No known key found for this signature in database
GPG Key ID: FEFF4B220DDF5589
3 changed files with 176 additions and 112 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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
]
},
{