diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 563abbc81a5..bdd81e25496 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -527,7 +527,7 @@ impl BaseClient { pub(crate) async fn handle_invited_state( &self, room: &Room, - events: &[Raw], + events: &[(Raw, AnyStrippedStateEvent)], push_rules: &Ruleset, room_info: &mut RoomInfo, changes: &mut StateChanges, @@ -535,22 +535,12 @@ impl BaseClient { ) -> Result<()> { let mut state_events = BTreeMap::new(); - for raw_event in events { - match raw_event.deserialize() { - Ok(e) => { - room_info.handle_stripped_state_event(&e); - state_events - .entry(e.event_type()) - .or_insert_with(BTreeMap::new) - .insert(e.state_key().to_owned(), raw_event.clone()); - } - Err(err) => { - warn!( - room_id = ?room_info.room_id, - "Couldn't deserialize stripped state event: {err:?}", - ); - } - } + for (raw_event, event) in events { + room_info.handle_stripped_state_event(event); + state_events + .entry(event.event_type()) + .or_insert_with(BTreeMap::new) + .insert(event.state_key().to_owned(), raw_event.clone()); } changes.stripped_state.insert(room_info.room_id().to_owned(), state_events.clone()); @@ -1121,13 +1111,16 @@ impl BaseClient { self.room_info_notable_update_sender.clone(), ); + let invite_state = + Self::deserialize_stripped_state_events(&new_info.invite_state.events); + let mut room_info = room.clone_info(); room_info.mark_as_invited(); room_info.mark_state_fully_synced(); self.handle_invited_state( &room, - &new_info.invite_state.events, + &invite_state, &push_rules, &mut room_info, &mut changes, @@ -1147,13 +1140,15 @@ impl BaseClient { self.room_info_notable_update_sender.clone(), ); + let knock_state = Self::deserialize_stripped_state_events(&new_info.knock_state.events); + let mut room_info = room.clone_info(); room_info.mark_as_knocked(); room_info.mark_state_fully_synced(); self.handle_invited_state( &room, - &new_info.knock_state.events, + &knock_state, &push_rules, &mut room_info, &mut changes, @@ -1608,6 +1603,21 @@ impl BaseClient { .collect() } + pub(crate) fn deserialize_stripped_state_events( + raw_events: &[Raw], + ) -> Vec<(Raw, AnyStrippedStateEvent)> { + raw_events + .iter() + .filter_map(|raw_event| match raw_event.deserialize() { + Ok(event) => Some((raw_event.clone(), event)), + Err(e) => { + warn!("Couldn't deserialize state event: {e}"); + None + } + }) + .collect() + } + /// Returns a new receiver that gets future room info notable updates. /// /// Learn more by reading the [`RoomInfoNotableUpdate`] type. diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index 77a52b702e6..a4e4a32d7b6 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -423,11 +423,17 @@ impl BaseClient { } } + let invite_state: Option, AnyStrippedStateEvent)>> = + room_data + .invite_state + .as_ref() + .map(|invite_state| Self::deserialize_stripped_state_events(invite_state)); + #[allow(unused_mut)] // Required for some feature flag combinations let (mut room, mut room_info, invited_room, knocked_room) = self .process_sliding_sync_room_membership( - room_data.as_ref(), &state_events, + &invite_state, store, user_id, room_id, @@ -452,7 +458,7 @@ impl BaseClient { let push_rules = self.get_push_rules(account_data_processor).await?; // This will be used for both invited and knocked rooms - if let Some(invite_state) = &room_data.invite_state { + if let Some(invite_state) = &invite_state { self.handle_invited_state( &room, invite_state, @@ -566,14 +572,14 @@ impl BaseClient { /// otherwise. https://github.com/matrix-org/matrix-spec-proposals/blob/kegan/sync-v3/proposals/3575-sync.md#room-list-parameters fn process_sliding_sync_room_membership( &self, - room_data: &http::response::Room, state_events: &[AnySyncStateEvent], + invite_state: &Option, AnyStrippedStateEvent)>>, store: &Store, user_id: &UserId, room_id: &RoomId, room_info_notable_updates: &mut BTreeMap, ) -> (Room, RoomInfo, Option, Option) { - if let Some(invite_state) = &room_data.invite_state { + if let Some(invite_state) = &invite_state { let room = store.get_or_create_room( room_id, RoomState::Invited, @@ -583,23 +589,21 @@ impl BaseClient { // We need to find the membership event since it could be for either an invited // or knocked room - let membership_event_content = invite_state.iter().find_map(|raw| { - raw.deserialize().ok().iter().find_map(|e| { - if let AnyStrippedStateEvent::RoomMember(membership_event) = e { - if membership_event.state_key == user_id { - return Some(membership_event.content.clone()); - } + let membership_event_content = invite_state.iter().find_map(|(_, event)| { + if let AnyStrippedStateEvent::RoomMember(membership_event) = event { + if membership_event.state_key == user_id { + return Some(membership_event.content.clone()); } - None - }) + } + None }); if let Some(membership_event_content) = membership_event_content { if membership_event_content.membership == MembershipState::Knock { // If we have a `Knock` membership state, set the room as such room_info.mark_as_knocked(); - let knock_state = - assign!(v3::KnockState::default(), { events: invite_state.clone() }); + let raw_events = invite_state.iter().map(|(raw, _)| raw.clone()).collect(); + let knock_state = assign!(v3::KnockState::default(), { events: raw_events }); let knocked_room = assign!(KnockedRoom::default(), { knock_state: knock_state }); return (room, room_info, None, Some(knocked_room)); @@ -608,7 +612,8 @@ impl BaseClient { // Otherwise assume it's an invited room room_info.mark_as_invited(); - let invited_room = InvitedRoom::from(v3::InviteState::from(invite_state.clone())); + let raw_events = invite_state.iter().map(|(raw, _)| raw.clone()).collect::>(); + let invited_room = InvitedRoom::from(v3::InviteState::from(raw_events)); (room, room_info, Some(invited_room), None) } else { let room = store.get_or_create_room(