@@ -10,29 +10,21 @@ use ruma::{
10
10
serde:: Raw ,
11
11
EventId , OwnedEventId , UserId ,
12
12
} ;
13
- use tracing:: { field :: display , instrument, trace} ;
13
+ use tracing:: { instrument, trace} ;
14
14
15
15
use super :: BaseClient ;
16
16
use crate :: { error:: Result , store:: StateChanges , PreviousEventsProvider , RoomInfo } ;
17
17
18
- #[ instrument( skip_all, fields( room_id) ) ]
18
+ #[ instrument( skip_all, fields( room_id = %room_info . room_id ) ) ]
19
19
pub ( crate ) async fn compute_notifications (
20
20
client : & BaseClient ,
21
21
changes : & StateChanges ,
22
22
previous_events_provider : & dyn PreviousEventsProvider ,
23
23
new_events : & [ SyncTimelineEvent ] ,
24
24
room_info : & mut RoomInfo ,
25
25
) -> Result < ( ) > {
26
- // Only apply the algorithm to encrypted rooms, since unencrypted rooms' unread
27
- // notification counts ought to be properly computed by the server.
28
- if !room_info. is_encrypted ( ) {
29
- return Ok ( ( ) ) ;
30
- }
31
-
32
- tracing:: Span :: current ( ) . record ( "room_id" , display ( & room_info. room_id ) ) ;
33
-
34
26
let user_id = & client. session_meta ( ) . unwrap ( ) . user_id ;
35
- let prev_latest_receipt_event_id = room_info. latest_read_receipt_event_id . clone ( ) ;
27
+ let prev_latest_receipt_event_id = room_info. read_receipts . latest_read_receipt_event_id . clone ( ) ;
36
28
37
29
if let Some ( receipt_event) = changes. receipts . get ( room_info. room_id ( ) ) {
38
30
trace ! ( "Got a new receipt event!" ) ;
@@ -62,7 +54,7 @@ pub(crate) async fn compute_notifications(
62
54
// about.
63
55
64
56
// First, save the event id as the latest one that has a read receipt.
65
- room_info. latest_read_receipt_event_id = Some ( receipt_event_id. clone ( ) ) ;
57
+ room_info. read_receipts . latest_read_receipt_event_id = Some ( receipt_event_id. clone ( ) ) ;
66
58
67
59
// Try to find if the read receipts refers to an event from the current sync, to
68
60
// avoid searching the cached timeline events.
@@ -110,17 +102,28 @@ pub(crate) async fn compute_notifications(
110
102
// for the next receipt.
111
103
trace ! ( "All other ways failed, including all new events for the receipts count." ) ;
112
104
for event in new_events {
113
- if event. push_actions . iter ( ) . any ( ruma:: push:: Action :: is_highlight) {
114
- room_info. notification_counts . highlight_count += 1 ;
115
- }
116
- if marks_as_unread ( & event. event , user_id) {
117
- room_info. notification_counts . notification_count += 1 ;
118
- }
105
+ count_unread_and_mentions ( event, user_id, room_info) ;
119
106
}
120
107
121
108
Ok ( ( ) )
122
109
}
123
110
111
+ #[ inline( always) ]
112
+ fn count_unread_and_mentions (
113
+ event : & SyncTimelineEvent ,
114
+ user_id : & UserId ,
115
+ room_info : & mut RoomInfo ,
116
+ ) {
117
+ for action in & event. push_actions {
118
+ if action. should_notify ( ) && marks_as_unread ( & event. event , user_id) {
119
+ room_info. read_receipts . num_unread += 1 ;
120
+ }
121
+ if action. is_highlight ( ) {
122
+ room_info. read_receipts . num_mentions += 1 ;
123
+ }
124
+ }
125
+ }
126
+
124
127
/// Try to find the event to which the receipt attaches to, and if found, will
125
128
/// update the notification count in the room.
126
129
///
@@ -134,20 +137,14 @@ fn find_and_count_events<'a>(
134
137
let mut counting_receipts = false ;
135
138
for event in events {
136
139
if counting_receipts {
137
- for action in & event. push_actions {
138
- if action. is_highlight ( ) {
139
- room_info. notification_counts . highlight_count += 1 ;
140
- }
141
- if action. should_notify ( ) && marks_as_unread ( & event. event , user_id) {
142
- room_info. notification_counts . notification_count += 1 ;
143
- }
144
- }
140
+ count_unread_and_mentions ( event, user_id, room_info) ;
145
141
} else if let Ok ( Some ( event_id) ) = event. event . get_field :: < OwnedEventId > ( "event_id" ) {
146
142
if event_id == receipt_event_id {
147
143
// Bingo! Switch over to the counting state, after resetting the
148
144
// previous counts.
149
145
trace ! ( "Found the event the receipt was referring to! Starting to count." ) ;
150
- room_info. notification_counts = Default :: default ( ) ;
146
+ room_info. read_receipts . num_unread = 0 ;
147
+ room_info. read_receipts . num_mentions = 0 ;
151
148
counting_receipts = true ;
152
149
}
153
150
}
0 commit comments