ui updates and bot updates. new commands and command handler
This commit is contained in:
112
discord-bot/commands/manage-commands.js
Normal file
112
discord-bot/commands/manage-commands.js
Normal file
@@ -0,0 +1,112 @@
|
||||
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionsBitField } = require('discord.js');
|
||||
const { readDb, writeDb } = require('../../backend/db.js');
|
||||
|
||||
module.exports = {
|
||||
name: 'manage-commands',
|
||||
description: 'Admin: List bot commands and toggle them Enabled/Disabled for this server.',
|
||||
enabled: true,
|
||||
builder: new SlashCommandBuilder()
|
||||
.setName('manage-commands')
|
||||
.setDescription('Admin: List bot commands and toggle them Enabled/Disabled for this server.'),
|
||||
async execute(interaction) {
|
||||
// Only allow administrators
|
||||
if (!interaction.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
|
||||
await interaction.reply({ content: 'You must be a server administrator to use this command.', flags: 64 });
|
||||
return;
|
||||
}
|
||||
|
||||
const db = readDb();
|
||||
if (!db[interaction.guildId]) db[interaction.guildId] = {};
|
||||
if (!db[interaction.guildId].commandToggles) db[interaction.guildId].commandToggles = {};
|
||||
|
||||
const toggles = db[interaction.guildId].commandToggles;
|
||||
// Include all loaded commands so simple command modules (no SlashCommandBuilder) like
|
||||
// `ping` are also listed. Filter for objects with a name for safety.
|
||||
const commands = Array.from(interaction.client.commands.values()).filter(cmd => cmd && cmd.name);
|
||||
|
||||
// Build button components (max 5 rows, 5 buttons per row)
|
||||
const actionRows = [];
|
||||
let currentRow = new ActionRowBuilder();
|
||||
let buttonsInRow = 0;
|
||||
|
||||
const protectedCommands = ['manage-commands', 'help'];
|
||||
|
||||
const buildButton = (cmd) => {
|
||||
if (protectedCommands.includes(cmd.name)) return null;
|
||||
const isEnabled = toggles[cmd.name] !== false && cmd.enabled !== false;
|
||||
return new ButtonBuilder()
|
||||
.setCustomId(`toggle_cmd_${cmd.name}`)
|
||||
.setLabel(`${cmd.name} : ${isEnabled ? 'ENABLED' : 'DISABLED'}`)
|
||||
.setStyle(isEnabled ? ButtonStyle.Success : ButtonStyle.Secondary);
|
||||
};
|
||||
|
||||
for (const cmd of commands) {
|
||||
const btn = buildButton(cmd);
|
||||
if (btn) {
|
||||
currentRow.addComponents(btn);
|
||||
buttonsInRow++;
|
||||
|
||||
if (buttonsInRow === 5) {
|
||||
actionRows.push(currentRow);
|
||||
currentRow = new ActionRowBuilder();
|
||||
buttonsInRow = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buttonsInRow > 0) actionRows.push(currentRow);
|
||||
|
||||
const description = commands.map(cmd => `• ${cmd.name} — ${cmd.description || 'No description.'}${protectedCommands.includes(cmd.name) ? ' (locked)' : ''}`).join('\n');
|
||||
|
||||
await interaction.reply({ content: `Manage Commands for this server:\n\n${description}`, components: actionRows, flags: 64 });
|
||||
|
||||
const message = await interaction.fetchReply();
|
||||
|
||||
// Collector to handle button presses for 5 minutes
|
||||
const filter = i => i.user.id === interaction.user.id && i.customId.startsWith('toggle_cmd_');
|
||||
const collector = message.createMessageComponentCollector({ filter, time: 5 * 60 * 1000 });
|
||||
|
||||
collector.on('collect', async i => {
|
||||
const cmdName = i.customId.replace('toggle_cmd_', '');
|
||||
toggles[cmdName] = !(toggles[cmdName] !== false);
|
||||
writeDb(db);
|
||||
|
||||
// rebuild buttons to reflect new state
|
||||
const updatedRows = [];
|
||||
let r = new ActionRowBuilder();
|
||||
let count = 0;
|
||||
for (const cmd of commands) {
|
||||
if (protectedCommands.includes(cmd.name)) continue;
|
||||
const btn = new ButtonBuilder()
|
||||
.setCustomId(`toggle_cmd_${cmd.name}`)
|
||||
.setLabel(`${cmd.name} : ${(toggles[cmd.name] !== false && cmd.enabled !== false) ? 'ENABLED' : 'DISABLED'}`)
|
||||
.setStyle((toggles[cmd.name] !== false && cmd.enabled !== false) ? ButtonStyle.Success : ButtonStyle.Secondary);
|
||||
r.addComponents(btn);
|
||||
count++;
|
||||
if (count === 5) { updatedRows.push(r); r = new ActionRowBuilder(); count = 0; }
|
||||
}
|
||||
if (count > 0) updatedRows.push(r);
|
||||
|
||||
await i.update({ content: `Manage Commands for this server:\n\n${description}`, components: updatedRows });
|
||||
});
|
||||
|
||||
collector.on('end', async () => {
|
||||
// disable buttons after collector ends
|
||||
const disabledRows = [];
|
||||
let rr = new ActionRowBuilder();
|
||||
let ccount = 0;
|
||||
for (const cmd of commands) {
|
||||
if (protectedCommands.includes(cmd.name)) continue;
|
||||
const btn = new ButtonBuilder()
|
||||
.setCustomId(`toggle_cmd_${cmd.name}`)
|
||||
.setLabel(`${cmd.name} : ${(toggles[cmd.name] !== false && cmd.enabled !== false) ? 'ENABLED' : 'DISABLED'}`)
|
||||
.setStyle((toggles[cmd.name] !== false && cmd.enabled !== false) ? ButtonStyle.Success : ButtonStyle.Secondary)
|
||||
.setDisabled(true);
|
||||
rr.addComponents(btn);
|
||||
ccount++;
|
||||
if (ccount === 5) { disabledRows.push(rr); rr = new ActionRowBuilder(); ccount = 0; }
|
||||
}
|
||||
if (ccount > 0) disabledRows.push(rr);
|
||||
try { await message.edit({ components: disabledRows }); } catch (e) { /* ignore */ }
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user