discorb 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +1 -1
  3. data/.github/workflows/lint-push.yml +4 -2
  4. data/.rubocop.yml +6 -2
  5. data/Changelog.md +27 -0
  6. data/Rakefile +6 -0
  7. data/docs/events.md +71 -5
  8. data/docs/faq.md +8 -8
  9. data/examples/simple/rolepanel.rb +1 -1
  10. data/examples/simple/shard.rb +17 -0
  11. data/lib/discorb/allowed_mentions.rb +7 -0
  12. data/lib/discorb/app_command/command.rb +64 -2
  13. data/lib/discorb/app_command/handler.rb +1 -1
  14. data/lib/discorb/application.rb +16 -7
  15. data/lib/discorb/asset.rb +9 -0
  16. data/lib/discorb/{file.rb → attachment.rb} +55 -33
  17. data/lib/discorb/audit_logs.rb +42 -4
  18. data/lib/discorb/channel.rb +47 -12
  19. data/lib/discorb/client.rb +135 -51
  20. data/lib/discorb/common.rb +18 -4
  21. data/lib/discorb/components/button.rb +5 -6
  22. data/lib/discorb/components/select_menu.rb +2 -16
  23. data/lib/discorb/dictionary.rb +2 -0
  24. data/lib/discorb/embed.rb +71 -38
  25. data/lib/discorb/emoji.rb +29 -2
  26. data/lib/discorb/emoji_table.rb +1 -1
  27. data/lib/discorb/error.rb +7 -1
  28. data/lib/discorb/event.rb +27 -17
  29. data/lib/discorb/exe/new.rb +5 -5
  30. data/lib/discorb/exe/run.rb +1 -15
  31. data/lib/discorb/gateway.rb +262 -161
  32. data/lib/discorb/gateway_requests.rb +4 -7
  33. data/lib/discorb/guild.rb +67 -33
  34. data/lib/discorb/guild_template.rb +24 -3
  35. data/lib/discorb/http.rb +25 -3
  36. data/lib/discorb/integration.rb +23 -8
  37. data/lib/discorb/intents.rb +15 -10
  38. data/lib/discorb/interaction/autocomplete.rb +4 -4
  39. data/lib/discorb/interaction/command.rb +34 -5
  40. data/lib/discorb/interaction/components.rb +15 -2
  41. data/lib/discorb/interaction/response.rb +12 -0
  42. data/lib/discorb/interaction/root.rb +16 -1
  43. data/lib/discorb/invite.rb +11 -7
  44. data/lib/discorb/member.rb +21 -0
  45. data/lib/discorb/message.rb +59 -3
  46. data/lib/discorb/message_meta.rb +36 -55
  47. data/lib/discorb/modules.rb +38 -14
  48. data/lib/discorb/permission.rb +14 -5
  49. data/lib/discorb/presence.rb +41 -8
  50. data/lib/discorb/rate_limit.rb +7 -2
  51. data/lib/discorb/reaction.rb +6 -0
  52. data/lib/discorb/role.rb +12 -0
  53. data/lib/discorb/shard.rb +74 -0
  54. data/lib/discorb/sticker.rb +22 -14
  55. data/lib/discorb/user.rb +11 -0
  56. data/lib/discorb/voice_state.rb +20 -2
  57. data/lib/discorb/webhook.rb +53 -2
  58. data/lib/discorb.rb +5 -3
  59. data/sig/discorb.rbs +7234 -6714
  60. metadata +5 -4
  61. data/lib/discorb/log.rb +0 -81
@@ -18,26 +18,39 @@ module Discorb
18
18
  @interaction_type = 3
19
19
  @interaction_name = :message_component
20
20
 
21
+ #
22
+ # Initialize a new message component interaction.
21
23
  # @private
24
+ #
25
+ # @param [Discorb::Client] client The client.
26
+ # @param [Hash] data The data.
27
+ #
22
28
  def initialize(client, data)
