-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(room_list): allow knock state event as latest_event
#4170
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4170 +/- ##
=======================================
Coverage 84.84% 84.85%
=======================================
Files 270 270
Lines 28991 29031 +40
=======================================
+ Hits 24597 24633 +36
- Misses 4394 4398 +4 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, lgtm 👌
7df1d4a
to
c79eaf0
Compare
@stefanceriu I added some logic changes in c79eaf0 in case you want to re-review. @bnjbvr let me know if you want to take a look too. |
/// Gets this Room's power levels. | ||
pub async fn power_levels(&self) -> Option<RoomPowerLevels> { | ||
self.store | ||
.get_state_event_static::<RoomPowerLevelsEventContent>(&self.room_id) | ||
.await | ||
.ok() | ||
.flatten() | ||
.and_then(|raw| raw.deserialize().ok()) | ||
.map(|ev| ev.power_levels()) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have matrix_sdk::Room::room_power_levels
, but we needed something at the matrix_sdk_base
crate too. Since sdk::Room
already has access to the fns in sdk_base::Room
, should I just remove the one in sdk and use this one instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, they do the same thing. Can we have this function here return a Result
instead, to not silently swallow errors, please? (and we can keep the shorter power_levels
name, I like it better 👍)
// can either accept or decline them | ||
if let AnySyncStateEvent::RoomMember(member) = state { | ||
if matches!(member.membership(), MembershipState::Knock) { | ||
let can_accept_or_decline_knocks = match power_levels_info { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to move this logic to within the RoomPowerLevels
, similar to the other can_foo
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's worth it, since it'll only be used here (I hope).
@@ -698,14 +698,34 @@ async fn cache_latest_events( | |||
let mut encrypted_events = | |||
Vec::with_capacity(room.latest_encrypted_events.read().unwrap().capacity()); | |||
|
|||
// Try to get room power levels from the current changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a lot of work to do just in case you get a knocked state event, which I presume doesn't happen very often.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but I didn't find any alternatives other than not implementing this part of the functionality 🫤 . We'd have to change the sync process so we can process these latest events after the client has processed the sync request and saved all the data to the store and I think that would be quite complex.
@@ -158,9 +158,21 @@ impl EventTimelineItem { | |||
let event_id = event.event_id().to_owned(); | |||
let is_own = client.user_id().map(|uid| uid == sender).unwrap_or(false); | |||
|
|||
// Get the room's power levels for calculating the latest event |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here I guess but I'm not sure how heavy it actually is. Does fetching a room and power levels have any potential of introducing slowdowns?
Passing the client into PossibleLatestEvent would be weird and it wouldn't improve the sliding sync part 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think getting both the room and the state event should be quite lightweight, but I'm not sure how much it could affect performance. The alternative could be to only load them if we reach a knock state event, maybe, although I'd have to change some data structures.
I'll do a lightweight review (I promise 😇) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
@@ -37,6 +47,9 @@ pub enum PossibleLatestEvent<'a> { | |||
/// This message is suitable - it's a call notification | |||
YesCallNotify(&'a SyncCallNotifyEvent), | |||
|
|||
/// This state event is suitable - it's a knock membership change |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// This state event is suitable - it's a knock membership change | |
/// This state event is suitable - it's a knock membership change | |
/// that can be handled by the current user. |
/// Gets this Room's power levels. | ||
pub async fn power_levels(&self) -> Option<RoomPowerLevels> { | ||
self.store | ||
.get_state_event_static::<RoomPowerLevelsEventContent>(&self.room_id) | ||
.await | ||
.ok() | ||
.flatten() | ||
.and_then(|raw| raw.deserialize().ok()) | ||
.map(|ev| ev.power_levels()) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, they do the same thing. Can we have this function here return a Result
instead, to not silently swallow errors, please? (and we can keep the shorter power_levels
name, I like it better 👍)
let power_levels_from_changes = || { | ||
let state_changes = changes?.state.get(room_info.room_id())?; | ||
let room_power_levels_state = | ||
state_changes.get(&StateEventType::RoomPowerLevels)?.values().next()?; | ||
match room_power_levels_state.deserialize().ok()? { | ||
AnySyncStateEvent::RoomPowerLevels(ev) => Some(ev.power_levels()), | ||
_ => None, | ||
} | ||
}; | ||
|
||
// If we didn't get any info, try getting it from local data | ||
let power_levels = match power_levels_from_changes() { | ||
Some(power_levels) => Some(power_levels), | ||
None => room.power_levels().await, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful 🤩
let room_power_levels_info = match (client.user_id(), power_levels.as_ref()) { | ||
(Some(user_id), Some(power_levels)) => Some((user_id, power_levels)), | ||
_ => None, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GOOD NEWS EVERYONE! There's Option::zip()
that does exactly the same thing :)
let room_power_levels_info = match (client.user_id(), power_levels.as_ref()) { | |
(Some(user_id), Some(power_levels)) => Some((user_id, power_levels)), | |
_ => None, | |
}; | |
let room_power_levels_info = client.user_id().zip(power_levels.as_ref())); |
c79eaf0
to
c97b36a
Compare
This allows clients to display pending knocking requests in the room list items.
…nt user can act on them That is, if their power level allows them to either invite or kick users.
This has been replaced by `sdk_base::Room::power_levels`, which can also be used from `sdk::Room`
c97b36a
to
61f48ba
Compare
This allows clients to display pending knocking requests in the room list items (needed by EXI and EXA).
Signed-off-by: