Class: ESM::Embed

Inherits:
Object
  • Object
show all
Defined in:
lib/esm/embed.rb

Defined Under Namespace

Modules: Limit

Constant Summary collapse

EMPTY_SPACE =
"\u200B"
TAB =
"#{EMPTY_SPACE}#{EMPTY_SPACE}#{EMPTY_SPACE}#{EMPTY_SPACE}"
ATTRIBUTES =

Attributes that are available for building via Hash

%i[author title description color fields]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type = nil, attributes = {}, &block) ⇒ Embed

Returns a new instance of Embed.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/esm/embed.rb', line 147

def initialize(type = nil, attributes = {}, &block)
  @title = nil
  @description = nil
  @fields = []
  @footer = nil
  @author = nil
  @image = nil
  @thumbnail = nil
  @color = ESM::Color.random
  @url = nil
  @timestamp = DateTime.now

  if block
    yield(self)
  else
    build_from_template(type, **attributes)
  end
end

Instance Attribute Details

#authorObject

Returns the value of attribute author.



145
146
147
# File 'lib/esm/embed.rb', line 145

def author
  @author
end

#colorObject

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def color
  @color
end

#descriptionObject

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def description
  @description
end

#fieldsObject

Returns the value of attribute fields.



145
146
147
# File 'lib/esm/embed.rb', line 145

def fields
  @fields
end

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def footer
  @footer
end

#imageObject

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def image
  @image
end

#thumbnailObject

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def thumbnail
  @thumbnail
end

#timestampObject

Returns the value of attribute timestamp.



145
146
147
# File 'lib/esm/embed.rb', line 145

def timestamp
  @timestamp
end

#titleObject

Instance methods



144
145
146
# File 'lib/esm/embed.rb', line 144

def title
  @title
end

#urlObject

Returns the value of attribute url.



145
146
147
# File 'lib/esm/embed.rb', line 145

def url
  @url
end

Class Method Details

.build(type = nil) ⇒ ESM::Embed

Creates an embed from a preset

Parameters:

  • type (Symbol) (defaults to: nil)

    Template to build. Valid options: :info, :success, :error

  • ** (Hash)

    Any embed attributes to set

  • & (Block, nil)

    optional block that yields the new embed

Returns:



31
32
33
# File 'lib/esm/embed.rb', line 31

def self.build(type = nil, **, &)
  ESM::Embed.new(type, **, &)
end

.from_hash(hash, &block) ⇒ ESM::Embed

Creates an embed from a Hash

Parameters:

  • hash (Hash)
  • &block (Block, nil)

    Optional block that yields the new embed

Returns:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/esm/embed.rb', line 43

def self.from_hash(hash, &block)
  hash = hash.deep_symbolize_keys

  new do |embed|
    ###########
    # Author
    # Supports string or HashMap with full options
    if (author = hash[:author]) && author.present?
      author = ESM::Arma::HashMap.from(author).presence || {name: author}
      author = author.slice(:name, :url, :icon_url).symbolize_keys
      embed.set_author(**author)
    end

    ###########
    # Title
    if (title = hash[:title]) && title.present?
      embed.title = title.to_s
    end

    ###########
    # Description
    if (description = hash[:description]) && description.present?
      embed.description = description.to_s
    end

    ###########
    # Color
    color = hash[:color]
    embed.color =
      if ESM::Regex::HEX_COLOR.match?(color)
        color
      elsif color && ESM::Color::Toast.const_defined?(color.upcase)
        ESM::Color::Toast.const_get(color.upcase)
      else
        ESM::Color.random
      end

    ###########
    # Fields
    if (fields = hash[:fields]) && fields.is_a?(Array)
      fields.each do |field|
        case field
        when Hash
          name = field[:name].to_s
          value = field[:value]
          inline = field[:inline] || false
        when Data, Struct, OpenStruct
          name = field.name.to_s
          value = field.value
          inline = field.inline || false
        when Array
          name, value, inline = field
          inline ||= false
        else
          next
        end

        # Transform the hash keys/values into a "list"
        value =
          if value.is_a?(Hash)
            value.join_map("\n") do |key, value|
              "**#{key.to_s.humanize(keep_id_suffix: true)}:** #{value}"
            end
          else
            value.to_s
          end

        embed.add_field(name:, value:, inline:)
      end
    end

    yield(embed) if block
  end
end