23
29
  super
24
- @message = Message.new(@client, data[:message].merge({ member: data[:member] }))
30
+ @message = Message.new(@client, data[:message].merge({ member: data[:member], guild_id: data[:guild_id] }))
25
31
  end
26
32
 
27
33
  class << self
28
34
  # @private
35
+ # @return [Integer] The component type.
29
36
  attr_reader :component_type
30
37
 
38
+ #
39
+ # Create a MessageComponentInteraction instance for the given data.
31
40
  # @private
41
+ #
32
42
  def make_interaction(client, data)
33
43
  nested_classes.each do |klass|
34
44
  return klass.new(client, data) if !klass.component_type.nil? && klass.component_type == data[:data][:component_type]
35
45
  end
36
- client.log.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
46
+ client.logger.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
37
47
  MessageComponentInteraction.new(client, data)
38
48
  end
39
49
 
50
+ #
51
+ # Returns the classes under this class.
40
52
  # @private
53
+ #
41
54
  def nested_classes
42
55
  constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
43
56
  end
@@ -74,7 +74,15 @@ module Discorb
74
74
  # Represents of a callback message of interaction.
75
75
  #
76
76
  class CallbackMessage
77
+ #
78
+ # Initializes a new instance of CallbackMessage.
77
79
  # @private
80
+ #
81
+ # @param [Client] client The client.
82
+ # @param [Hash] data The payload.
83
+ # @param [String] application_id The application ID.
84
+ # @param [String] token The token.
85
+ #
78
86
  def initialize(client, data, application_id, token)
79
87
  @client = client
80
88
  @data = data
@@ -128,6 +136,10 @@ module Discorb
128
136
  @client.http.request(Route.new("/webhooks/#{@application_id}/#{@token}/messages/@original", "//webhooks/:webhook_id/:token/messages/@original", :delete)).wait
129
137
  end
130
138
  end
139
+
140
+ def inspect
141
+ "#<#{self.class.name} application_id=#{@application_id}"
142
+ end
131
143
  end
132
144
  end
133
145
 
@@ -38,7 +38,13 @@ module Discorb
38
38
  @interaction_type = nil
39
39
  @interaction_name = nil
40
40
 
41
+ #
42
+ # Initialize a new interaction.
41
43
  # @private
44
+ #
45
+ # @param [Discorb::Client] client The client this interaction belongs to.
46
+ # @param [Hash] data The data of the interaction.
47
+ #
42
48
  def initialize(client, data)
43
49
  @client = client
44
50
  @id = Snowflake.new(data[:id])
@@ -81,20 +87,29 @@ module Discorb
81
87
  # @private
82
88
  attr_reader :interaction_type, :interaction_name, :event_name
83
89
 
90
+ #
91
+ # Create a new Interaction instance from the data.
84
92
  # @private
93
+ #
94
+ # @param [Discorb::Client] client The client this interaction belongs to.
95
+ # @param [Hash] data The data of the interaction.
96
+ #
85
97
  def make_interaction(client, data)
86
98
  interaction = nil
87
99
  descendants.each do |klass|
88
100
  interaction = klass.make_interaction(client, data) if !klass.interaction_type.nil? && klass.interaction_type == data[:type]
89
101
  end
90
102
  if interaction.nil?
91
- client.log.warn("Unknown interaction type #{data[:type]}, initialized Interaction")
103
+ client.logger.warn("Unknown interaction type #{data[:type]}, initialized Interaction")
92
104
  interaction = Interaction.new(client, data)
93
105
  end
94
106
  interaction
95
107
  end
96
108
 
109
+ #
110
+ # Returns the descendants of the class.
97
111
  # @private
112
+ #
98
113
  def descendants
99
114
  ObjectSpace.each_object(Class).select { |klass| klass < self }
100
115
  end
@@ -66,13 +66,22 @@ module Discorb
66
66
  # Whether the invite is temporary.
