matrix_sdk_base/response_processors/account_data/
room.rs1use ruma::{
16 RoomId,
17 events::{
18 AnyRoomAccountDataEvent, fully_read::FullyReadEventContent,
19 marked_unread::MarkedUnreadEventContent,
20 },
21 serde::Raw,
22};
23use tracing::{instrument, warn};
24
25use super::super::{Context, RoomInfoNotableUpdates};
26use crate::{
27 RoomInfo, RoomInfoNotableUpdateReasons, StateChanges, room::AccountDataSource,
28 store::BaseStateStore,
29};
30
31#[instrument(skip_all, fields(?room_id))]
32pub fn for_room(
33 context: &mut Context,
34 room_id: &RoomId,
35 events: &[Raw<AnyRoomAccountDataEvent>],
36 state_store: &BaseStateStore,
37) {
38 for raw_event in events {
40 match raw_event.deserialize() {
41 Ok(event) => {
42 context.state_changes.add_room_account_data(
43 room_id,
44 event.clone(),
45 raw_event.clone(),
46 );
47
48 match event {
49 AnyRoomAccountDataEvent::MarkedUnread(event) => {
50 on_room_info(
51 room_id,
52 &mut context.state_changes,
53 state_store,
54 |room_info| {
55 on_unread_marker(
56 room_id,
57 &event.content,
58 AccountDataSource::Stable,
59 room_info,
60 &mut context.room_info_notable_updates,
61 );
62 },
63 );
64 }
65 AnyRoomAccountDataEvent::UnstableMarkedUnread(event) => {
66 on_room_info(
67 room_id,
68 &mut context.state_changes,
69 state_store,
70 |room_info| {
71 on_unread_marker(
72 room_id,
73 &event.content.0,
74 AccountDataSource::Unstable,
75 room_info,
76 &mut context.room_info_notable_updates,
77 );
78 },
79 );
80 }
81 AnyRoomAccountDataEvent::Tag(event) => {
82 on_room_info(
83 room_id,
84 &mut context.state_changes,
85 state_store,
86 |room_info| {
87 room_info.base_info.handle_notable_tags(&event.content.tags);
88 },
89 );
90 }
91 AnyRoomAccountDataEvent::FullyRead(event) => {
92 on_room_info(
93 room_id,
94 &mut context.state_changes,
95 state_store,
96 |room_info| {
97 on_fully_read_marker(
98 room_id,
99 &event.content,
100 room_info,
101 &mut context.room_info_notable_updates,
102 );
103 },
104 );
105 }
106
107 _ => {}
109 }
110 }
111
112 Err(err) => {
113 warn!("unable to deserialize account data event: {err}");
114 }
115 }
116 }
117}
118
119fn on_room_info<F>(
124 room_id: &RoomId,
125 state_changes: &mut StateChanges,
126 state_store: &BaseStateStore,
127 mut on_room_info: F,
128) where
129 F: FnMut(&mut RoomInfo),
130{
131 if let Some(room_info) = state_changes.room_infos.get_mut(room_id) {
133 on_room_info(room_info);
135 }
136 else if let Some(room) = state_store.room(room_id) {
138 let mut room_info = room.clone_info();
140
141 on_room_info(&mut room_info);
143
144 state_changes.add_room(room_info);
146 }
147}
148
149fn on_fully_read_marker(
152 room_id: &RoomId,
153 content: &FullyReadEventContent,
154 room_info: &mut RoomInfo,
155 room_info_notable_updates: &mut RoomInfoNotableUpdates,
156) {
157 if room_info.base_info.fully_read_event_id.as_ref() == Some(&content.event_id) {
158 return;
159 }
160
161 room_info.base_info.fully_read_event_id = Some(content.event_id.clone());
162 room_info_notable_updates
163 .entry(room_id.to_owned())
164 .or_default()
165 .insert(RoomInfoNotableUpdateReasons::FULLY_READ);
166}
167
168fn on_unread_marker(
170 room_id: &RoomId,
171 content: &MarkedUnreadEventContent,
172 source: AccountDataSource,
173 room_info: &mut RoomInfo,
174 room_info_notable_updates: &mut RoomInfoNotableUpdates,
175) {
176 if room_info.base_info.is_marked_unread_source == AccountDataSource::Stable
177 && source != AccountDataSource::Stable
178 {
179 return;
181 }
182
183 if room_info.base_info.is_marked_unread != content.unread {
184 room_info_notable_updates
187 .entry(room_id.to_owned())
188 .or_default()
189 .insert(RoomInfoNotableUpdateReasons::UNREAD_MARKER);
190 }
191
192 room_info.base_info.is_marked_unread = content.unread;
193 room_info.base_info.is_marked_unread_source = source;
194}