Friday, September 20, 2024 5:46:52 AM
> settings

Customize


Authenticate

> help.rb
# frozen_string_literal: true

module ESM
  module Command
    module General
      class Help < ApplicationCommand
        #################################
        #
        # Arguments (required first, then order matters)
        #

        # Optional: Command expects this
        argument :category, display_name: :with

        #
        # Configuration
        #

        change_attribute :allowed_in_text_channels, modifiable: false
        change_attribute :cooldown_time, modifiable: false
        change_attribute :enabled, modifiable: false
        change_attribute :allowlist_enabled, modifiable: false
        change_attribute :allowlisted_role_ids, modifiable: false

        command_type :player

        does_not_require :registration

        use_root_namespace

        #################################

        def on_execute
          case arguments.category
          when "commands"
            commands
          when "player commands"
            commands(types: [:player], include_development: false)
          when "admin commands"
            commands(types: [:admin], include_development: false)
          when ->(category) { ESM::Command.include?(category) }
            command
          else
            getting_started
          end
        end

        private

        def getting_started
          embed =
            ESM::Embed.build do |e|
              e.title = I18n.t("commands.help.getting_started.title", user: current_user.username)

              commands_by_type = ESM::Command.by_type
              e.description = I18n.t(
                "commands.help.getting_started.description",
                command_count_player: commands_by_type[:player].size,
                command_count_total: commands_by_type.values.flatten.size
              )

              # history
              %w[commands command privacy].each do |field_type|
                e.add_field(
                  name: I18n.t("commands.help.getting_started.fields.#{field_type}.name"),
                  value: I18n.t("commands.help.getting_started.fields.#{field_type}.value")
                )
              end
            end

          reply(embed)
        end

        def commands(types: ESM::Command::TYPES.dup, include_development: ESM.env.development?)
          types << :development if include_development

          # Remove :admin if player mode is enabled for this community
          types.delete(:admin) if current_community&.player_mode_enabled?

          # Now build the embed for each type
          types.each do |type|
            next if categories(type).blank?

            embed =
              ESM::Embed.build do |e|
                e.title = I18n.t("commands.help.commands.#{type}.title")
                e.description = I18n.t("commands.help.commands.#{type}.description")
                e.color = ESM::Color.random

                categories(type).each do |category, commands|
                  e.add_field(
                    name: "**__#{category.humanize}__**",
                    value: format_commands(commands)
                  )
                end
              end

            reply(embed)
          end
        end

        def categories(type)
          return [] if ESM::Command.by_type[type].nil?

          ESM::Command.by_type[type].group_by(&:category)
        end

        # Return an array so ESM::Embed field logic will handle overflow correctly
        def format_commands(commands)
          commands.sort_by(&:usage).map do |command|
            description = command.description
            description += "\n#{command.description_extra}" if command.description_extra.present?

            "**`#{command.usage}`**\n#{description}"
          end
        end

        def command
          command = ESM::Command[arguments.category].new
          embed =
            ESM::Embed.build do |e|
              e.title = I18n.t("commands.help.command.title", name: command.usage)
              description = ["*This command used to be `!#{command.command_name}`*", command.description, ""]

              # Adds a note about being limited to DM or Text
              description << I18n.t("commands.help.command.note") if command.limited_to || command.command_allowlist_enabled?
              description << I18n.t("commands.help.command.limited_to", channel_type: I18n.t(command.limited_to)) if command.limited_to
              description << I18n.t("commands.help.command.allowlist_enabled") if command.command_allowlist_enabled?
              e.description = description

              # Usage
              e.add_field(
                name: I18n.t("commands.help.command.usage"),
                value: "```#{command.usage}```"
              )

              # Arguments
              if command.arguments.present?
                e.add_field(
                  name: I18n.t("commands.help.command.arguments"),
                  value: command.arguments.templates.map { |_, argument| argument.help_documentation }
                )
              end

              # Examples
              if command.examples.present?
                e.add_field(
                  name: I18n.t("commands.help.command.examples"),
                  value: command.examples
                )
              end
            end

          reply(embed)
        end
      end
    end
  end
end
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8