67
67
  # @return [Boolean]
68
68
 
69
- @target_types = {
69
+ # @private
70
+ # @return [{Integer => Symbol}] The mapping of target types.
71
+ TARGET_TYPES = {
70
72
  nil => :voice,
71
73
  1 => :stream,
72
74
  2 => :guild,
73
75
  }.freeze
74
76
 
77
+ #
78
+ # Initialize a new invite.
75
79
  # @private
80
+ #
81
+ # @param [Discorb::Client] client The client.
82
+ # @param [Hash] data The data of invite.
83
+ # @param [Boolean] gateway Whether the data is from gateway.
84
+ #
76
85
  def initialize(client, data, gateway)
77
86
  @client = client
78
87
  @data = data[:data]
@@ -124,7 +133,7 @@ module Discorb
124
133
  @expires_at = data[:expires_at] && Time.iso8601(data[:expires_at])
125
134
  end
126
135
  @inviter_data = data[:inviter]
127
- @target_type = self.class.target_types[data[:target_type]]
136
+ @target_type = TARGET_TYPES[data[:target_type]]
128
137
  @target_user = @client.users[data[:target_user][:id]] || User.new(@client, data[:target_user]) if data[:target_user]
129
138
  # @target_application = nil
130
139
 
@@ -137,10 +146,5 @@ module Discorb
137
146
  @temporary = data[:temporary]
138
147
  @created_at = Time.iso8601(data[:created_at])
139
148
  end
140
-
141
- class << self
142
- # @private
143
- attr_reader :target_types
144
- end
145
149
  end
146
150
  end
@@ -62,7 +62,15 @@ module Discorb
62
62
  # @!attribute [r] owner?
63
63
  # @return [Boolean] Whether the member is the owner of the guild.
64
64
 
65
+ #
66
+ # Initialize a new instance of the member.
65
67
  # @private
68
+ #
69
+ # @param [Discorb::Client] client The client.
70
+ # @param [Discorb::Snowflake] guild_id The ID of the guild.
71
+ # @param [Hash] user_data The data of the user.
72
+ # @param [Hash] member_data The data of the member.
73
+ #
66
74
  def initialize(client, guild_id, user_data, member_data)
67
75
  @guild_id = guild_id
68
76
  @client = client
@@ -248,6 +256,19 @@ module Discorb
248
256
  end
249
257
  end
250
258
 
259
+ #
260
+ # Checks if the member can manage the given role.
261
+ #
262
+ # @param [Discorb::Role] role The role.
263
+ #
264
+ # @return [Boolean] `true` if the member can manage the role.
265
+ #
266
+ def can_manage?(role)
267
+ return true if owner?
268
+ top_role = roles.max_by(&:position)
269
+ top_role.position > role.position
270
+ end
271
+
251
272
  private
252
273
 
253
274
  def _set_data(user_data, member_data)
@@ -152,7 +152,14 @@ module Discorb
152
152
  !@guild_id.nil?
153
153
  end
154
154
 
155
+ #
156
+ # Initialize a new message.
155
157
  # @private
158
+ #
159
+ # @param [Discorb::Client] client The client.
160
+ # @param [Hash] data The data of the welcome screen.
161
+ # @param [Boolean] no_cache Whether to disable caching.
162
+ #
156
163
  def initialize(client, data, no_cache: false)
157
164
  @client = client
158
165
  @data = {}
@@ -244,16 +251,17 @@ module Discorb
244
251
  # @param [Discorb::Embed] embed The embed to send.
245
252
  # @param [Array<Discorb::Embed>] embeds The embeds to send.
246
253
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
254
+ # @param [Array<Discorb::Attachment>] attachments The new attachments.
247
255
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
248
256
  # @param [Boolean] supress Whether to supress embeds.
249
257
  #
250
258
  # @return [Async::Task<void>] The task.
251
259
  #
252
- def edit(content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
253
- components: nil, supress: nil)
260
+ def edit(content = Discorb::Unset, embed: Discorb::Unset, embeds: Discorb::Unset, allowed_mentions: Discorb::Unset,
261
+ attachments: Discorb::Unset, components: Discorb::Unset, supress: Discorb::Unset)
254
262
  Async do
255
263
  channel.edit_message(@id, content, embed: embed, embeds: embeds, allowed_mentions: allowed_mentions,
256
- components: components, supress: supress).wait
264
+ attachments: attachments, components: components, supress: supress).wait
257
265
  end
