From de806e5d1b16e4ce8026ba066e3c1ea711a85d10 Mon Sep 17 00:00:00 2001 From: mikoto Date: Tue, 7 May 2024 07:42:10 +0200 Subject: [PATCH] wip --- src/api/client_server/context.rs | 6 +- src/utils/filter.rs | 170 +++++++++++++++++++++++-------- 2 files changed, 132 insertions(+), 44 deletions(-) diff --git a/src/api/client_server/context.rs b/src/api/client_server/context.rs index 011e2647..05303de8 100644 --- a/src/api/client_server/context.rs +++ b/src/api/client_server/context.rs @@ -194,10 +194,10 @@ pub async fn get_context_route( .map(|(count, _)| count.stringify()) .unwrap_or_else(|| base_token.stringify()); - let events_after: Vec<_> = events_after + let events_after = events_after .into_iter() - .map(|(_, pdu)| pdu.to_room_event()) - .collect(); + .map(|(_, pdu)| pdu.to_room_event()); + // .collect(); let mut state = Vec::new(); diff --git a/src/utils/filter.rs b/src/utils/filter.rs index ae0e833c..2c0a1a92 100644 --- a/src/utils/filter.rs +++ b/src/utils/filter.rs @@ -1,48 +1,136 @@ -use ruma::{api::client::filter::RoomEventFilter, events::AnyTimelineEvent, serde::Raw}; +use std::collections::HashSet; -pub fn filter_room_events>>( +use ruma::{ + api::client::filter::{LazyLoadOptions, RoomEventFilter}, + events::AnyTimelineEvent, + serde::Raw, + DeviceId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId, +}; + +use crate::services; + +pub fn filter_room_events<'i, I: Iterator>>( events: I, + sender_user: &UserId, + sender_device: &DeviceId, + room_id: Option<&RoomId>, filter: RoomEventFilter, -) { - events - .filter(|event| match &filter.types { - None => true, - Some(types) => types.iter().any(|t| { - t.as_str() - == event - .get_field::("type") - .expect("room events should deserialize") - .expect("room events should have a type") +) -> crate::Result>>> { + let (lazy_load_enabled, lazy_load_send_redundant) = match &filter.lazy_load_options { + LazyLoadOptions::Enabled { + include_redundant_members, + } => (true, *include_redundant_members), + _ => (false, false), + }; + + let it = Box::new( + events + .filter(|event| match &filter.rooms { + None => true, + Some(rooms) => rooms.iter().any(|r| { + r.as_str() + == event + .get_field::("room_id") + .expect("room events should deserialize") + .expect("room events should have a room_id") + }), + }) + .filter(|event| match &filter.not_rooms[..] { + [] => true, + not_rooms => not_rooms.iter().all(|r| { + r.as_str() + != event + .get_field::("room_id") + .expect("room events should deserialize") + .expect("room events should have a room_id") + }), + }) + .filter(|event| match &filter.senders { + None => true, + Some(rooms) => rooms.iter().any(|r| { + r.as_str() + == event + .get_field::("sender") + .expect("room events should deserialize") + .expect("room events should have a sender") + }), + }) + .filter(|event| match &filter.not_senders[..] { + [] => true, + not_senders => not_senders.iter().all(|r| { + r.as_str() + != event + .get_field::("sender") + .expect("room events should deserialize") + .expect("room events should have a sender") + }), + }) + .filter(|event| match &filter.types { + None => true, + Some(types) => types.iter().any(|t| { + t.as_str() + == event + .get_field::("type") + .expect("room events should deserialize") + .expect("room events should have a type") + }), + }) + .filter(|event| match &filter.not_types[..] { + [] => true, + not_types => not_types.iter().all(|t| { + t.as_str() + != event + .get_field::("type") + .expect("room events should deserialize") + .expect("room events should have a type") + }), + }) + .filter(|event| { + let room_id = event + .get_field::("room_id") + .expect("room events should deserialize") + .expect("room events should have a room_id"); + let event_id = event + .get_field::("event_id") + .expect("room events should deserialize") + .expect("room events should have an event_id"); + + services() + .rooms + .state_accessor + .user_can_see_event(sender_user, &room_id, &event_id) + .unwrap_or(false) }), + ); + + let memberships = it + .map(|event| { + let room_id = event + .get_field::("room_id") + .expect("room events should deserialize") + .expect("room events should have a room_id"); + let sender = event + .get_field::("sender") + .expect("room events should deserialize") + .expect("room events should have a sender"); + + (room_id, sender) }) - .filter(|event| match &filter.not_types[..] { - [] => true, - not_types => not_types.iter().all(|t| { - t.as_str() - != event - .get_field::("type") - .expect("room events should deserialize") - .expect("room events should have a type") - }), + .flat_map(|(room_id, sender)| { + services() + .rooms + .lazy_loading + .lazy_load_was_sent_before(sender_user, sender_device, &room_id, &sender) + .map(|b| { + if !b || lazy_load_send_redundant { + Some(sender) + } else { + None + } + }) + .transpose() }) - .filter(|event| match &filter.rooms { - None => true, - Some(rooms) => rooms.iter().any(|r| { - r.as_str() - == event - .get_field::("room_id") - .expect("room events should deserialize") - .expect("room events should have a type") - }), - }) - .filter(|event| match &filter.rooms { - None => true, - Some(rooms) => rooms.iter().all(|r| { - r.as_str() - != event - .get_field::("room_id") - .expect("room events should deserialize") - .expect("room events should have a type") - }), - }); + .collect::>>()?; + + Ok(it) }