Skip to main content

matrix_sdk_ui/room_list_service/filters/
unread.rs

1// Copyright 2024 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use matrix_sdk_base::read_receipts::RoomReadReceipts;
16
17use super::{super::RoomListItem, Filter};
18
19type IsMarkedUnread = bool;
20
21fn matches<F>(read_receipts_and_unread: F, room: &RoomListItem) -> bool
22where
23    F: Fn(&RoomListItem) -> (RoomReadReceipts, IsMarkedUnread),
24{
25    let (read_receipts, is_marked_unread) = read_receipts_and_unread(room);
26
27    read_receipts.num_notifications > 0 || is_marked_unread
28}
29
30/// Create a new filter that will filter out rooms that have no unread
31/// notifications (different from unread messages), or is not marked as unread.
32pub fn new_filter() -> impl Filter {
33    let read_receipts_and_unread =
34        |room: &RoomListItem| (room.read_receipts(), room.is_marked_unread());
35
36    move |room_list_entry| -> bool { matches(read_receipts_and_unread, room_list_entry) }
37}
38
39#[cfg(test)]
40mod tests {
41    use std::ops::Not;
42
43    use matrix_sdk::test_utils::mocks::MatrixMockServer;
44    use matrix_sdk_base::read_receipts::RoomReadReceipts;
45    use matrix_sdk_test::async_test;
46    use ruma::room_id;
47
48    use super::{super::new_rooms, *};
49
50    #[async_test]
51    async fn test_has_unread_notifications() {
52        let server = MatrixMockServer::new().await;
53        let client = server.client_builder().build().await;
54        let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
55
56        for is_marked_as_unread in [true, false] {
57            let read_receipts_and_unread = |_: &RoomListItem| {
58                let read_receipts = RoomReadReceipts {
59                    num_unread: 42,
60                    num_notifications: 42,
61                    ..Default::default()
62                };
63
64                (read_receipts, is_marked_as_unread)
65            };
66
67            assert!(matches(read_receipts_and_unread, &room));
68        }
69    }
70
71    #[async_test]
72    async fn test_has_unread_messages_but_no_unread_notifications_and_is_not_marked_as_unread() {
73        let server = MatrixMockServer::new().await;
74        let client = server.client_builder().build().await;
75        let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
76
77        let read_receipts_and_unread = |_: &RoomListItem| {
78            let read_receipts =
79                RoomReadReceipts { num_unread: 42, num_notifications: 0, ..Default::default() };
80
81            (read_receipts, false)
82        };
83
84        assert!(matches(read_receipts_and_unread, &room).not());
85    }
86
87    #[async_test]
88    async fn test_has_unread_messages_but_no_unread_notifications_and_is_marked_as_unread() {
89        let server = MatrixMockServer::new().await;
90        let client = server.client_builder().build().await;
91        let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
92
93        let read_receipts_and_unread = |_: &RoomListItem| {
94            let read_receipts =
95                RoomReadReceipts { num_unread: 42, num_notifications: 0, ..Default::default() };
96
97            (read_receipts, true)
98        };
99
100        assert!(matches(read_receipts_and_unread, &room));
101    }
102
103    #[async_test]
104    async fn test_has_no_unread_notifications_and_is_not_marked_as_unread() {
105        let server = MatrixMockServer::new().await;
106        let client = server.client_builder().build().await;
107        let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
108
109        let read_receipts_and_unread = |_: &RoomListItem| (RoomReadReceipts::default(), false);
110
111        assert!(matches(read_receipts_and_unread, &room).not());
112    }
113
114    #[async_test]
115    async fn test_has_no_unread_notifications_and_is_marked_as_unread() {
116        let server = MatrixMockServer::new().await;
117        let client = server.client_builder().build().await;
118        let [room] = new_rooms([room_id!("!a:b.c")], &client, &server).await;
119
120        let read_receipts_and_unread = |_: &RoomListItem| (RoomReadReceipts::default(), true);
121
122        assert!(matches(read_receipts_and_unread, &room));
123    }
124}