258
266
  end
259
267
 
@@ -445,6 +453,54 @@ module Discorb
445
453
  "#<#{self.class} #{@content.inspect} id=#{@id}>"
446
454
  end
447
455
 
456
+ private
457
+
458
+ def _set_data(data)
459
+ @id = Snowflake.new(data[:id])
460
+ @channel_id = data[:channel_id]
461
+
462
+ if data[:guild_id]
463
+ @guild_id = data[:guild_id]
464
+ @dm = nil
465
+ else
466
+ @dm = Discorb::DMChannel.new(@client, data[:channel_id])
467
+ @guild_id = nil
468
+ end
469
+
470
+ if data[:member].nil? && data[:webhook_id]
471
+ @webhook_id = Snowflake.new(data[:webhook_id])
472
+ @author = Webhook::Message::Author.new(data[:author])
473
+ elsif data[:guild_id].nil? || data[:guild_id].empty? || data[:member].nil?
474
+ @author = @client.users[data[:author][:id]] || User.new(@client, data[:author])
475
+ else
476
+ @author = guild&.members&.get(data[:author][:id]) || Member.new(@client,
477
+ @guild_id, data[:author], data[:member])
478
+ end
479
+ @content = data[:content]
480
+ @created_at = Time.iso8601(data[:timestamp])
481
+ @updated_at = data[:edited_timestamp].nil? ? nil : Time.iso8601(data[:edited_timestamp])
482
+
483
+ @tts = data[:tts]
484
+ @mention_everyone = data[:mention_everyone]
485
+ @mention_roles = data[:mention_roles].map { |r| guild.roles[r] }
486
+ @attachments = data[:attachments].map { |a| Attachment.from_hash(a) }
487
+ @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : []
488
+ @reactions = data[:reactions] ? data[:reactions].map { |r| Reaction.new(self, r) } : []
489
+ @pinned = data[:pinned]
490
+ @type = self.class.message_type[data[:type]]
491
+ @activity = data[:activity] && Activity.new(data[:activity])
492
+ @application_id = data[:application_id]
493
+ @message_reference = data[:message_reference] && Reference.from_hash(data[:message_reference])
494
+ @flag = Flag.new(0b111 - data[:flags])
495
+ @sticker_items = data[:sticker_items] ? data[:sticker_items].map { |s| Message::Sticker.new(s) } : []
496
+ # @referenced_message = data[:referenced_message] && Message.new(@client, data[:referenced_message])
497
+ @interaction = data[:interaction] && Message::Interaction.new(@client, data[:interaction])
498
+ @thread = data[:thread] && Channel.make_channel(@client, data[:thread])
499
+ @components = data[:components].map { |c| c[:components].map { |co| Component.from_hash(co) } }
500
+ @data.update(data)
501
+ @deleted = false
502
+ end
503
+
448
504
  class << self
449
505
  # @private
450
506
  attr_reader :message_type
@@ -88,74 +88,39 @@ module Discorb
88
88
  def self.from_hash(data)
89
89
  new(data[:guild_id], data[:channel_id], data[:message_id], fail_if_not_exists: data[:fail_if_not_exists])
90
90
  end
91
+
92
+ def inspect
93
+ "#<#{self.class.name} #{@channel_id}/#{@message_id}>"
94
+ end
91
95
  end
