matrix_sdk_ui/room_list_service/filters/
unread.rs1use matrix_sdk_base::read_receipts::RoomReadReceipts;
16
17use super::{super::Room, Filter};
18
19type IsMarkedUnread = bool;
20
21struct UnreadRoomMatcher<F>
22where
23 F: Fn(&Room) -> (RoomReadReceipts, IsMarkedUnread),
24{
25 read_receipts_and_unread: F,
26}
27
28impl<F> UnreadRoomMatcher<F>
29where
30 F: Fn(&Room) -> (RoomReadReceipts, IsMarkedUnread),
31{
32 fn matches(&self, room: &Room) -> bool {
33 let (read_receipts, is_marked_unread) = (self.read_receipts_and_unread)(room);
34
35 read_receipts.num_notifications > 0 || is_marked_unread
36 }
37}
38
39pub fn new_filter() -> impl Filter {
42 let matcher = UnreadRoomMatcher {
43 read_receipts_and_unread: move |room| (room.read_receipts(), room.is_marked_unread()),
44 };
45
46 move |room_list_entry| -> bool { matcher.matches(room_list_entry) }
47}
48
49#[cfg(test)]
50mod tests {
51 use std::ops::Not;
52
53 use matrix_sdk::test_utils::logged_in_client_with_server;
54 use matrix_sdk_base::read_receipts::RoomReadReceipts;
55 use matrix_sdk_test::async_test;
56 use ruma::room_id;
57
58 use super::{super::new_rooms, *};
59
60 #[async_test]
61 async fn test_has_unread_notifications() {
62 let (client, server) = logged_in_client_with_server().await;
63 let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
64
65 for is_marked_as_unread in [true, false] {
66 let matcher = UnreadRoomMatcher {
67 read_receipts_and_unread: |_| {
68 let mut read_receipts = RoomReadReceipts::default();
69 read_receipts.num_unread = 42;
70 read_receipts.num_notifications = 42;
71
72 (read_receipts, is_marked_as_unread)
73 },
74 };
75
76 assert!(matcher.matches(&room));
77 }
78 }
79
80 #[async_test]
81 async fn test_has_unread_messages_but_no_unread_notifications_and_is_not_marked_as_unread() {
82 let (client, server) = logged_in_client_with_server().await;
83 let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
84
85 let matcher = UnreadRoomMatcher {
86 read_receipts_and_unread: |_| {
87 let mut read_receipts = RoomReadReceipts::default();
88 read_receipts.num_unread = 42;
89 read_receipts.num_notifications = 0;
90
91 (read_receipts, false)
92 },
93 };
94
95 assert!(matcher.matches(&room).not());
96 }
97
98 #[async_test]
99 async fn test_has_unread_messages_but_no_unread_notifications_and_is_marked_as_unread() {
100 let (client, server) = logged_in_client_with_server().await;
101 let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
102
103 let matcher = UnreadRoomMatcher {
104 read_receipts_and_unread: |_| {
105 let mut read_receipts = RoomReadReceipts::default();
106 read_receipts.num_unread = 42;
107 read_receipts.num_notifications = 0;
108
109 (read_receipts, true)
110 },
111 };
112
113 assert!(matcher.matches(&room));
114 }
115
116 #[async_test]
117 async fn test_has_no_unread_notifications_and_is_not_marked_as_unread() {
118 let (client, server) = logged_in_client_with_server().await;
119 let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
120
121 let matcher = UnreadRoomMatcher {
122 read_receipts_and_unread: |_| (RoomReadReceipts::default(), false),
123 };
124
125 assert!(matcher.matches(&room).not());
126 }
127
128 #[async_test]
129 async fn test_has_no_unread_notifications_and_is_marked_as_unread() {
130 let (client, server) = logged_in_client_with_server().await;
131 let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
132
133 let matcher =
134 UnreadRoomMatcher { read_receipts_and_unread: |_| (RoomReadReceipts::default(), true) };
135
136 assert!(matcher.matches(&room));
137 }
138}