diff --git a/src/api/client/sync/v5.rs b/src/api/client/sync/v5.rs index 8976fd02..df2f5844 100644 --- a/src/api/client/sync/v5.rs +++ b/src/api/client/sync/v5.rs @@ -30,7 +30,8 @@ api::client::sync::sync_events::{self, DeviceLists, UnreadNotificationsCount}, directory::RoomTypeFilter, events::{ - AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, StateEventType, TimelineEventType, + AnyRawAccountDataEvent, AnySyncEphemeralRoomEvent, AnySyncStateEvent, StateEventType, + TimelineEventType, room::member::{MembershipState, RoomMemberEventContent}, typing::TypingEventContent, }, @@ -533,6 +534,9 @@ async fn process_rooms<'a, Rooms>( } }); + let required_state = + collect_required_state(services, room_id, required_state_request).await; + let room_events: Vec<_> = timeline_pdus .iter() .stream() @@ -551,21 +555,6 @@ async fn process_rooms<'a, Rooms>( } } - let required_state = required_state_request - .iter() - .stream() - .filter_map(|state| async move { - services - .rooms - .state_accessor - .room_state_get(room_id, &state.0, &state.1) - .await - .map(Event::into_format) - .ok() - }) - .collect() - .await; - // Heroes let heroes: Vec<_> = services .rooms @@ -689,6 +678,46 @@ async fn process_rooms<'a, Rooms>( Ok(rooms) } +/// Collect the required state events for a room +async fn collect_required_state( + services: &Services, + room_id: &RoomId, + required_state_request: &BTreeSet, +) -> Vec> { + let mut required_state = Vec::new(); + for (event_type, state_key) in required_state_request { + // Resolve wild-card sentinel issue + // Addresses: https://forgejo.ellis.link/continuwuation/continuwuity/issues/1306 + if state_key.as_str() == "*" { + if let Ok(keys) = services + .rooms + .state_accessor + .room_state_keys(room_id, event_type) + .await + { + for key in keys { + if let Ok(event) = services + .rooms + .state_accessor + .room_state_get(room_id, event_type, &key) + .await + { + required_state.push(Event::into_format(event)); + } + } + } + } else if let Ok(event) = services + .rooms + .state_accessor + .room_state_get(room_id, event_type, state_key) + .await + { + required_state.push(Event::into_format(event)); + } + } + required_state +} + async fn collect_typing_events( services: &Services, sender_user: &UserId,