92
96
 
93
97
  #
94
98
  # Represents a sticker.
95
99
  #
96
100
  class Sticker
97
- attr_reader :id, :name, :format
101
+ # @return [Discorb::Snowflake] The sticker ID.
102
+ attr_reader :id
103
+ # @return [String] The sticker name.
104
+ attr_reader :name
105
+ # @return [Symbol] The sticker format.
106
+ attr_reader :format
98
107
 
99
108
  def initialize(data)
100
109
  @id = Snowflake.new(data[:id])
101
110
  @name = data[:name]
102
- @format = Discorb::Sticker.sticker_format[data[:format]]
103
- end
104
- end
105
-
106
- private
107
-
108
- def _set_data(data)
109
- @id = Snowflake.new(data[:id])
110
- @channel_id = data[:channel_id]
111
-
112
- if data[:guild_id]
113
- @guild_id = data[:guild_id]
114
- @dm = nil
115
- else
116
- @dm = Discorb::DMChannel.new(@client, data[:channel_id])
117
- @guild_id = nil
111
+ @format = Discorb::Sticker::STICKER_FORMAT[data[:format]]
118
112
  end
119
113
 
120
- if data[:member].nil? && data[:webhook_id]
121
- @webhook_id = Snowflake.new(data[:webhook_id])
122
- @author = Webhook::Message::Author.new(data[:author])
123
- elsif data[:guild_id].nil? || data[:guild_id].empty? || data[:member].nil?
124
- @author = @client.users[data[:author][:id]] || User.new(@client, data[:author])
125
- else
126
- @author = guild&.members&.get(data[:author][:id]) || Member.new(@client,
127
- @guild_id, data[:author], data[:member])
114
+ def inspect
115
+ "#<#{self.class.name} #{@id}: #{@name} format=#{@format}>"
128
116
  end
129
- @content = data[:content]
130
- @created_at = Time.iso8601(data[:timestamp])
131
- @updated_at = data[:edited_timestamp].nil? ? nil : Time.iso8601(data[:edited_timestamp])
132
-
133
- @tts = data[:tts]
134
- @mention_everyone = data[:mention_everyone]
135
- @mention_roles = data[:mention_roles].map { |r| guild.roles[r] }
136
- @attachments = data[:attachments].map { |a| Attachment.new(a) }
137
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : []
138
- @reactions = data[:reactions] ? data[:reactions].map { |r| Reaction.new(self, r) } : []
139
- @pinned = data[:pinned]
140
- @type = self.class.message_type[data[:type]]
141
- @activity = data[:activity] && Activity.new(data[:activity])
142
- @application_id = data[:application_id]
143
- @message_reference = data[:message_reference] && Reference.from_hash(data[:message_reference])
144
- @flag = Flag.new(0b111 - data[:flags])
145
- @sticker_items = data[:sticker_items] ? data[:sticker_items].map { |s| Message::Sticker.new(s) } : []
146
- # @referenced_message = data[:referenced_message] && Message.new(@client, data[:referenced_message])
147
- @interaction = data[:interaction] && Message::Interaction.new(@client, data[:interaction])
148
- @thread = data[:thread] && Channel.make_channel(@client, data[:thread])
149
- @components = data[:components].map { |c| c[:components].map { |co| Component.from_hash(co) } }
150
- @data.update(data)
151
- @deleted = false
152
117
  end
153
118
 
154
119
  #
155
120
  # Represents a interaction of message.
156
121
  #
157
122
  class Interaction < DiscordModel
158
- # @return [Discorb::Snowflake] The user ID.
123
+ # @return [Discorb::Snowflake] The interaction ID.
159
124
  attr_reader :id
160
125
  # @return [String] The name of command.
161
126
  # @return [nil] If the message is not a command.
@@ -165,13 +130,23 @@ module Discorb
165
130
  # @return [Discorb::User] The user.
