tuwunel_service/account_data/
direct.rs1use std::collections::BTreeSet;
7
8use ruma::{
9 OwnedRoomId, RoomId, UserId,
10 events::{
11 GlobalAccountDataEventType,
12 direct::{DirectEvent, DirectEventContent, DirectUserIdentifier},
13 },
14};
15use tuwunel_core::{Result, at, implement, is_equal_to};
16
17#[implement(super::Service)]
23pub async fn direct_rooms(&self, user_id: &UserId) -> BTreeSet<OwnedRoomId> {
24 self.direct_content(user_id)
25 .await
26 .into_iter()
27 .flat_map(DirectEventContent::into_iter)
28 .map(at!(1))
29 .flat_map(Vec::into_iter)
30 .collect()
31}
32
33#[implement(super::Service)]
44pub async fn mark_direct(&self, user_id: &UserId, target: &UserId, room_id: &RoomId) -> Result {
45 let mut content = self
46 .direct_content(user_id)
47 .await
48 .unwrap_or_default();
49
50 let target: &DirectUserIdentifier = target.into();
51 let listed = content
52 .get(target)
53 .is_some_and(|rooms| rooms.iter().any(is_equal_to!(room_id)));
54
55 if listed {
56 return Ok(());
57 }
58
59 content
60 .entry(target.to_owned())
61 .or_default()
62 .push(room_id.to_owned());
63
64 let event = serde_json::to_value(DirectEvent { content })?;
65
66 let event_type = GlobalAccountDataEventType::Direct
67 .to_string()
68 .into();
69
70 self.services
71 .account_data
72 .update(None, user_id, event_type, &event)
73 .await
74}
75
76#[implement(super::Service)]
81async fn direct_content(&self, user_id: &UserId) -> Result<DirectEventContent> {
82 self.services
83 .account_data
84 .get_global(user_id, GlobalAccountDataEventType::Direct)
85 .await
86 .map(|event: DirectEvent| event.content)
87}