SSS: implement receipts

This commit is contained in:
Lambda 2025-05-28 18:19:30 +00:00
parent 72c898dd41
commit 96a9632438

View file

@ -19,13 +19,15 @@ use ruma::{
}, },
events::{ events::{
direct::DirectEventContent, direct::DirectEventContent,
receipt::ReceiptEventContent,
room::{ room::{
create::RoomCreateEventContent, create::RoomCreateEventContent,
encryption::PossiblyRedactedRoomEncryptionEventContent, encryption::PossiblyRedactedRoomEncryptionEventContent,
member::{MembershipState, RoomMemberEventContent}, member::{MembershipState, RoomMemberEventContent},
}, },
AnyStrippedStateEvent, PossiblyRedactedStateEventContent, AnyStrippedStateEvent, AnySyncEphemeralRoomEvent,
StateEventType, StrippedStateEvent, TimelineEventType, PossiblyRedactedStateEventContent, StateEventType, StrippedStateEvent,
SyncEphemeralRoomEvent, TimelineEventType,
}, },
room::RoomType, room::RoomType,
serde::Raw, serde::Raw,
@ -510,6 +512,60 @@ pub(crate) async fn sync_events_v5_route(
None None
}; };
#[allow(clippy::if_then_some_else_none)]
let receipts = if body.extensions.receipts.enabled == Some(true) {
let mut receipts = BTreeMap::new();
for (room_id, todo_room) in &todo_rooms {
let mut event_content: BTreeMap<_, BTreeMap<_, BTreeMap<_, _>>> =
BTreeMap::new();
for x in services()
.rooms
.edus
.read_receipt
.readreceipts_since(room_id, todo_room.roomsince)
{
let Ok((_user_id, _, edu)) = x else {
// invalid DB entry
continue;
};
let Ok(edu) = edu.deserialize() else {
// invalid EDU JSON
continue;
};
let AnySyncEphemeralRoomEvent::Receipt(edu) = edu else {
// wrong EDU type
continue;
};
// merge all receipt EDUs into one
for (event_id, receipts) in edu.content.0 {
let entry = event_content.entry(event_id).or_default();
for (typ, receipts) in receipts {
let entry = entry.entry(typ).or_default();
for (user, receipt) in receipts {
entry.insert(user, receipt);
}
}
}
}
if !event_content.is_empty() {
let Ok(event) = Raw::new(&SyncEphemeralRoomEvent {
content: ReceiptEventContent(event_content),
}) else {
continue;
};
receipts.insert(room_id.clone(), event);
}
}
Some(sync_events::v5::response::Receipts {
rooms: receipts,
})
} else {
None
};
let mut rooms = BTreeMap::new(); let mut rooms = BTreeMap::new();
for (room_id, todo_room) in todo_rooms { for (room_id, todo_room) in todo_rooms {
if let Some(room) = process_room(&sender_user, &room_id, &todo_room)? { if let Some(room) = process_room(&sender_user, &room_id, &todo_room)? {
@ -521,9 +577,7 @@ pub(crate) async fn sync_events_v5_route(
to_device, to_device,
e2ee: e2ee.unwrap_or_default(), e2ee: e2ee.unwrap_or_default(),
account_data: account_data.unwrap_or_default(), account_data: account_data.unwrap_or_default(),
receipts: sync_events::v5::response::Receipts { receipts: receipts.unwrap_or_default(),
rooms: BTreeMap::new(),
},
typing: sync_events::v5::response::Typing { typing: sync_events::v5::response::Typing {
rooms: BTreeMap::new(), rooms: BTreeMap::new(),
}, },