166
131
  attr_reader :user
167
132
 
133
+ #
134
+ # Initialize a new interaction.
168
135
  # @private
136
+ #
137
+ # @param [Discorb::Client] client The client.
138
+ # @param [Hash] data The interaction data.
139
+ #
169
140
  def initialize(client, data)
170
141
  @id = Snowflake.new(data[:id])
171
142
  @name = data[:name]
172
143
  @type = Discorb::Interaction.descendants.find { |c| c.interaction_type == data[:type] }
173
144
  @user = client.users[data[:user][:id]] || User.new(client, data[:user])
174
145
  end
146
+
147
+ def inspect
148
+ "<#{self.class.name} #{@id}: #{@name} type=#{@type} #{@user}>"
149
+ end
175
150
  end
176
151
 
177
152
  #
@@ -183,22 +158,28 @@ module Discorb
183
158
  # @return [Symbol] The type of activity.
184
159
  attr_reader :type
185
160
 
186
- @type = {
161
+ # @private
162
+ # @return [{Integer => Symbol}] The mapping of activity type.
163
+ TYPES = {
187
164
  1 => :join,
188
165
  2 => :spectate,
189
166
  3 => :listen,
190
167
  5 => :join_request,
191
- }
168
+ }.freeze
192
169
 
170
+ #
171
+ # Initialize a new activity.
193
172
  # @private
173
+ #
174
+ # @param [Hash] data The activity data.
175
+ #
194
176
  def initialize(data)
195
177
  @name = data[:name]
196
- @type = self.class.type(data[:type])
178
+ @type = TYPES[data[:type]]
197
179
  end
198
180
 
199
- class << self
200
- # @private
201
- attr_reader :type
181
+ def inspect
182
+ "<#{self.class.name} #{@name} type=#{@type}>"
202
183
  end
203
184
  end
204
185
  end
@@ -16,13 +16,13 @@ module Discorb
16
16
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
17
17
  # @param [Discorb::Message, Discorb::Message::Reference] reference The message to reply to.
18
18
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
19
- # @param [Discorb::File] file The file to send.
20
- # @param [Array<Discorb::File>] files The files to send.
19
+ # @param [Discorb::Attachment] attachment The attachment to send.
20
+ # @param [Array<Discorb::Attachment>] attachments The attachments to send.
21
21
  #
22
22
  # @return [Async::Task<Discorb::Message>] The message sent.
23
23
  #
24
24
  def post(content = nil, tts: false, embed: nil, embeds: nil, allowed_mentions: nil,
25
- reference: nil, components: nil, file: nil, files: nil)
25
+ reference: nil, components: nil, attachment: nil, attachments: nil)
26
26
  Async do
27
27
  payload = {}
28
28
  payload[:content] = content if content
@@ -37,8 +37,17 @@ module Discorb
37
37
  allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
38
38
  payload[:message_reference] = reference.to_reference if reference
39
39
  payload[:components] = Component.to_payload(components) if components
40
- files = [file]
41
- _resp, data = @client.http.multipart_request(Route.new("/channels/#{channel_id.wait}/messages", "//channels/:channel_id/messages", :post), payload, files).wait
40
+ attachments ||= attachment ? [attachment] : []
41
+
42
+ payload[:attachments] = attachments.map.with_index do |a, i|
43
+ {
44
+ id: i,
45
+ filename: a.filename,
46
+ description: a.description,
47
+ }
48
+ end
49
+
50
+ _resp, data = @client.http.multipart_request(Route.new("/channels/#{channel_id.wait}/messages", "//channels/:channel_id/messages", :post), payload, attachments).wait
42
51
  Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
43
52
  end
44
53
  end
@@ -48,33 +57,48 @@ module Discorb
48
57
  #
49
58
  # Edit a message.
50
59
  # @async
60
+ # @!macro edit
51
61
  #
52
62
  # @param [#to_s] message_id The message id.
