use std::collections::BTreeMap;
use matrix_sdk_base::{
deserialized_responses::AmbiguityChange,
event_cache::{Event, Gap},
linked_chunk::{self, OwnedLinkedChunkId},
};
use ruma::{OwnedEventId, OwnedRoomId, events::AnySyncEphemeralRoomEvent, serde::Raw};
use tokio::sync::broadcast::{Receiver, Sender};
use super::super::TimelineVectorDiffs;
#[derive(Debug, Clone)]
pub enum RoomEventCacheUpdate {
MoveReadMarkerTo {
event_id: OwnedEventId,
},
UpdateMembers {
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
},
UpdateTimelineEvents(TimelineVectorDiffs),
AddEphemeralEvents {
events: Vec<Raw<AnySyncEphemeralRoomEvent>>,
},
}
#[derive(Clone, Debug)]
pub struct RoomEventCacheGenericUpdate {
pub room_id: OwnedRoomId,
}
#[derive(Clone, Debug)]
pub struct RoomEventCacheLinkedChunkUpdate {
pub linked_chunk_id: OwnedLinkedChunkId,
pub updates: Vec<linked_chunk::Update<Event, Gap>>,
}
impl RoomEventCacheLinkedChunkUpdate {
pub fn events(self) -> impl DoubleEndedIterator<Item = Event> {
use itertools::Either;
self.updates.into_iter().flat_map(|update| match update {
linked_chunk::Update::PushItems { items, .. } => {
Either::Left(Either::Left(items.into_iter()))
}
linked_chunk::Update::ReplaceItem { item, .. } => {
Either::Left(Either::Right(std::iter::once(item)))
}
linked_chunk::Update::RemoveItem { .. }
| linked_chunk::Update::DetachLastItems { .. }
| linked_chunk::Update::StartReattachItems
| linked_chunk::Update::EndReattachItems
| linked_chunk::Update::NewItemsChunk { .. }
| linked_chunk::Update::NewGapChunk { .. }
| linked_chunk::Update::RemoveChunk(..)
| linked_chunk::Update::Clear => {
Either::Right(std::iter::empty())
}
})
}
}
#[derive(Clone)]
pub struct RoomEventCacheUpdateSender {
room_sender: Sender<RoomEventCacheUpdate>,
generic_sender: Sender<RoomEventCacheGenericUpdate>,
}
impl RoomEventCacheUpdateSender {
pub fn new(generic_sender: Sender<RoomEventCacheGenericUpdate>) -> Self {
Self { room_sender: Sender::new(32), generic_sender }
}
pub fn send(
&self,
room_update: RoomEventCacheUpdate,
generic_update: Option<RoomEventCacheGenericUpdate>,
) {
let _ = self.room_sender.send(room_update);
if let Some(generic_update) = generic_update {
let _ = self.generic_sender.send(generic_update);
}
}
pub(super) fn new_room_receiver(&self) -> Receiver<RoomEventCacheUpdate> {
self.room_sender.subscribe()
}
}