matrix_sdk 2.1.3 → 2.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +1 -1
- data/lib/matrix_sdk/api.rb +49 -32
- data/lib/matrix_sdk/client.rb +71 -54
- data/lib/matrix_sdk/errors.rb +4 -0
- data/lib/matrix_sdk/mxid.rb +50 -15
- data/lib/matrix_sdk/protocols/cs.rb +182 -124
- data/lib/matrix_sdk/protocols/msc.rb +5 -1
- data/lib/matrix_sdk/response.rb +3 -1
- data/lib/matrix_sdk/room.rb +335 -102
- data/lib/matrix_sdk/rooms/space.rb +79 -0
- data/lib/matrix_sdk/user.rb +11 -3
- data/lib/matrix_sdk/util/events.rb +111 -0
- data/lib/matrix_sdk/util/extensions.rb +75 -0
- data/lib/matrix_sdk/util/tinycache.rb +134 -0
- data/lib/matrix_sdk/util/tinycache_adapter.rb +77 -0
- data/lib/matrix_sdk/util/uri.rb +89 -0
- data/lib/matrix_sdk/version.rb +1 -1
- data/lib/matrix_sdk.rb +16 -1
- metadata +12 -8
- data/lib/matrix_sdk/application_service.rb +0 -212
- data/lib/matrix_sdk/extensions.rb +0 -197
data/lib/matrix_sdk/room.rb
CHANGED
@@ -1,54 +1,45 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'matrix_sdk'
|
4
|
+
require 'matrix_sdk/util/events'
|
5
|
+
require 'matrix_sdk/util/tinycache'
|
4
6
|
|
5
7
|
module MatrixSdk
|
6
8
|
# A class for tracking the information about a room on Matrix
|
7
9
|
class Room
|
8
10
|
extend MatrixSdk::Extensions
|
11
|
+
extend MatrixSdk::Util::Tinycache
|
9
12
|
include MatrixSdk::Logging
|
10
13
|
|
11
|
-
# @!attribute [rw] canonical_alias
|
12
|
-
# @return [String, nil] the canonical alias of the room
|
13
14
|
# @!attribute [rw] event_history_limit
|
14
15
|
# @return [Fixnum] the limit of events to keep in the event log
|
15
|
-
attr_accessor :
|
16
|
+
attr_accessor :event_history_limit
|
16
17
|
# @!attribute [r] id
|
17
18
|
# @return [String] the internal ID of the room
|
18
19
|
# @!attribute [r] client
|
19
20
|
# @return [Client] the client for the room
|
20
|
-
# @!attribute [rw] name
|
21
|
-
# @return [String, nil] the user-provided name of the room
|
22
|
-
# @see reload_name!
|
23
|
-
# @!attribute [rw] topic
|
24
|
-
# @return [String, nil] the user-provided topic of the room
|
25
|
-
# @see reload_topic!
|
26
|
-
# @!attribute [r] aliases
|
27
|
-
# @return [Array(String)] a list of user-set aliases for the room
|
28
|
-
# @see add_alias
|
29
|
-
# @see reload_alias!
|
30
|
-
# @!attribute [rw] join_rule
|
31
|
-
# @return [:invite, :public] the join rule for the room -
|
32
|
-
# either +:invite+ or +:public+
|
33
|
-
# @!attribute [rw] guest_access
|
34
|
-
# @return [:can_join, :forbidden] the guest access for the room -
|
35
|
-
# either +:can_join+ or +:forbidden+
|
36
|
-
# @!attribute [r] members
|
37
|
-
# @return [Array(User)] the members of the room
|
38
|
-
# @see reload_members!
|
39
21
|
# @!attribute [r] events
|
40
22
|
# @return [Array(Object)] the last +event_history_limit+ events to arrive in the room
|
41
23
|
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync
|
42
24
|
# The timeline events are what will end up in here
|
43
|
-
attr_reader :id, :client, :
|
25
|
+
attr_reader :id, :client, :events
|
44
26
|
|
45
27
|
# @!method inspect
|
46
28
|
# An inspect method that skips a handful of instance variables to avoid
|
47
29
|
# flooding the terminal with debug data.
|
48
30
|
# @return [String] a regular inspect string without the data for some variables
|
49
|
-
ignore_inspect :client, :
|
31
|
+
ignore_inspect :client, :events, :prev_batch, :logger, :tinycache_adapter
|
32
|
+
|
33
|
+
# Requires heavy lookups, so they're cached for an hour
|
34
|
+
cached :joined_members, :aliases, cache_level: :all, expires_in: 60 * 60
|
35
|
+
# Only cache unfiltered requests for all members
|
36
|
+
cached :all_members, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 3600
|
37
|
+
|
38
|
+
# Much simpler to look up, and lighter data-wise, so the cache is wider
|
39
|
+
cached :canonical_alias, :name, :avatar_url, :topic, :guest_access, :join_rule, :power_levels, cache_level: :some, expires_in: 15 * 60
|
50
40
|
|
51
41
|
alias room_id id
|
42
|
+
alias members joined_members
|
52
43
|
|
53
44
|
# Create a new room instance
|
54
45
|
#
|
@@ -62,7 +53,7 @@ module MatrixSdk
|
|
62
53
|
# @option data [String] :topic The current topic of the room
|
63
54
|
# @option data [String,MXID] :canonical_alias The canonical alias of the room
|
64
55
|
# @option data [Array(String,MXID)] :aliases All non-canonical aliases of the room
|
65
|
-
# @option data [:invite,:public] :join_rule The join rule for the room
|
56
|
+
# @option data [:invite,:public,:knock] :join_rule The join rule for the room
|
66
57
|
# @option data [:can_join,:forbidden] :guest_access The guest access setting for the room
|
67
58
|
# @option data [Boolean] :world_readable If the room is readable by the entire world
|
68
59
|
# @option data [Array(User)] :members The list of joined members
|
@@ -72,38 +63,57 @@ module MatrixSdk
|
|
72
63
|
# @option data [String,URI] :avatar_url The avatar URL for the room
|
73
64
|
# @option data [String] :prev_batch The previous batch token for backfill
|
74
65
|
def initialize(client, room_id, data = {})
|
66
|
+
if client.is_a? Room
|
67
|
+
copy = client
|
68
|
+
client = copy.client
|
69
|
+
room_id = copy.id
|
70
|
+
# data = copy.attributes
|
71
|
+
end
|
72
|
+
|
75
73
|
raise ArgumentError, 'Must be given a Client instance' unless client.is_a? Client
|
76
74
|
|
75
|
+
@client = client
|
77
76
|
room_id = MXID.new room_id unless room_id.is_a?(MXID)
|
78
77
|
raise ArgumentError, 'room_id must be a valid Room ID' unless room_id.room_id?
|
79
78
|
|
80
|
-
@name = nil
|
81
|
-
@topic = nil
|
82
|
-
@canonical_alias = nil
|
83
|
-
@aliases = []
|
84
|
-
@join_rule = nil
|
85
|
-
@guest_access = nil
|
86
|
-
@world_readable = nil
|
87
|
-
@members = []
|
88
79
|
@events = []
|
89
|
-
@members_loaded = false
|
90
80
|
@event_history_limit = 10
|
91
|
-
@
|
81
|
+
@room_type = nil
|
92
82
|
|
93
83
|
@prev_batch = nil
|
94
84
|
|
95
85
|
data.each do |k, v|
|
96
|
-
|
86
|
+
next if %i[client].include? k
|
87
|
+
|
88
|
+
if respond_to?("#{k}_cached?".to_sym) && send("#{k}_cached?".to_sym)
|
89
|
+
tinycache_adapter.write(k, v)
|
90
|
+
elsif instance_variable_defined? "@#{k}"
|
91
|
+
instance_variable_set("@#{k}", v)
|
92
|
+
end
|
97
93
|
end
|
98
94
|
|
99
|
-
@client = client
|
100
95
|
@id = room_id.to_s
|
101
96
|
|
102
|
-
@name_checked = Time.new(0)
|
103
|
-
|
104
97
|
logger.debug "Created room #{room_id}"
|
105
98
|
end
|
106
99
|
|
100
|
+
#
|
101
|
+
# Casting operators
|
102
|
+
#
|
103
|
+
|
104
|
+
def to_space
|
105
|
+
return nil unless space?
|
106
|
+
|
107
|
+
Rooms::Space.new self, nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_s
|
111
|
+
prefix = canonical_alias if canonical_alias_has_value?
|
112
|
+
prefix ||= id
|
113
|
+
return "#{prefix} | #{name}" if name_has_value?
|
114
|
+
|
115
|
+
prefix
|
116
|
+
end
|
107
117
|
|
108
118
|
#
|
109
119
|
# Event handlers
|
@@ -127,7 +137,6 @@ module MatrixSdk
|
|
127
137
|
ensure_room_handlers[:ephemeral_event]
|
128
138
|
end
|
129
139
|
|
130
|
-
|
131
140
|
#
|
132
141
|
# State readers
|
133
142
|
#
|
@@ -156,19 +165,22 @@ module MatrixSdk
|
|
156
165
|
'Empty Room'
|
157
166
|
end
|
158
167
|
|
168
|
+
# @return [String, nil] the canonical alias of the room
|
169
|
+
def canonical_alias
|
170
|
+
client.api.get_room_state(id, 'm.room.canonical_alias')[:alias]
|
171
|
+
rescue MatrixSdk::MatrixNotFoundError
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
|
159
175
|
# Populates and returns the #members array
|
160
176
|
#
|
161
177
|
# @return [Array(User)] The list of members in the room
|
162
178
|
def joined_members
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
display_name: data.fetch(:display_name, nil),
|
168
|
-
avatar_url: data.fetch(:avatar_url, nil)))
|
179
|
+
client.api.get_room_joined_members(id)[:joined].map do |mxid, data|
|
180
|
+
User.new(client, mxid.to_s,
|
181
|
+
display_name: data.fetch(:display_name, nil),
|
182
|
+
avatar_url: data.fetch(:avatar_url, nil))
|
169
183
|
end
|
170
|
-
@members_loaded = true
|
171
|
-
members
|
172
184
|
end
|
173
185
|
|
174
186
|
# Get all members (member events) in the room
|
@@ -188,10 +200,7 @@ module MatrixSdk
|
|
188
200
|
#
|
189
201
|
# @return [String,nil] The room name - if any
|
190
202
|
def name
|
191
|
-
|
192
|
-
|
193
|
-
@name_checked = Time.now
|
194
|
-
@name ||= client.api.get_room_name(id)
|
203
|
+
client.api.get_room_name(id)[:name]
|
195
204
|
rescue MatrixNotFoundError
|
196
205
|
# No room name has been specified
|
197
206
|
nil
|
@@ -201,18 +210,34 @@ module MatrixSdk
|
|
201
210
|
#
|
202
211
|
# @return [String,nil] The avatar URL - if any
|
203
212
|
def avatar_url
|
204
|
-
|
213
|
+
client.api.get_room_avatar(id)[:url]
|
205
214
|
rescue MatrixNotFoundError
|
206
215
|
# No avatar has been set
|
207
216
|
nil
|
208
217
|
end
|
209
218
|
|
219
|
+
# Gets the room topic - if any
|
220
|
+
#
|
221
|
+
# @return [String,nil] The topic of the room
|
222
|
+
def topic
|
223
|
+
client.api.get_room_topic(id)[:topic]
|
224
|
+
rescue MatrixNotFoundError
|
225
|
+
# No room name has been specified
|
226
|
+
nil
|
227
|
+
end
|
228
|
+
|
229
|
+
# Gets the guest access rights for the room
|
230
|
+
#
|
231
|
+
# @return [:can_join,:forbidden] The current guest access right
|
210
232
|
def guest_access
|
211
|
-
|
233
|
+
client.api.get_room_guest_access(id)[:guest_access]&.to_sym
|
212
234
|
end
|
213
235
|
|
236
|
+
# Gets the join rule for the room
|
237
|
+
#
|
238
|
+
# @return [:public,:knock,:invite,:private] The current join rule
|
214
239
|
def join_rule
|
215
|
-
|
240
|
+
client.api.get_room_join_rules(id)[:join_rule]&.to_sym
|
216
241
|
end
|
217
242
|
|
218
243
|
# Checks if +guest_access+ is set to +:can_join+
|
@@ -225,6 +250,39 @@ module MatrixSdk
|
|
225
250
|
join_rule == :invite
|
226
251
|
end
|
227
252
|
|
253
|
+
# Checks if +join_rule+ is set to +:knock+
|
254
|
+
def knock_only?
|
255
|
+
join_rule == :knock
|
256
|
+
end
|
257
|
+
|
258
|
+
# Gets the history visibility of the room
|
259
|
+
#
|
260
|
+
# @return [:invited,:joined,:shared,:world_readable] The current history visibility for the room
|
261
|
+
def history_visibility
|
262
|
+
client.api.get_room_state(id, 'm.room.history_visibility')[:history_visibility]&.to_sym
|
263
|
+
end
|
264
|
+
|
265
|
+
# Checks if the room history is world readable
|
266
|
+
#
|
267
|
+
# @return [Boolean] If the history is world readable
|
268
|
+
def world_readable?
|
269
|
+
history_visibility == :world_readable
|
270
|
+
end
|
271
|
+
alias world_readable world_readable?
|
272
|
+
|
273
|
+
# Gets the room aliases
|
274
|
+
#
|
275
|
+
# @return [Array[String]] The assigned room aliases
|
276
|
+
def aliases
|
277
|
+
client.api.get_room_aliases(id).aliases
|
278
|
+
rescue MatrixNotFoundError
|
279
|
+
data = client.api.get_room_state_all(id)
|
280
|
+
data.select { |chunk| chunk[:type] == 'm.room.aliases' && !chunk.dig(*%i[content aliases]).nil? }
|
281
|
+
.map { |chunk| chunk.dig(*%i[content aliases]) }
|
282
|
+
.flatten
|
283
|
+
.compact
|
284
|
+
end
|
285
|
+
|
228
286
|
#
|
229
287
|
# Message handling
|
230
288
|
#
|
@@ -365,7 +423,13 @@ module MatrixSdk
|
|
365
423
|
# @param reverse [Boolean] whether to fill messages in reverse or not
|
366
424
|
# @param limit [Integer] the maximum number of messages to backfill
|
367
425
|
# @note This will trigger the `on_event` events as messages are added
|
368
|
-
def backfill_messages(reverse
|
426
|
+
def backfill_messages(*args, reverse: false, limit: 10)
|
427
|
+
# To be backwards-compatible
|
428
|
+
if args.length == 2
|
429
|
+
reverse = args.first
|
430
|
+
limit = args.last
|
431
|
+
end
|
432
|
+
|
369
433
|
data = client.api.get_room_messages(id, @prev_batch, direction: :b, limit: limit)
|
370
434
|
|
371
435
|
events = data[:chunk]
|
@@ -466,6 +530,41 @@ module MatrixSdk
|
|
466
530
|
true
|
467
531
|
end
|
468
532
|
|
533
|
+
# Gets the room creation information
|
534
|
+
#
|
535
|
+
# @return [Response] The content of the m.room.create event
|
536
|
+
def creation_info
|
537
|
+
# Not caching here, easier to cache the important values separately instead
|
538
|
+
client.api.get_room_creation_info(id)
|
539
|
+
end
|
540
|
+
|
541
|
+
# Retrieves the type of the room
|
542
|
+
#
|
543
|
+
# @return ['m.space',String,nil] The type of the room
|
544
|
+
def room_type
|
545
|
+
# Can't change, so a permanent cache is ok
|
546
|
+
return @room_type if @room_type_retrieved || @room_type
|
547
|
+
|
548
|
+
@room_type_retrieved = true
|
549
|
+
@room_type ||= creation_info[:type]
|
550
|
+
end
|
551
|
+
|
552
|
+
# Retrieves the room version
|
553
|
+
#
|
554
|
+
# @return [String] The version of the room
|
555
|
+
def room_version
|
556
|
+
@room_version ||= creation_info[:room_version]
|
557
|
+
end
|
558
|
+
|
559
|
+
# Checks if the room is a Matrix Space
|
560
|
+
#
|
561
|
+
# @return [Boolean,nil] True if the room is a space
|
562
|
+
def space?
|
563
|
+
room_type == 'm.space'
|
564
|
+
rescue MatrixSdk::MatrixForbiddenError, MatrixSdk::MatrixNotFoundError
|
565
|
+
nil
|
566
|
+
end
|
567
|
+
|
469
568
|
# Returns a list of the room tags
|
470
569
|
#
|
471
570
|
# @return [Response] A list of the tags and their data, with add and remove methods implemented
|
@@ -483,7 +582,7 @@ module MatrixSdk
|
|
483
582
|
@room
|
484
583
|
end
|
485
584
|
tag_obj.define_singleton_method(:add) do |tag, **data|
|
486
|
-
@room.add_tag(tag.to_s.to_sym, data)
|
585
|
+
@room.add_tag(tag.to_s.to_sym, **data)
|
487
586
|
self[tag.to_s.to_sym] = data
|
488
587
|
self
|
489
588
|
end
|
@@ -528,22 +627,16 @@ module MatrixSdk
|
|
528
627
|
#
|
529
628
|
# @param name [String] The new name to set
|
530
629
|
def name=(name)
|
630
|
+
tinycache_adapter.write(:name, name)
|
531
631
|
client.api.set_room_name(id, name)
|
532
|
-
|
632
|
+
name
|
533
633
|
end
|
534
634
|
|
535
635
|
# Reloads the name of the room
|
536
636
|
#
|
537
637
|
# @return [Boolean] if the name was changed or not
|
538
638
|
def reload_name!
|
539
|
-
|
540
|
-
client.api.get_room_name(id)
|
541
|
-
rescue MatrixNotFoundError
|
542
|
-
nil
|
543
|
-
end
|
544
|
-
changed = data[:name] != @name
|
545
|
-
@name = data[:name] if changed
|
546
|
-
changed
|
639
|
+
clear_name_cache
|
547
640
|
end
|
548
641
|
alias refresh_name! reload_name!
|
549
642
|
|
@@ -551,22 +644,16 @@ module MatrixSdk
|
|
551
644
|
#
|
552
645
|
# @param topic [String] The new topic to set
|
553
646
|
def topic=(topic)
|
647
|
+
tinycache_adapter.write(:topic, topic)
|
554
648
|
client.api.set_room_topic(id, topic)
|
555
|
-
|
649
|
+
topic
|
556
650
|
end
|
557
651
|
|
558
652
|
# Reloads the topic of the room
|
559
653
|
#
|
560
654
|
# @return [Boolean] if the topic was changed or not
|
561
655
|
def reload_topic!
|
562
|
-
|
563
|
-
client.api.get_room_topic(id)
|
564
|
-
rescue MatrixNotFoundError
|
565
|
-
nil
|
566
|
-
end
|
567
|
-
changed = data[:topic] != @topic
|
568
|
-
@topic = data[:topic] if changed
|
569
|
-
changed
|
656
|
+
clear_topic_cache
|
570
657
|
end
|
571
658
|
alias refresh_topic! reload_topic!
|
572
659
|
|
@@ -575,7 +662,7 @@ module MatrixSdk
|
|
575
662
|
# @return [Boolean] if the addition was successful or not
|
576
663
|
def add_alias(room_alias)
|
577
664
|
client.api.set_room_alias(id, room_alias)
|
578
|
-
|
665
|
+
tinycache_adapter.read(:aliases) << room_alias if tinycache_adapter.exist?(:aliases)
|
579
666
|
true
|
580
667
|
end
|
581
668
|
|
@@ -585,21 +672,7 @@ module MatrixSdk
|
|
585
672
|
# @note The list of aliases is not sorted, ordering changes will result in
|
586
673
|
# alias list updates.
|
587
674
|
def reload_aliases!
|
588
|
-
|
589
|
-
new_aliases = client.api.get_room_aliases(id).aliases
|
590
|
-
rescue MatrixNotFoundError
|
591
|
-
data = client.api.get_room_state_all(id)
|
592
|
-
new_aliases = data.select { |chunk| chunk[:type] == 'm.room.aliases' && chunk.key?(:content) && chunk[:content].key?(:aliases) }
|
593
|
-
.map { |chunk| chunk[:content][:aliases] }
|
594
|
-
.flatten
|
595
|
-
.compact
|
596
|
-
end
|
597
|
-
|
598
|
-
return false if new_aliases.nil?
|
599
|
-
|
600
|
-
changed = new_aliases != aliases
|
601
|
-
@aliases = new_aliases if changed
|
602
|
-
changed
|
675
|
+
clear_aliases_cache
|
603
676
|
end
|
604
677
|
alias refresh_aliases! reload_aliases!
|
605
678
|
|
@@ -608,7 +681,7 @@ module MatrixSdk
|
|
608
681
|
# @param invite_only [Boolean] If it should be invite only or not
|
609
682
|
def invite_only=(invite_only)
|
610
683
|
self.join_rule = invite_only ? :invite : :public
|
611
|
-
|
684
|
+
invite_only
|
612
685
|
end
|
613
686
|
|
614
687
|
# Sets the join rule of the room
|
@@ -616,7 +689,8 @@ module MatrixSdk
|
|
616
689
|
# @param join_rule [:invite,:public] The join rule of the room
|
617
690
|
def join_rule=(join_rule)
|
618
691
|
client.api.set_room_join_rules(id, join_rule)
|
619
|
-
|
692
|
+
tinycache_adapter.write(:join_rule, join_rule)
|
693
|
+
join_rule
|
620
694
|
end
|
621
695
|
|
622
696
|
# Sets if guests are allowed in the room
|
@@ -624,7 +698,7 @@ module MatrixSdk
|
|
624
698
|
# @param allow_guests [Boolean] If guests are allowed to join or not
|
625
699
|
def allow_guests=(allow_guests)
|
626
700
|
self.guest_access = (allow_guests ? :can_join : :forbidden)
|
627
|
-
|
701
|
+
allow_guests
|
628
702
|
end
|
629
703
|
|
630
704
|
# Sets the guest access status for the room
|
@@ -632,18 +706,101 @@ module MatrixSdk
|
|
632
706
|
# @param guest_access [:can_join,:forbidden] The new guest access status of the room
|
633
707
|
def guest_access=(guest_access)
|
634
708
|
client.api.set_room_guest_access(id, guest_access)
|
635
|
-
|
709
|
+
tinycache_adapter.write(:guest_access, guest_access)
|
710
|
+
guest_access
|
636
711
|
end
|
637
712
|
|
638
713
|
# Sets a new avatar URL for the room
|
639
714
|
#
|
640
|
-
# @param avatar_url [URI::
|
715
|
+
# @param avatar_url [URI::MXC] The mxc:// URL for the new room avatar
|
641
716
|
def avatar_url=(avatar_url)
|
642
717
|
avatar_url = URI(avatar_url) unless avatar_url.is_a? URI
|
643
|
-
raise ArgumentError, 'Must be a valid MXC URL' unless avatar_url.is_a? URI::
|
718
|
+
raise ArgumentError, 'Must be a valid MXC URL' unless avatar_url.is_a? URI::MXC
|
644
719
|
|
645
720
|
client.api.set_room_avatar(id, avatar_url)
|
646
|
-
|
721
|
+
tinycache_adapter.write(:avatar_url, avatar_url)
|
722
|
+
avatar_url
|
723
|
+
end
|
724
|
+
|
725
|
+
# Get the power levels of the room
|
726
|
+
#
|
727
|
+
# @note The returned power levels are cached for a minute
|
728
|
+
# @return [Hash] The current power levels as set for the room
|
729
|
+
# @see Protocols::CS#get_power_levels
|
730
|
+
def power_levels
|
731
|
+
client.api.get_power_levels(id)
|
732
|
+
end
|
733
|
+
|
734
|
+
# Gets the power level of a user in the room
|
735
|
+
#
|
736
|
+
# @param user [User,MXID,String] The user to check the power level for
|
737
|
+
# @param use_default [Boolean] Should the user default level be checked if no user-specific one exists
|
738
|
+
# @return [Integer,nil] The current power level for the requested user, nil if there's no user specific level
|
739
|
+
# and use_default is false
|
740
|
+
def user_powerlevel(user, use_default: true)
|
741
|
+
user = user.id if user.is_a? User
|
742
|
+
user = MXID.new(user.to_s) unless user.is_a? MXID
|
743
|
+
raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
|
744
|
+
|
745
|
+
level = power_levels.dig(:users, user.to_s.to_sym)
|
746
|
+
level = power_levels[:users_default] || 0 if level.nil? && use_default
|
747
|
+
level
|
748
|
+
end
|
749
|
+
|
750
|
+
# Check if a user is an admin in the room
|
751
|
+
#
|
752
|
+
# @param user [User,MXID,String] The user to check for admin privileges
|
753
|
+
# @param target_level [Integer] The power level that's to be considered as admin privileges
|
754
|
+
# @return [Boolean] If the requested user has a power level highe enough to be an admin
|
755
|
+
# @see #user_powerlevel
|
756
|
+
def admin?(user, target_level: 100)
|
757
|
+
level = user_powerlevel(user, use_default: false)
|
758
|
+
return false unless level
|
759
|
+
|
760
|
+
level >= target_level
|
761
|
+
end
|
762
|
+
|
763
|
+
# Make a user an admin in the room
|
764
|
+
#
|
765
|
+
# @param user [User,MXID,String] The user to give admin privileges
|
766
|
+
# @param level [Integer] The power level to set the user to
|
767
|
+
# @see #modify_user_power_levels
|
768
|
+
def admin!(user, level: 100)
|
769
|
+
return true if admin?(user, target_level: level)
|
770
|
+
|
771
|
+
user = user.id if user.is_a? User
|
772
|
+
user = MXID.new(user.to_s) unless user.is_a? MXID
|
773
|
+
raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
|
774
|
+
|
775
|
+
modify_user_power_levels({ user.to_s.to_sym => level })
|
776
|
+
end
|
777
|
+
|
778
|
+
# Check if a user is a moderator in the room
|
779
|
+
#
|
780
|
+
# @param user [User,MXID,String] The user to check for admin privileges
|
781
|
+
# @param target_level [Integer] The power level that's to be considered as admin privileges
|
782
|
+
# @return [Boolean] If the requested user has a power level highe enough to be an admin
|
783
|
+
# @see #user_powerlevel
|
784
|
+
def moderator?(user, target_level: 50)
|
785
|
+
level = user_powerlevel(user, use_default: false)
|
786
|
+
return false unless level
|
787
|
+
|
788
|
+
level >= target_level
|
789
|
+
end
|
790
|
+
|
791
|
+
# Make a user a moderator in the room
|
792
|
+
#
|
793
|
+
# @param user [User,MXID,String] The user to give moderator privileges
|
794
|
+
# @param level [Integer] The power level to set the user to
|
795
|
+
# @see #modify_user_power_levels
|
796
|
+
def moderator!(user, level: 50)
|
797
|
+
return true if moderator?(user, target_level: level)
|
798
|
+
|
799
|
+
user = user.id if user.is_a? User
|
800
|
+
user = MXID.new(user.to_s) unless user.is_a? MXID
|
801
|
+
raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
|
802
|
+
|
803
|
+
modify_user_power_levels({ user.to_s.to_sym => level })
|
647
804
|
end
|
648
805
|
|
649
806
|
# Modifies the power levels of the room
|
@@ -654,13 +811,23 @@ module MatrixSdk
|
|
654
811
|
def modify_user_power_levels(users = nil, users_default = nil)
|
655
812
|
return false if users.nil? && users_default.nil?
|
656
813
|
|
657
|
-
data =
|
814
|
+
data = power_levels_without_cache
|
815
|
+
tinycache_adapter.write(:power_levels, data)
|
658
816
|
data[:users_default] = users_default unless users_default.nil?
|
659
817
|
|
660
818
|
if users
|
661
819
|
data[:users] = {} unless data.key? :users
|
662
|
-
|
663
|
-
|
820
|
+
users.each do |user, level|
|
821
|
+
user = user.id if user.is_a? User
|
822
|
+
user = MXID.new(user.to_s) unless user.is_a? MXID
|
823
|
+
raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
|
824
|
+
|
825
|
+
if level.nil?
|
826
|
+
data[:users].delete(user.to_s.to_sym)
|
827
|
+
else
|
828
|
+
data[:users][user.to_s.to_sym] = level
|
829
|
+
end
|
830
|
+
end
|
664
831
|
end
|
665
832
|
|
666
833
|
client.api.set_power_levels(id, data)
|
@@ -675,7 +842,8 @@ module MatrixSdk
|
|
675
842
|
def modify_required_power_levels(events = nil, params = {})
|
676
843
|
return false if events.nil? && (params.nil? || params.empty?)
|
677
844
|
|
678
|
-
data =
|
845
|
+
data = power_levels_without_cache
|
846
|
+
tinycache_adapter.write(:power_levels, data)
|
679
847
|
data.merge!(params)
|
680
848
|
data.delete_if { |_k, v| v.nil? }
|
681
849
|
|
@@ -692,9 +860,62 @@ module MatrixSdk
|
|
692
860
|
private
|
693
861
|
|
694
862
|
def ensure_member(member)
|
863
|
+
tinycache_adapter.write(:joined_members, []) unless tinycache_adapter.exist? :joined_members
|
864
|
+
|
865
|
+
members = tinycache_adapter.read(:joined_members) || []
|
695
866
|
members << member unless members.any? { |m| m.id == member.id }
|
696
867
|
end
|
697
868
|
|
869
|
+
def handle_power_levels(event)
|
870
|
+
tinycache_adapter.write(:power_levels, event[:content])
|
871
|
+
end
|
872
|
+
|
873
|
+
def handle_room_name(event)
|
874
|
+
tinycache_adapter.write(:name, event.dig(*%i[content name]))
|
875
|
+
end
|
876
|
+
|
877
|
+
def handle_room_topic(event)
|
878
|
+
tinycache_adapter.write(:topic, event.dig(*%i[content topic]))
|
879
|
+
end
|
880
|
+
|
881
|
+
def handle_room_guest_access(event)
|
882
|
+
tinycache_adapter.write(:guest_access, event.dig(*%i[content guest_access])&.to_sym)
|
883
|
+
end
|
884
|
+
|
885
|
+
def handle_room_join_rules(event)
|
886
|
+
tinycache_adapter.write(:join_rule, event.dig(*%i[content join_rule])&.to_sym)
|
887
|
+
end
|
888
|
+
|
889
|
+
def handle_room_member(event)
|
890
|
+
return unless client.cache == :all
|
891
|
+
|
892
|
+
if event.dig(*%i[content membership]) == 'join'
|
893
|
+
ensure_member(client.get_user(event[:state_key]).dup.tap do |u|
|
894
|
+
u.instance_variable_set(:@display_name, event.dig(*%i[content displayname]))
|
895
|
+
end)
|
896
|
+
elsif tinycache_adapter.exist? :joined_members
|
897
|
+
members = tinycache_adapter.read(:joined_members)
|
898
|
+
members.delete_if { |m| m.id == event[:state_key] }
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
def handle_room_canonical_alias(event)
|
903
|
+
canonical_alias = tinycache_adapter.write(:canonical_alias, event.dig(*%i[content alias]))
|
904
|
+
|
905
|
+
data = tinycache_adapter.read(:aliases) || []
|
906
|
+
data << canonical_alias
|
907
|
+
tinycache_adapter.write(:aliases, data)
|
908
|
+
end
|
909
|
+
|
910
|
+
def handle_room_aliases(event)
|
911
|
+
tinycache_adapter.write(:aliases, []) unless tinycache_adapter.exist? :aliases
|
912
|
+
|
913
|
+
aliases = tinycache_adapter.read(:aliases) || []
|
914
|
+
aliases.concat(event.dig(*%i[content aliases]))
|
915
|
+
|
916
|
+
tinycache_adapter.write(:aliases, aliases)
|
917
|
+
end
|
918
|
+
|
698
919
|
def room_handlers?
|
699
920
|
client.instance_variable_get(:@room_handlers).key? id
|
700
921
|
end
|
@@ -707,6 +928,16 @@ module MatrixSdk
|
|
707
928
|
}
|
708
929
|
end
|
709
930
|
|
931
|
+
INTERNAL_HANDLERS = {
|
932
|
+
'm.room.aliases' => :handle_room_aliases,
|
933
|
+
'm.room.canonical_alias' => :handle_room_canonical_alias,
|
934
|
+
'm.room.guest_access' => :handle_room_guest_access,
|
935
|
+
'm.room.join_rules' => :handle_room_join_rules,
|
936
|
+
'm.room.member' => :handle_room_member,
|
937
|
+
'm.room.name' => :handle_room_name,
|
938
|
+
'm.room.power_levels' => :handle_power_levels,
|
939
|
+
'm.room.topic' => :handle_room_topic
|
940
|
+
}.freeze
|
710
941
|
def put_event(event)
|
711
942
|
ensure_room_handlers[:event].fire(MatrixEvent.new(self, event), event[:type]) if room_handlers?
|
712
943
|
|
@@ -721,6 +952,8 @@ module MatrixSdk
|
|
721
952
|
end
|
722
953
|
|
723
954
|
def put_state_event(event)
|
955
|
+
send(INTERNAL_HANDLERS[event[:type]], event) if INTERNAL_HANDLERS.key? event[:type]
|
956
|
+
|
724
957
|
return unless room_handlers?
|
725
958
|
|
726
959
|
ensure_room_handlers[:state_event].fire(MatrixEvent.new(self, event), event[:type])
|