53
63
  # @param [String] content The message content.
54
64
  # @param [Discorb::Embed] embed The embed to send.
55
65
  # @param [Array<Discorb::Embed>] embeds The embeds to send.
56
66
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
67
+ # @param [Array<Discorb::Attachment>] attachments The new attachments.
57
68
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
58
69
  # @param [Boolean] supress Whether to supress embeds.
59
70
  #
60
71
  # @return [Async::Task<void>] The task.
61
72
  #
62
- def edit_message(message_id, content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
63
- components: nil, supress: nil)
73
+ def edit_message(message_id, content = Discorb::Unset, embed: Discorb::Unset, embeds: Discorb::Unset, allowed_mentions: Discorb::Unset,
74
+ attachments: Discorb::Unset, components: Discorb::Unset, supress: Discorb::Unset)
64
75
  Async do
65
76
  payload = {}
66
- payload[:content] = content if content
67
- tmp_embed = if embed
77
+ payload[:content] = content if content != Discorb::Unset
78
+ tmp_embed = if embed != Discorb::Unset
68
79
  [embed]
69
- elsif embeds
80
+ elsif embeds != Discorb::Unset
70
81
  embeds
71
82
  end
72
83
  payload[:embeds] = tmp_embed.map(&:to_hash) if tmp_embed
73
84
  payload[:allowed_mentions] =
74
- allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
75
- payload[:components] = Component.to_payload(components) if components
76
- payload[:flags] = (supress ? 1 << 2 : 0) unless supress.nil?
77
- @client.http.request(Route.new("/channels/#{channel_id.wait}/messages/#{message_id}", "//channels/:channel_id/messages/:message_id", :patch), payload).wait
85
+ allowed_mentions == Discorb::Unset ? @client.allowed_mentions.to_hash : allowed_mentions.to_hash(@client.allowed_mentions)
86
+ payload[:components] = Component.to_payload(components) if components != Discorb::Unset
87
+ payload[:flags] = (supress ? 1 << 2 : 0) if supress != Discorb::Unset
88
+ if attachments != Discorb::Unset
89
+ payload[:attachments] = attachments.map.with_index do |a, i|
90
+ {
91
+ id: i,
92
+ filename: a.filename,
93
+ description: a.description,
94
+ }
95
+ end
96
+ end
97
+ @client.http.multipart_request(
98
+ Route.new("/channels/#{channel_id.wait}/messages/#{message_id}", "//channels/:channel_id/messages/:message_id", :patch),
99
+ payload,
100
+ attachments == Discorb::Unset ? [] : attachments
101
+ ).wait
78
102
  end
79
103
  end
80
104
 
@@ -138,7 +138,13 @@ module Discorb
138
138
  }.freeze
139
139
  @bits = @raw_bits.transform_values { |v| 1 << v }.freeze
140
140
 
141
+ #
142
+ # Initializes a new PermissionOverwrite.
141
143
  # @private
144
+ #
145
+ # @param allow [Integer] The allowed permissions.
146
+ # @param deny [Integer] The denied permissions.
147
+ #
142
148
  def initialize(allow, deny)
143
149
  @allow = allow
144
150
  @deny = deny
@@ -175,11 +181,14 @@ module Discorb
175
181
  #
176
182
  def to_hash
177
183
  self.class.bits.keys.to_h do |field|
178
- [field, if @allow & self.class.bits[field] != 0
179
- true
180
- elsif @deny & self.class.bits[method] != 0
181
- false
182
- end]
184
+ [
185
+ field,
186
+ if @allow & self.class.bits[field] != 0
187
+ true
188
+ elsif @deny & self.class.bits[field] != 0
189
+ false
190
+ end,
191
+ ]
183
192
  end
184
193
  end
185
194
 
@@ -19,7 +19,13 @@ module Discorb
19
19
  # @!attribute [r] activity
