Skip to content

Commit 6f9147d

Browse files
authored
Merge pull request #3205 from matrix-org/stefan/invites_main_room_list
feat: Expose a room list filter for Invites only
2 parents 78889ae + 6a67ff9 commit 6f9147d

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

bindings/matrix-sdk-ffi/src/room_list.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ use matrix_sdk_ui::{
1616
room_list_service::{
1717
filters::{
1818
new_filter_all, new_filter_any, new_filter_category, new_filter_favourite,
19-
new_filter_fuzzy_match_room_name, new_filter_non_left, new_filter_none,
20-
new_filter_normalized_match_room_name, new_filter_unread, RoomCategory,
19+
new_filter_fuzzy_match_room_name, new_filter_invite, new_filter_non_left,
20+
new_filter_none, new_filter_normalized_match_room_name, new_filter_unread,
21+
RoomCategory,
2122
},
2223
BoxedFilterFn,
2324
},
@@ -421,6 +422,7 @@ pub enum RoomListEntriesDynamicFilterKind {
421422
NonLeft,
422423
Unread,
423424
Favourite,
425+
Invite,
424426
Category { expect: RoomListFilterCategory },
425427
None,
426428
NormalizedMatchRoomName { pattern: String },
@@ -460,6 +462,7 @@ impl FilterWrapper {
460462
Kind::NonLeft => Self(Box::new(new_filter_non_left(client))),
461463
Kind::Unread => Self(Box::new(new_filter_unread(client))),
462464
Kind::Favourite => Self(Box::new(new_filter_favourite(client))),
465+
Kind::Invite => Self(Box::new(new_filter_invite(client))),
463466
Kind::Category { expect } => Self(Box::new(new_filter_category(client, expect.into()))),
464467
Kind::None => Self(Box::new(new_filter_none())),
465468
Kind::NormalizedMatchRoomName { pattern } => {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use matrix_sdk::{Client, RoomListEntry};
2+
use matrix_sdk_base::RoomState;
3+
4+
use super::Filter;
5+
6+
struct InviteRoomMatcher<F>
7+
where
8+
F: Fn(&RoomListEntry) -> Option<RoomState>,
9+
{
10+
state: F,
11+
}
12+
13+
impl<F> InviteRoomMatcher<F>
14+
where
15+
F: Fn(&RoomListEntry) -> Option<RoomState>,
16+
{
17+
fn matches(&self, room: &RoomListEntry) -> bool {
18+
if !matches!(room, RoomListEntry::Filled(_) | RoomListEntry::Invalidated(_)) {
19+
return false;
20+
}
21+
22+
if let Some(state) = (self.state)(room) {
23+
state == RoomState::Invited
24+
} else {
25+
false
26+
}
27+
}
28+
}
29+
30+
/// Create a new filter that will accept all filled or invalidated entries, but
31+
/// filters out rooms that are not invites (see
32+
/// [`matrix_sdk_base::RoomState::Invited`]).
33+
pub fn new_filter(client: &Client) -> impl Filter {
34+
let client = client.clone();
35+
36+
let matcher = InviteRoomMatcher {
37+
state: move |room| {
38+
let room_id = room.as_room_id()?;
39+
let room = client.get_room(room_id)?;
40+
Some(room.state())
41+
},
42+
};
43+
44+
move |room_list_entry| -> bool { matcher.matches(room_list_entry) }
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use matrix_sdk::RoomListEntry;
50+
use matrix_sdk_base::RoomState;
51+
use ruma::room_id;
52+
53+
use super::InviteRoomMatcher;
54+
55+
#[test]
56+
fn test_all_invite_kind_of_room_list_entry() {
57+
// When we can't figure out the room state, nothing matches.
58+
let matcher = InviteRoomMatcher { state: |_| None };
59+
assert!(!matcher.matches(&RoomListEntry::Empty));
60+
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
61+
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
62+
63+
// When a room has been left, it doesn't match.
64+
let matcher = InviteRoomMatcher { state: |_| Some(RoomState::Left) };
65+
assert!(!matcher.matches(&RoomListEntry::Empty));
66+
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
67+
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
68+
69+
// When a room has been joined, it doesn't match.
70+
let matcher = InviteRoomMatcher { state: |_| Some(RoomState::Joined) };
71+
assert!(!matcher.matches(&RoomListEntry::Empty));
72+
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
73+
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
74+
75+
// When a room has been joined, it does match (unless it's empty).
76+
let matcher = InviteRoomMatcher { state: |_| Some(RoomState::Invited) };
77+
assert!(!matcher.matches(&RoomListEntry::Empty));
78+
assert!(matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
79+
assert!(matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
80+
}
81+
}

crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ mod any;
5959
mod category;
6060
mod favourite;
6161
mod fuzzy_match_room_name;
62+
mod invite;
6263
mod non_left;
6364
mod none;
6465
mod normalized_match_room_name;
@@ -70,6 +71,7 @@ pub use any::new_filter as new_filter_any;
7071
pub use category::{new_filter as new_filter_category, RoomCategory};
7172
pub use favourite::new_filter as new_filter_favourite;
7273
pub use fuzzy_match_room_name::new_filter as new_filter_fuzzy_match_room_name;
74+
pub use invite::new_filter as new_filter_invite;
7375
use matrix_sdk::RoomListEntry;
7476
pub use non_left::new_filter as new_filter_non_left;
7577
pub use none::new_filter as new_filter_none;

0 commit comments

Comments
 (0)