use ruma::{events::StateEventType, RoomId, UserId}; use tracing::error; use crate::{ service::rooms::timeline::PduCount, services, Error, PduEvent, Result, }; pub(crate) mod msc3575; pub(crate) mod v3; fn load_timeline( sender_user: &UserId, room_id: &RoomId, roomsincecount: PduCount, limit: u64, ) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> { let timeline_pdus; let limited; if services().rooms.timeline.last_timeline_count(sender_user, room_id)? > roomsincecount { let mut non_timeline_pdus = services() .rooms .timeline .pdus_until(sender_user, room_id, PduCount::MAX)? .filter_map(|x| match x { Ok(x) => Some(x), Err(error) => { error!(%error, "Bad PDU in pdus_since"); None } }) .take_while(|(pducount, _)| pducount > &roomsincecount); // Take the last events for the timeline timeline_pdus = non_timeline_pdus .by_ref() .take(limit.try_into().expect("limit should fit in usize")) .collect::>() .into_iter() .rev() .collect::>(); // They /sync response doesn't always return all messages, so we say the // output is limited unless there are events in // non_timeline_pdus limited = non_timeline_pdus.next().is_some(); } else { timeline_pdus = Vec::new(); limited = false; } Ok((timeline_pdus, limited)) } fn share_encrypted_room( sender_user: &UserId, user_id: &UserId, ignore_room: &RoomId, ) -> Result { Ok(services() .rooms .user .get_shared_rooms(vec![sender_user.to_owned(), user_id.to_owned()])? .filter_map(Result::ok) .filter(|room_id| room_id != ignore_room) .filter_map(|other_room_id| { Some( services() .rooms .state_accessor .room_state_get( &other_room_id, &StateEventType::RoomEncryption, "", ) .ok()? .is_some(), ) }) .any(|encrypted| encrypted)) }