20
20
  # @return [Discorb::Presence::Activity] The activity of the presence.
21
21
 
22
+ #
23
+ # Initialize a presence.
22
24
  # @private
25
+ #
26
+ # @param [Discorb::Client] client The client.
27
+ # @param [Hash] data The data of the presence.
28
+ #
23
29
  def initialize(client, data)
24
30
  @client = client
25
31
  @data = data
@@ -80,19 +86,26 @@ module Discorb
80
86
  # @return [Discorb::Presence::Activity::Flag] The flags of the activity.
81
87
  attr_reader :flags
82
88
 
83
- @activity_types = {
89
+ # @private
90
+ # @return [{Integer => Symbol}] The mapping of activity types.
91
+ ACTIVITY_TYPES = {
84
92
  0 => :game,
85
93
  1 => :streaming,
86
94
  2 => :listening,
87
95
  3 => :watching,
88
96
  4 => :custom,
89
97
  5 => :competing,
90
- }
98
+ }.freeze
91
99
 
100
+ #
101
+ # Initialize the activity.
92
102
  # @private
103
+ #
104
+ # @param [Hash] data The activity data.
105
+ #
93
106
  def initialize(data)
94
107
  @name = data[:name]
95
- @type = self.class.activity_types[data[:type]]
108
+ @type = ACTIVITY_TYPES[data[:type]]
96
109
  @url = data[:url]
97
110
  @created_at = Time.at(data[:created_at])
98
111
  @timestamps = data[:timestamps] && Timestamps.new(data[:timestamps])
@@ -140,7 +153,12 @@ module Discorb
140
153
  # @return [Time] The end time of the activity.
141
154
  attr_reader :end
142
155
 
156
+ #
157
+ # Initialize the timestamps.
143
158
  # @private
159
+ #
160
+ # @param [Hash] data The timestamps data.
161
+ #
144
162
  def initialize(data)
145
163
  @start = data[:start] && Time.at(data[:start])
146
164
  @end = data[:end] && Time.at(data[:end])
@@ -159,7 +177,12 @@ module Discorb
159
177
  # @!attribute [r] max_size
160
178
  # @return [Integer] The max size of the party.
161
179
 
180
+ #
181
+ # Initialize the party.
162
182
  # @private
183
+ #
184
+ # @param [Hash] data The party data.
185
+ #
163
186
  def initialize(data)
164
187
  @id = data[:id]
165
188
  @size = data[:size]
@@ -229,7 +252,12 @@ module Discorb
229
252
  # @return [String] The match secret of the activity.
230
253
  attr_reader :match
231
254
 
255
+ #
256
+ # Initialize the secrets.
232
257
  # @private
258
+ #
259
+ # @param [Hash] data The secrets data.
260
+ #
233
261
  def initialize(data)
234
262
  @join = data[:join]
235
263
  @spectate = data[:spectate]
@@ -247,17 +275,17 @@ module Discorb
247
275
  attr_reader :url
248
276
  alias text label
249
277
 
278
+ #
279
+ # Initialize the button.
250
280
  # @private
281
+ #
282
+ # @param [Hash] data The button data.
283
+ #
251
284
  def initialize(data)
252
285
  @label = data[0]
253
286
  @url = data[1]
254
287
  end
255
288
  end
256
-
257
- class << self
258
- # @private
259
- attr_reader :activity_types
260
- end
261
289
  end
262
290
 
263
291
  #
@@ -278,7 +306,12 @@ module Discorb
278
306
  # @!attribute [r] web?
279
307
  # @return [Boolean] Whether the user is not offline on web.
280
308
 
309
+ #
310
+ # Initialize the client status.
281
311
  # @private
312
+ #
313
+ # @param [Hash] data The client status data.
314
+ #
282
315
  def initialize(data)
283
316
  @desktop = data[:desktop]&.to_sym || :offline
284
317
  @mobile = data[:mobile]&.to_sym || :offline