discorb 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +10 -0
  5. data/Rakefile +482 -454
  6. data/lib/discorb/allowed_mentions.rb +68 -72
  7. data/lib/discorb/app_command/command.rb +466 -398
  8. data/lib/discorb/app_command/common.rb +65 -25
  9. data/lib/discorb/app_command/handler.rb +304 -266
  10. data/lib/discorb/app_command.rb +5 -5
  11. data/lib/discorb/application.rb +198 -197
  12. data/lib/discorb/asset.rb +101 -101
  13. data/lib/discorb/attachment.rb +134 -119
  14. data/lib/discorb/audit_logs.rb +412 -385
  15. data/lib/discorb/automod.rb +279 -269
  16. data/lib/discorb/channel/base.rb +107 -108
  17. data/lib/discorb/channel/category.rb +32 -32
  18. data/lib/discorb/channel/container.rb +44 -44
  19. data/lib/discorb/channel/dm.rb +26 -28
  20. data/lib/discorb/channel/guild.rb +311 -246
  21. data/lib/discorb/channel/stage.rb +156 -140
  22. data/lib/discorb/channel/text.rb +430 -336
  23. data/lib/discorb/channel/thread.rb +374 -325
  24. data/lib/discorb/channel/voice.rb +85 -79
  25. data/lib/discorb/channel.rb +5 -5
  26. data/lib/discorb/client.rb +635 -621
  27. data/lib/discorb/color.rb +178 -182
  28. data/lib/discorb/common.rb +168 -164
  29. data/lib/discorb/components/button.rb +107 -106
  30. data/lib/discorb/components/select_menu.rb +157 -145
  31. data/lib/discorb/components/text_input.rb +103 -106
  32. data/lib/discorb/components.rb +68 -66
  33. data/lib/discorb/dictionary.rb +135 -135
  34. data/lib/discorb/embed.rb +404 -398
  35. data/lib/discorb/emoji.rb +309 -302
  36. data/lib/discorb/emoji_table.rb +16099 -8857
  37. data/lib/discorb/error.rb +131 -131
  38. data/lib/discorb/event.rb +360 -314
  39. data/lib/discorb/event_handler.rb +39 -39
  40. data/lib/discorb/exe/about.rb +17 -17
  41. data/lib/discorb/exe/irb.rb +72 -67
  42. data/lib/discorb/exe/new.rb +323 -315
  43. data/lib/discorb/exe/run.rb +69 -68
  44. data/lib/discorb/exe/setup.rb +57 -55
  45. data/lib/discorb/exe/show.rb +12 -12
  46. data/lib/discorb/extend.rb +25 -45
  47. data/lib/discorb/extension.rb +89 -83
  48. data/lib/discorb/flag.rb +126 -128
  49. data/lib/discorb/gateway.rb +984 -804
  50. data/lib/discorb/gateway_events.rb +670 -638
  51. data/lib/discorb/gateway_requests.rb +45 -48
  52. data/lib/discorb/guild.rb +2115 -1626
  53. data/lib/discorb/guild_template.rb +280 -241
  54. data/lib/discorb/http.rb +247 -232
  55. data/lib/discorb/image.rb +42 -42
  56. data/lib/discorb/integration.rb +169 -161
  57. data/lib/discorb/intents.rb +161 -163
  58. data/lib/discorb/interaction/autocomplete.rb +76 -62
  59. data/lib/discorb/interaction/command.rb +279 -224
  60. data/lib/discorb/interaction/components.rb +114 -104
  61. data/lib/discorb/interaction/modal.rb +36 -32
  62. data/lib/discorb/interaction/response.rb +379 -336
  63. data/lib/discorb/interaction/root.rb +271 -257
  64. data/lib/discorb/interaction.rb +5 -5
  65. data/lib/discorb/invite.rb +154 -153
  66. data/lib/discorb/member.rb +344 -311
  67. data/lib/discorb/message.rb +615 -544
  68. data/lib/discorb/message_meta.rb +197 -186
  69. data/lib/discorb/modules.rb +371 -290
  70. data/lib/discorb/permission.rb +305 -291
  71. data/lib/discorb/presence.rb +352 -346
  72. data/lib/discorb/rate_limit.rb +81 -76
  73. data/lib/discorb/reaction.rb +55 -54
  74. data/lib/discorb/role.rb +272 -240
  75. data/lib/discorb/shard.rb +76 -74
  76. data/lib/discorb/sticker.rb +193 -171
  77. data/lib/discorb/user.rb +205 -188
  78. data/lib/discorb/utils/colored_puts.rb +16 -16
  79. data/lib/discorb/utils.rb +12 -16
  80. data/lib/discorb/voice_state.rb +305 -281
  81. data/lib/discorb/webhook.rb +537 -507
  82. data/lib/discorb.rb +62 -56
  83. data/sig/discorb/application.rbs +2 -0
  84. data/sig/discorb/automod.rbs +10 -1
  85. data/sig/discorb/guild.rbs +2 -0
  86. data/sig/discorb/message.rbs +2 -0
  87. data/sig/discorb/user.rbs +22 -20
  88. metadata +2 -2
