From f8cff0f9a4c0101a174d5583ed562cebf3c01deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mj=C3=B6llnir?= Date: Wed, 13 Nov 2024 16:52:29 +0100 Subject: [PATCH] fix embed for help command --- bot_commands.lua | 173 ++++++++++++++++----- deps/discordia/libs/containers/Message.lua | 1 + localization/en.lua | 4 + localization/fr.lua | 4 + 4 files changed, 139 insertions(+), 43 deletions(-) diff --git a/bot_commands.lua b/bot_commands.lua index 876f11f..cd97f0d 100644 --- a/bot_commands.lua +++ b/bot_commands.lua @@ -6,6 +6,8 @@ local client = Bot.Client local config = Config local enums = discordia.enums +local MAX_NUMBER_OF_EMBED_FIELDS = 25 + function Bot:BuildUsage(commandTable) local usage = {} for k,v in ipairs(commandTable.Args) do @@ -159,17 +161,122 @@ client:on('messageCreate', function(message) end end) +local function getCommands(member) + local commands = {} + + for commandName, commandTable in pairs(Bot.Commands) do + local visible = true + if (commandTable.PrivilegeCheck) then + local success, ret = Bot:ProtectedCall("Command " .. commandName .. " privilege check", commandTable.PrivilegeCheck, member) + if (not success or not ret) then + visible = false + end + end + + if (visible) then + table.insert(commands, commandTable) + end + end + + table.sort(commands, function (a, b) return a.Name < b.Name end) + + local commandsFields = {} + for _, commandTable in pairs(commands) do + local helpStr = commandTable.Help or "" + if(type(helpStr) == "function") then -- localization + helpStr = commandTable.Help(member.guild) + end + + table.insert(commandsFields, { + name = string.format("**Command: %s**", commandTable.Name), + value = string.format("**Description:** %s\n**Usage:** %s %s", helpStr, commandTable.Name, Bot:BuildUsage(commandTable)) + }) + end + + return commandsFields +end + +local function getHelpButtonsComponent(guild, selectedPage, nbPages) + local components = {} + local actionButtons = { + { + type = enums.componentType.button, + custom_id = "help_button_previous_page_" .. selectedPage - 1, + style = enums.buttonStyle.primary, + label = Bot:Format(guild, "BOT_HELP_PREV_BUTTON_LABEL"), + disabled = (selectedPage - 1) < 1 and true or false + }, + { + type = enums.componentType.button, + custom_id = "help_button_next_page_" .. selectedPage + 1, + style = enums.buttonStyle.primary, + label = Bot:Format(guild, "BOT_HELP_NEXT_BUTTON_LABEL"), + disabled = (selectedPage + 1) > nbPages and true or false + } + } + + table.insert(components, { + type = enums.componentType.actionRow, + components = actionButtons + }) + + return components +end + +client:on("interactionCreate", function (interaction) + local guild = interaction.guild + if (not guild) then + return + end + + local member = interaction.member + local interactionId = interaction.data.custom_id + if (not string.match(interactionId, "^help_button")) then + return + end + + local commandsFields = getCommands(member) + local nbPages = math.floor((#commandsFields - 1) / MAX_NUMBER_OF_EMBED_FIELDS) + 1 + local selectedPage = tonumber(string.match(interactionId, "(%d+)$")) or 1 + + if (selectedPage < 1 or selectedPage > nbPages) then + return + end + + local page = { + table.unpack( + commandsFields, + ((selectedPage - 1) * MAX_NUMBER_OF_EMBED_FIELDS) + 1, + selectedPage * MAX_NUMBER_OF_EMBED_FIELDS + ) + } + + interaction.message:update({ + components = getHelpButtonsComponent(guild, selectedPage, nbPages), + embed = { + fields = page, + footer = { text = string.format("Page %s/%s", selectedPage, nbPages) } + } + }) + + interaction:respond({ + type = enums.interactionResponseType.updateMessage + }) +end) + Bot:RegisterCommand({ Name = "help", Args = { - {Name = "command", Type = Bot.ConfigType.String, Optional = true} + { Name = "command", Type = Bot.ConfigType.String, Optional = true } }, Silent = false, - Help = "Print commands list", + Help = function (guild) return Bot:Format(guild, "BOT_HELP_HELP") end, Func = function (message, commandName) local member = message.member local guild = message.guild + local commandsFields = {} + if (commandName) then commandName = commandName:lower() local commandTable = Bot.Commands[commandName] @@ -195,52 +302,32 @@ Bot:RegisterCommand({ helpStr = commandTable.Help(guild) end - message:reply({ - embed = { - fields = { - { - name = string.format("**Command: %s**", commandName), - value = string.format("**Description:** %s\n**Usage:** %s %s", helpStr, commandName, Bot:BuildUsage(commandTable)) - } - } - } + table.insert(commandsFields, { + name = string.format("**Command: %s**", commandName), + value = string.format("**Description:** %s\n**Usage:** %s %s", helpStr, commandName, Bot:BuildUsage(commandTable)) }) else - local commands = {} - for commandName, commandTable in pairs(Bot.Commands) do - local visible = true - if (commandTable.PrivilegeCheck) then - local success, ret = Bot:ProtectedCall("Command " .. commandName .. " privilege check", commandTable.PrivilegeCheck, member) - if (not success or not ret) then - visible = false - end - end - - if (visible) then - table.insert(commands, commandTable) - end - end - - table.sort(commands, function (a, b) return a.Name < b.Name end) + commandsFields = getCommands(member) + end - local fields = {} - for _, commandTable in pairs(commands) do - local helpStr = commandTable.Help or "" - if(type(helpStr) == "function") then -- localization - helpStr = commandTable.Help(guild) - end + -- pagination + local components = {} + if (#commandsFields > MAX_NUMBER_OF_EMBED_FIELDS) then + local nbPages = math.floor((#commandsFields - 1) / MAX_NUMBER_OF_EMBED_FIELDS) + 1 + local selectedPage = 1 - table.insert(fields, { - name = string.format("**Command: %s**", commandTable.Name), - value = string.format("**Description:** %s\n**Usage:** %s %s", helpStr, commandTable.Name, Bot:BuildUsage(commandTable)) - }) - end + commandsFields = { table.unpack(commandsFields, 1, MAX_NUMBER_OF_EMBED_FIELDS) } + components = getHelpButtonsComponent(guild, selectedPage, nbPages) - message:reply({ - embed = { - fields = fields - } - }) + local footer = { text = string.format("Page %s/%s", selectedPage, nbPages) } end + + message:reply({ + embed = { + fields = commandsFields, + footer = footer or null + }, + components = components + }) end }) diff --git a/deps/discordia/libs/containers/Message.lua b/deps/discordia/libs/containers/Message.lua index 66c2811..265a4ac 100644 --- a/deps/discordia/libs/containers/Message.lua +++ b/deps/discordia/libs/containers/Message.lua @@ -298,6 +298,7 @@ sent by other users). function Message:update(data) return self:_modify({ content = data.content or null, + components = data.components or null, embed = data.embed or null, allowed_mentions = { parse = {'users', 'roles', 'everyone'}, diff --git a/localization/en.lua b/localization/en.lua index 0c0cf9a..45d3572 100644 --- a/localization/en.lua +++ b/localization/en.lua @@ -4,6 +4,10 @@ return { Locs = { GLOBAL_DEFAULT_REASON = "No reason provided.", + BOT_HELP_HELP = "Print commands list.", + BOT_HELP_NEXT_BUTTON_LABEL = "Next Page", + BOT_HELP_PREV_BUTTON_LABEL = "Previous Page", + CLEAN_URLS_NO_RULE_PROVIDED = "No rule provided", CLEAN_URLS_NO_RULES_PROVIDED = "No rules provided", CLEAN_URLS_RULE_ADDED = "Added rule: `%s`", diff --git a/localization/fr.lua b/localization/fr.lua index d54fdd5..adc1f98 100644 --- a/localization/fr.lua +++ b/localization/fr.lua @@ -165,6 +165,10 @@ return { Locs = { GLOBAL_DEFAULT_REASON = "Aucune raison donnée.", + BOT_HELP_HELP = "Affiche la liste des commandes.", + BOT_HELP_NEXT_BUTTON_LABEL = "Page Suivante", + BOT_HELP_PREV_BUTTON_LABEL = "Page Précédente", + CLEAN_URLS_NO_RULE_PROVIDED = "Aucune règle fournie", CLEAN_URLS_NO_RULES_PROVIDED = "Aucune règles fournies", CLEAN_URLS_RULE_ADDED = "Règle ajoutée : `%s`",