.from_hash!(hash) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/esm/embed.rb', line 118

def self.from_hash!(hash)
  # Missing data or extra data? That's a paddling
  embed_data = hash.slice(*ATTRIBUTES)

  if embed_data.blank?
    raise ArgumentError, I18n.translate(
      "exceptions.embed.missing_attributes",
      attributes: Embed::ATTRIBUTES.map(&:in_quotes).to_sentence
    )
  end

  invalid_attributes = hash.keys - embed_data.keys

  if invalid_attributes.size > 0
    raise ArgumentError, I18n.translate(
      "exceptions.embed.invalid_attributes",
      attributes: invalid_attributes.map(&:in_quotes).to_sentence
    )
  end

  from_hash(embed_data)
end

Instance Method Details

#add_field(value:, name: nil, inline: false) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/esm/embed.rb', line 179

def add_field(value:, name: nil, inline: false)
  # This will make the name appear empty
  name = EMPTY_SPACE if name.nil?

  # Discord won't send messages that have an empty field. This forces the value to be appear empty, and Discord will accept it.
  value = EMPTY_SPACE if value.blank?

  if value.is_a?(Array)
    add_field_array(name:, values: value, inline:)
  else
    store_field(name:, value:, inline:)
  end

  self
end

#build_from_template(type, **attributes) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/esm/embed.rb', line 300

def build_from_template(type, **attributes)
  case type
  when :info
    self.color = :blue
  when :error
    self.color = :red
  when :success
    self.color = :green
  end

  attributes.each do |attr_name, attr_value|
    send(:"#{attr_name}=", attr_value)
  end
end

#for_discord_embedObject



285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/esm/embed.rb', line 285

def for_discord_embed
  {
    title: title,
    description: description,
    timestamp: timestamp.to_s,
    color: color&.sub("#", "")&.to_i(16),
    footer: footer&.to_hash,
    fields: fields.map(&:to_hash),
    author: author&.to_hash,
    thumbnail: thumbnail&.to_hash,
    image: image&.to_hash,
    url: url&.to_hash
  }
end

#set_author(name:, url: nil, icon_url: nil) ⇒ Object



203
204
205
# File 'lib/esm/embed.rb', line 203

def set_author(name:, url: nil, icon_url: nil)
  @author = Discordrb::Webhooks::EmbedAuthor.new(name: name, url: url, icon_url: icon_url)
end


195
196
197
# File 'lib/esm/embed.rb', line 195

def set_footer(text: nil, icon_url: nil)
  @footer = Discordrb::Webhooks::EmbedFooter.new(text: text, icon_url: icon_url)
end

#to_hObject



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/esm/embed.rb', line 270

def to_h
  {
    title: title,
    description: description,
    timestamp: timestamp,
    color: color,
    footer: footer&.text,
    fields: fields.map { |f| {name: f.name, value: f.value, inline: f.inline} },
    author: author&.to_hash,
    thumbnail: thumbnail,
    image: image,
    url: url
  }
end

#to_sObject



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/esm/embed.rb', line 240

def to_s
  output = ""
  output += "Title (#{title.size}): #{title}\n" if title
  output += "Description (#{description.size}): #{description}\n" if description

  if fields
    output += "Fields:\n"
    fields.each_with_index do |field, index|
      output += "\t##{index + 1}"
      output += " <inline>" if field.inline

      output += "\n\t  Name (#{field.name.size}): #{field.name}"
      output += "\n\t  Value (#{field.value.size}): #{field.value}\n"
    end
  end

  # Add the metadata
  if metadata?
    output += "Metadata:\n"
    output += "\tTimestamp: #{timestamp}\n" if timestamp
    output += "\tColor: #{color}\n" if color
    output += "\tImage: #{image.url}\n" if image
    output += "\tThumbnail: #{thumbnail.url}\n" if thumbnail
    output += "\tURL: #{url}\n" if url
    output += "\tFooter: #{footer.text}" if footer
  end

  output
end

#transfer(embed) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/esm/embed.rb', line 224

def transfer(embed)
  # And you can't do `embed = new_embed`
  embed.title = title if title
  embed.description = description if description
  embed.url = url if url
  embed.timestamp = timestamp if timestamp
  embed.color = color if color
  embed.footer = footer if footer
  embed.image = image if image
  embed.thumbnail = thumbnail if thumbnail
  embed.author = author if author
  embed.fields = fields if fields

  self
end