@@ -1,346 +1,352 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a presence of user.
6
- #
7
- class Presence < DiscordModel
8
- # @return [:online, :idle, :dnd, :offline] The status of the user.
9
- attr_reader :status
10
- # @return [Array<Discorb::Presence::Activity>] The activities of the user.
11
- attr_reader :activities
12
- # @return [Discorb::Presence::ClientStatus] The client status of the user.
13
- attr_reader :client_status
14
-
15
- # @!attribute [r] user
16
- # @return [Discorb::User] The user of the presence.
17
- # @!attribute [r] guild
18
- # @return [Discorb::Guild] The guild of the presence.
19
- # @!attribute [r] activity
20
- # @return [Discorb::Presence::Activity] The activity of the presence.
21
-
22
- #
23
- # Initialize a presence.
24
- # @private
25
- #
26
- # @param [Discorb::Client] client The client.
27
- # @param [Hash] data The data of the presence.
28
- #
29
- def initialize(client, data)
30
- @client = client
31
- @data = data
32
- _set_data(data)
33
- end
34
-
35
- def user
36
- @client.users[@user_id]
37
- end
38
-
39
- def guild
40
- @client.guilds[@guild_id]
41
- end
42
-
43
- def activity
44
- @activities[0]
45
- end
46
-
47
- def inspect
48
- "#<#{self.class} @status=#{@status.inspect} @activity=#{activity.inspect}>"
49
- end
50
-
51
- #
52
- # Represents an activity of a user.
53
- #
54
- class Activity < DiscordModel
55
- # @return [String] The name of the activity.
56
- attr_reader :name
57
- # @return [:game, :streaming, :listening, :watching, :custom, :competing] The type of the activity.
58
- attr_reader :type
59
- # @return [String] The url of the activity.
60
- attr_reader :url
61
- # @return [Time] The time the activity was created.
62
- attr_reader :created_at
63
- alias started_at created_at
64
- # @return [Discorb::Presence::Activity::Timestamps] The timestamps of the activity.
65
- attr_reader :timestamps
66
- # @return [Discorb::Snowflake] The application id of the activity.
67
- attr_reader :application_id
68
- # @return [String] The details of the activity.
69
- attr_reader :details
70
- # @return [String] The state of party.
71
- attr_reader :state
72
- # @return [Discorb::Emoji] The emoji of the activity.
73
- attr_reader :emoji
74
- # @return [Discorb::Presence::Activity::Party] The party of the activity.
75
- # @return [nil] If the activity is not a party activity.
76
- attr_reader :party
77
- # @return [Discorb::Presence::Activity::Asset] The assets of the activity.
78
- # @return [nil] If the activity has no assets.
79
- attr_reader :assets
80
- # @return [Discorb::StageInstance] The instance of the activity.
81
- # @return [nil] If the activity is not a stage activity.
82
- attr_reader :instance
83
- # @return [Array<Discorb::Presence::Activity::Button>] The buttons of the activity.
84
- # @return [nil] If the activity has no buttons.
85
- attr_reader :buttons
86
- # @return [Discorb::Presence::Activity::Flag] The flags of the activity.
87
- attr_reader :flags
88
-
89
- # @private
90
- # @return [{Integer => Symbol}] The mapping of activity types.
91
- ACTIVITY_TYPES = {
92
- 0 => :game,
93
- 1 => :streaming,
94
- 2 => :listening,
95
- 3 => :watching,
96
- 4 => :custom,
97
- 5 => :competing,
98
- }.freeze
99
-
100
- #
101
- # Initialize the activity.
102
- # @private
103
- #
104
- # @param [Hash] data The activity data.
105
- #
106
- def initialize(data)
107
- @name = data[:name]
108
- @type = ACTIVITY_TYPES[data[:type]]
109
- @url = data[:url]
110
- @created_at = Time.at(data[:created_at])
111
- @timestamps = data[:timestamps] && Timestamps.new(data[:timestamps])
112
- @application_id = data[:application_id] && Snowflake.new(data[:application_id])
113
- @details = data[:details]
114
- @state = data[:state]
115
- @emoji = if data[:emoji]
116
- data[:emoji][:id].nil? ? UnicodeEmoji.new(data[:emoji][:name]) : PartialEmoji.new(data[:emoji])
117
- end
118
- @party = data[:party] && Party.new(data[:party])
119
- @assets = data[:assets] && Asset.new(data[:assets])
120
- @instance = data[:instance]
121
- @buttons = data[:buttons]&.map { |b| Button.new(b) }
122
- @flags = data[:flags] && Flag.new(data[:flags])
123
- end
124
-
125
- #
126
- # Convert the activity to a string.
127
- #
128
- # @return [String] The string representation of the activity.
129
- #
130
- def to_s
131
- case @type
132
- when :game
133
- "Playing #{@name}"
134
- when :streaming
135
- "Streaming #{@details}"
136
- when :listening
137
- "Listening to #{@name}"
138
- when :watching
139
- "Watching #{@name}"
140
- when :custom
141
- "#{@emoji} #{@state}"
142
- when :competing
143
- "Competing in #{@name}"
144
- else
145
- raise "Unknown activity type: #{@type}"
146
- end
147
- end
148
-
149
- #
150
- # Represents the timestamps of an activity.
151
- #
152
- class Timestamps < DiscordModel
153
- # @return [Time] The start time of the activity.
154
- attr_reader :start
155
- # @return [Time] The end time of the activity.
156
- attr_reader :end
157
-
158
- #
159
- # Initialize the timestamps.
160
- # @private
161
- #
162
- # @param [Hash] data The timestamps data.
163
- #
164
- def initialize(data)
165
- @start = data[:start] && Time.at(data[:start])
166
- @end = data[:end] && Time.at(data[:end])
167
- end
168
- end
169
-
170
- #
171
- # Represents the party of an activity.
172
- #
173
- class Party < DiscordModel
174
- # @return [String] The id of the party.
175
- attr_reader :id
176
-
177
- # @!attribute [r] current_size
178
- # @return [Integer] The current size of the party.
179
- # @!attribute [r] max_size
180
- # @return [Integer] The max size of the party.
181
-
182
- #
183
- # Initialize the party.
184
- # @private
185
- #
186
- # @param [Hash] data The party data.
187
- #
188
- def initialize(data)
189
- @id = data[:id]
190
- @size = data[:size]
191
- end
192
-
193
- def current_size
194
- @size[0]
195
- end
196
-
197
- def max_size
198
- @size[1]
199
- end
200
- end
201
-
202
- #
203
- # Represents the assets of an activity.
204
- #
205
- class Asset < DiscordModel
206
- # @return [String] The large image ID or URL of the asset.
207
- attr_reader :large_image
208
- alias large_id large_image
209
- # @return [String] The large text of the activity.
210
- attr_reader :large_text
211
- # @return [String] The small image ID or URL of the activity.
212
- attr_reader :small_image
213
- alias small_id small_image
214
- # @return [String] The small text of the activity.
215
- attr_reader :small_text
216
-
217
- def initialize(data)
218
- @large_image = data[:large_image]
219
- @large_text = data[:large_text]
220
- @small_image = data[:small_image]
221
- @small_text = data[:small_text]
222
- end
223
- end
224
-
225
- #
226
- # Represents the flags of an activity.
227
- # ## Flag fields
228
- # |`1 << 0`|`:instance`|
229
- # |`1 << 1`|`:join`|
230
- # |`1 << 2`|`:spectate`|
231
- # |`1 << 3`|`:join_request`|
232
- # |`1 << 4`|`:sync`|
233
- # |`1 << 5`|`:play`|
234
- #
235
- class Flag < Discorb::Flag
236
- @bits = {
237
- instance: 0,
238
- join: 1,
239
- spectate: 2,
240
- join_request: 3,
241
- sync: 4,
242
- play: 5,
243
- }
244
- end
245
-
246
- #
247
- # Represents a secrets of an activity.
248
- #
249
- class Secrets < DiscordModel
250
- # @return [String] The join secret of the activity.
251
- attr_reader :join
252
- # @return [String] The spectate secret of the activity.
253
- attr_reader :spectate
254
- # @return [String] The match secret of the activity.
255
- attr_reader :match
256
-
257
- #
258
- # Initialize the secrets.
259
- # @private
260
- #
261
- # @param [Hash] data The secrets data.
262
- #
263
- def initialize(data)
264
- @join = data[:join]
265
- @spectate = data[:spectate]
266
- @match = data[:match]
267
- end
268
- end
269
-
270
- #
271
- # Represents a button of an activity.
272
- #
273
- class Button < DiscordModel
274
- # @return [String] The text of the button.
275
- attr_reader :label
276
- # @return [String] The URL of the button.
277
- attr_reader :url
278
- alias text label
279
-
280
- #
281
- # Initialize the button.
282
- # @private
283
- #
284
- # @param [Hash] data The button data.
285
- #
286
- def initialize(data)
287
- @label = data[0]
288
- @url = data[1]
289
- end
290
- end
291
- end
292
-
293
- #
294
- # Represents a user's client status.
295
- #
296
- class ClientStatus < DiscordModel
297
- # @return [Symbol] The desktop status of the user.
298
- attr_reader :desktop
299
- # @return [Symbol] The mobile status of the user.
300
- attr_reader :mobile
301
- # @return [Symbol] The web status of the user.
302
- attr_reader :web
303
-
304
- # @!attribute [r] desktop?
305
- # @return [Boolean] Whether the user is not offline on desktop.
306
- # @!attribute [r] mobile?
307
- # @return [Boolean] Whether the user is not offline on mobile.
308
- # @!attribute [r] web?
309
- # @return [Boolean] Whether the user is not offline on web.
310
-
311
- #
312
- # Initialize the client status.
313
- # @private
314
- #
315
- # @param [Hash] data The client status data.
316
- #
317
- def initialize(data)
318
- @desktop = data[:desktop]&.to_sym || :offline
319
- @mobile = data[:mobile]&.to_sym || :offline
320
- @web = data[:web]&.to_sym || :offline
321
- end
322
-
323
- def desktop?
324
- @desktop != :offline
325
- end
326
-
327
- def mobile?
328
- @mobile != :offline
329
- end
330
-
331
- def web?
332
- @web != :offline
333
- end
334
- end
335
-
336
- private
337
-
338
- def _set_data(data)
339
- @user_id = data[:user][:id]
340
- @guild_id = data[:guild_id]
341
- @status = data[:status].to_sym
342
- @activities = data[:activities].map { |a| Activity.new(a) }
343
- @client_status = ClientStatus.new(data[:client_status])
344
- end
345
- end
346
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a presence of user.
6
+ #
7
+ class Presence < DiscordModel
8
+ # @return [:online, :idle, :dnd, :offline] The status of the user.
9
+ attr_reader :status
10
+ # @return [Array<Discorb::Presence::Activity>] The activities of the user.
11
+ attr_reader :activities
12
+ # @return [Discorb::Presence::ClientStatus] The client status of the user.
13
+ attr_reader :client_status
14
+
15
+ # @!attribute [r] user
16
+ # @return [Discorb::User] The user of the presence.
17
+ # @!attribute [r] guild
18
+ # @return [Discorb::Guild] The guild of the presence.
19
+ # @!attribute [r] activity
20
+ # @return [Discorb::Presence::Activity] The activity of the presence.
21
+
22
+ #
23
+ # Initialize a presence.
24
+ # @private
25
+ #
26
+ # @param [Discorb::Client] client The client.
27
+ # @param [Hash] data The data of the presence.
28
+ #
29
+ def initialize(client, data)
30
+ @client = client
31
+ @data = data
32
+ _set_data(data)
33
+ end
34
+
35
+ def user
36
+ @client.users[@user_id]
37
+ end
38
+
39
+ def guild
40
+ @client.guilds[@guild_id]
41
+ end
42
+
43
+ def activity
44
+ @activities[0]
45
+ end
46
+
47
+ def inspect
48
+ "#<#{self.class} @status=#{@status.inspect} @activity=#{activity.inspect}>"
49
+ end
50
+
51
+ #
52
+ # Represents an activity of a user.
53
+ #
54
+ class Activity < DiscordModel
55
+ # @return [String] The name of the activity.
56
+ attr_reader :name
57
+ # @return [:game, :streaming, :listening, :watching, :custom, :competing] The type of the activity.
58
+ attr_reader :type
59
+ # @return [String] The url of the activity.
60
+ attr_reader :url
61
+ # @return [Time] The time the activity was created.
62
+ attr_reader :created_at
63
+ alias started_at created_at
64
+ # @return [Discorb::Presence::Activity::Timestamps] The timestamps of the activity.
65
+ attr_reader :timestamps
66
+ # @return [Discorb::Snowflake] The application id of the activity.
67
+ attr_reader :application_id
68
+ # @return [String] The details of the activity.
69
+ attr_reader :details
70
+ # @return [String] The state of party.
71
+ attr_reader :state
72
+ # @return [Discorb::Emoji] The emoji of the activity.
73
+ attr_reader :emoji
74
+ # @return [Discorb::Presence::Activity::Party] The party of the activity.
75
+ # @return [nil] If the activity is not a party activity.
76
+ attr_reader :party
77
+ # @return [Discorb::Presence::Activity::Asset] The assets of the activity.
78
+ # @return [nil] If the activity has no assets.
79
+ attr_reader :assets
80
+ # @return [Discorb::StageInstance] The instance of the activity.
81
+ # @return [nil] If the activity is not a stage activity.
82
+ attr_reader :instance
83
+ # @return [Array<Discorb::Presence::Activity::Button>] The buttons of the activity.
84
+ # @return [nil] If the activity has no buttons.
85
+ attr_reader :buttons
86
+ # @return [Discorb::Presence::Activity::Flag] The flags of the activity.
87
+ attr_reader :flags
88
+
89
+ # @private
90
+ # @return [{Integer => Symbol}] The mapping of activity types.
91
+ ACTIVITY_TYPES = {
92
+ 0 => :game,
93
+ 1 => :streaming,
94
+ 2 => :listening,
95
+ 3 => :watching,
96
+ 4 => :custom,
97
+ 5 => :competing
98
+ }.freeze
99
+
100
+ #
101
+ # Initialize the activity.
102
+ # @private
103
+ #
104
+ # @param [Hash] data The activity data.
105
+ #
106
+ def initialize(data)
107
+ @name = data[:name]
108
+ @type = ACTIVITY_TYPES[data[:type]]
109
+ @url = data[:url]
110
+ @created_at = Time.at(data[:created_at])
111
+ @timestamps = data[:timestamps] && Timestamps.new(data[:timestamps])
112
+ @application_id =
113
+ data[:application_id] && Snowflake.new(data[:application_id])
114
+ @details = data[:details]
115
+ @state = data[:state]
116
+ @emoji =
117
+ if data[:emoji]
118
+ if data[:emoji][:id].nil?
119
+ UnicodeEmoji.new(data[:emoji][:name])
120
+ else
121
+ PartialEmoji.new(data[:emoji])
122
+ end
123
+ end
124
+ @party = data[:party] && Party.new(data[:party])
125
+ @assets = data[:assets] && Asset.new(data[:assets])
126
+ @instance = data[:instance]
127
+ @buttons = data[:buttons]&.map { |b| Button.new(b) }
128
+ @flags = data[:flags] && Flag.new(data[:flags])
129
+ end
130
+
131
+ #
132
+ # Convert the activity to a string.
133
+ #
134
+ # @return [String] The string representation of the activity.
135
+ #
136
+ def to_s
137
+ case @type
138
+ when :game
139
+ "Playing #{@name}"
140
+ when :streaming
141
+ "Streaming #{@details}"
142
+ when :listening
143
+ "Listening to #{@name}"
144
+ when :watching
145
+ "Watching #{@name}"
146
+ when :custom
147
+ "#{@emoji} #{@state}"
148
+ when :competing
149
+ "Competing in #{@name}"
150
+ else
151
+ raise "Unknown activity type: #{@type}"
152
+ end
153
+ end
154
+
155
+ #
156
+ # Represents the timestamps of an activity.
157
+ #
158
+ class Timestamps < DiscordModel
159
+ # @return [Time] The start time of the activity.
160
+ attr_reader :start
161
+ # @return [Time] The end time of the activity.
162
+ attr_reader :end
163
+
164
+ #
165
+ # Initialize the timestamps.
166
+ # @private
167
+ #
168
+ # @param [Hash] data The timestamps data.
169
+ #
170
+ def initialize(data)
171
+ @start = data[:start] && Time.at(data[:start])
172
+ @end = data[:end] && Time.at(data[:end])
173
+ end
174
+ end
175
+
176
+ #
177
+ # Represents the party of an activity.
178
+ #
179
+ class Party < DiscordModel
180
+ # @return [String] The id of the party.
181
+ attr_reader :id
182
+
183
+ # @!attribute [r] current_size
184
+ # @return [Integer] The current size of the party.
185
+ # @!attribute [r] max_size
186
+ # @return [Integer] The max size of the party.
187
+
188
+ #
189
+ # Initialize the party.
190
+ # @private
191
+ #
192
+ # @param [Hash] data The party data.
193
+ #
194
+ def initialize(data)
195
+ @id = data[:id]
196
+ @size = data[:size]
197
+ end
198
+
199
+ def current_size
200
+ @size[0]
201
+ end
202
+
203
+ def max_size
204
+ @size[1]
205
+ end
206
+ end
207
+
208
+ #
209
+ # Represents the assets of an activity.
210
+ #
211
+ class Asset < DiscordModel
212
+ # @return [String] The large image ID or URL of the asset.
213
+ attr_reader :large_image
214
+ alias large_id large_image
215
+ # @return [String] The large text of the activity.
216
+ attr_reader :large_text
217
+ # @return [String] The small image ID or URL of the activity.
218
+ attr_reader :small_image
219
+ alias small_id small_image
220
+ # @return [String] The small text of the activity.
221
+ attr_reader :small_text
222
+
223
+ def initialize(data)
224
+ @large_image = data[:large_image]
225
+ @large_text = data[:large_text]
226
+ @small_image = data[:small_image]
227
+ @small_text = data[:small_text]
228
+ end
229
+ end
230
+
231
+ #
232
+ # Represents the flags of an activity.
233
+ # ## Flag fields
234
+ # |`1 << 0`|`:instance`|
235
+ # |`1 << 1`|`:join`|
236
+ # |`1 << 2`|`:spectate`|
237
+ # |`1 << 3`|`:join_request`|
238
+ # |`1 << 4`|`:sync`|
239
+ # |`1 << 5`|`:play`|
240
+ #
241
+ class Flag < Discorb::Flag
242
+ @bits = {
243
+ instance: 0,
244
+ join: 1,
245
+ spectate: 2,
246
+ join_request: 3,
247
+ sync: 4,
248
+ play: 5
249
+ }
250
+ end
251
+
252
+ #
253
+ # Represents a secrets of an activity.
254
+ #
255
+ class Secrets < DiscordModel
256
+ # @return [String] The join secret of the activity.
257
+ attr_reader :join
258
+ # @return [String] The spectate secret of the activity.
259
+ attr_reader :spectate
260
+ # @return [String] The match secret of the activity.
261
+ attr_reader :match
262
+
263
+ #
264
+ # Initialize the secrets.
265
+ # @private
266
+ #
267
+ # @param [Hash] data The secrets data.
268
+ #
269
+ def initialize(data)
270
+ @join = data[:join]
271
+ @spectate = data[:spectate]
272
+ @match = data[:match]
273
+ end
274
+ end
275
+
276
+ #
277
+ # Represents a button of an activity.
278
+ #
279
+ class Button < DiscordModel
280
+ # @return [String] The text of the button.
281
+ attr_reader :label
282
+ # @return [String] The URL of the button.
283
+ attr_reader :url
284
+ alias text label
285
+
286
+ #
287
+ # Initialize the button.
288
+ # @private
289
+ #
290
+ # @param [Hash] data The button data.
291
+ #
292
+ def initialize(data)
293
+ @label = data[0]
294
+ @url = data[1]
295
+ end
296
+ end
297
+ end
298
+
299
+ #
300
+ # Represents a user's client status.
301
+ #
302
+ class ClientStatus < DiscordModel
303
+ # @return [Symbol] The desktop status of the user.
304
+ attr_reader :desktop
305
+ # @return [Symbol] The mobile status of the user.
306
+ attr_reader :mobile
307
+ # @return [Symbol] The web status of the user.
308
+ attr_reader :web
309
+
310
+ # @!attribute [r] desktop?
311
+ # @return [Boolean] Whether the user is not offline on desktop.
312
+ # @!attribute [r] mobile?
313
+ # @return [Boolean] Whether the user is not offline on mobile.
314
+ # @!attribute [r] web?
315
+ # @return [Boolean] Whether the user is not offline on web.
316
+
317
+ #
318
+ # Initialize the client status.
319
+ # @private
320
+ #
321
+ # @param [Hash] data The client status data.
322
+ #
323
+ def initialize(data)
324
+ @desktop = data[:desktop]&.to_sym || :offline
325
+ @mobile = data[:mobile]&.to_sym || :offline
326
+ @web = data[:web]&.to_sym || :offline
327
+ end
328
+
329
+ def desktop?
330
+ @desktop != :offline
331
+ end
332
+
333
+ def mobile?
334
+ @mobile != :offline
335
+ end
336
+
337
+ def web?
338
+ @web != :offline
339
+ end
340
+ end
341
+
342
+ private
343
+
344
+ def _set_data(data)
345
+ @user_id = data[:user][:id]
346
+ @guild_id = data[:guild_id]
347
+ @status = data[:status].to_sym
348
+ @activities = data[:activities].map { |a| Activity.new(a) }
349
+ @client_status = ClientStatus.new(data[:client_status])
350
+ end
351
+ end
352
+ end