Merge pull request #3386 from matrix-org/stefan/joinedRoomListFilter

feat(ui): add room list filter for excluding non-joined rooms
This commit is contained in:
Ivan Enderlin
2024-05-13 11:24:13 +02:00
committed by GitHub
4 changed files with 89 additions and 4 deletions

View File

@@ -16,9 +16,9 @@ use matrix_sdk_ui::{
room_list_service::{
filters::{
new_filter_all, new_filter_any, new_filter_category, new_filter_favourite,
new_filter_fuzzy_match_room_name, new_filter_invite, new_filter_non_left,
new_filter_none, new_filter_normalized_match_room_name, new_filter_unread,
RoomCategory,
new_filter_fuzzy_match_room_name, new_filter_invite, new_filter_joined,
new_filter_non_left, new_filter_none, new_filter_normalized_match_room_name,
new_filter_unread, RoomCategory,
},
BoxedFilterFn,
},
@@ -423,6 +423,7 @@ pub enum RoomListEntriesDynamicFilterKind {
All { filters: Vec<RoomListEntriesDynamicFilterKind> },
Any { filters: Vec<RoomListEntriesDynamicFilterKind> },
NonLeft,
Joined,
Unread,
Favourite,
Invite,
@@ -463,6 +464,7 @@ impl FilterWrapper {
filters.into_iter().map(|filter| FilterWrapper::from(client, filter).0).collect(),
))),
Kind::NonLeft => Self(Box::new(new_filter_non_left(client))),
Kind::Joined => Self(Box::new(new_filter_joined(client))),
Kind::Unread => Self(Box::new(new_filter_unread(client))),
Kind::Favourite => Self(Box::new(new_filter_favourite(client))),
Kind::Invite => Self(Box::new(new_filter_invite(client))),

View File

@@ -72,7 +72,7 @@ mod tests {
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
// When a room has been joined, it does match (unless it's empty).
// When a room is an invite, it does match (unless it's empty).
let matcher = InviteRoomMatcher { state: |_| Some(RoomState::Invited) };
assert!(!matcher.matches(&RoomListEntry::Empty));
assert!(matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));

View File

@@ -0,0 +1,81 @@
use matrix_sdk::{Client, RoomListEntry};
use matrix_sdk_base::RoomState;
use super::Filter;
struct JoinedRoomMatcher<F>
where
F: Fn(&RoomListEntry) -> Option<RoomState>,
{
state: F,
}
impl<F> JoinedRoomMatcher<F>
where
F: Fn(&RoomListEntry) -> Option<RoomState>,
{
fn matches(&self, room: &RoomListEntry) -> bool {
if !matches!(room, RoomListEntry::Filled(_) | RoomListEntry::Invalidated(_)) {
return false;
}
if let Some(state) = (self.state)(room) {
state == RoomState::Joined
} else {
false
}
}
}
/// Create a new filter that will accept all filled or invalidated entries, but
/// filters out rooms that are not joined (see
/// [`matrix_sdk_base::RoomState::Joined`]).
pub fn new_filter(client: &Client) -> impl Filter {
let client = client.clone();
let matcher = JoinedRoomMatcher {
state: move |room| {
let room_id = room.as_room_id()?;
let room = client.get_room(room_id)?;
Some(room.state())
},
};
move |room_list_entry| -> bool { matcher.matches(room_list_entry) }
}
#[cfg(test)]
mod tests {
use matrix_sdk::RoomListEntry;
use matrix_sdk_base::RoomState;
use ruma::room_id;
use super::JoinedRoomMatcher;
#[test]
fn test_all_joined_kind_of_room_list_entry() {
// When we can't figure out the room state, nothing matches.
let matcher = JoinedRoomMatcher { state: |_| None };
assert!(!matcher.matches(&RoomListEntry::Empty));
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
// When a room has been left, it doesn't match.
let matcher = JoinedRoomMatcher { state: |_| Some(RoomState::Left) };
assert!(!matcher.matches(&RoomListEntry::Empty));
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
// When a room is an invite, it doesn't match.
let matcher = JoinedRoomMatcher { state: |_| Some(RoomState::Invited) };
assert!(!matcher.matches(&RoomListEntry::Empty));
assert!(!matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
assert!(!matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
// When a room has been joined, it does match (unless it's empty).
let matcher = JoinedRoomMatcher { state: |_| Some(RoomState::Joined) };
assert!(!matcher.matches(&RoomListEntry::Empty));
assert!(matcher.matches(&RoomListEntry::Filled(room_id!("!r0:bar.org").to_owned())));
assert!(matcher.matches(&RoomListEntry::Invalidated(room_id!("!r0:bar.org").to_owned())));
}
}

View File

@@ -60,6 +60,7 @@ mod category;
mod favourite;
mod fuzzy_match_room_name;
mod invite;
mod joined;
mod non_left;
mod none;
mod normalized_match_room_name;
@@ -72,6 +73,7 @@ pub use category::{new_filter as new_filter_category, RoomCategory};
pub use favourite::new_filter as new_filter_favourite;
pub use fuzzy_match_room_name::new_filter as new_filter_fuzzy_match_room_name;
pub use invite::new_filter as new_filter_invite;
pub use joined::new_filter as new_filter_joined;
use matrix_sdk::RoomListEntry;
pub use non_left::new_filter as new_filter_non_left;
pub use none::new_filter as new_filter_none;