feature(space) : filter space manually so we can show space invites

This commit is contained in:
ganfra 2025-10-02 17:38:47 +02:00
parent db424b6e41
commit 576429b183
4 changed files with 51 additions and 25 deletions

View file

@ -58,11 +58,12 @@ sealed interface RoomListFilter {
data object Invite : RoomListFilter data object Invite : RoomListFilter
/** /**
* A filter that matches either Group or People rooms. * A filter that matches either Group,People rooms or Space.
*/ */
sealed interface Category : RoomListFilter { sealed interface Category : RoomListFilter {
data object Group : Category data object Group : Category
data object People : Category data object People : Category
data object Space : Category
} }
/** /**

View file

@ -29,7 +29,6 @@ import org.matrix.rustcomponents.sdk.RoomList as InnerRoomList
private val ROOM_LIST_RUST_FILTERS = listOf( private val ROOM_LIST_RUST_FILTERS = listOf(
RoomListEntriesDynamicFilterKind.NonLeft, RoomListEntriesDynamicFilterKind.NonLeft,
RoomListEntriesDynamicFilterKind.NonSpace,
RoomListEntriesDynamicFilterKind.DeduplicateVersions RoomListEntriesDynamicFilterKind.DeduplicateVersions
) )

View file

@ -15,41 +15,57 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
val RoomListFilter.predicate val RoomListFilter.predicate
get() = when (this) { get() = when (this) {
is RoomListFilter.All -> { _: RoomSummary -> true } is RoomListFilter.All -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) }
is RoomListFilter.Any -> { _: RoomSummary -> true } is RoomListFilter.Any -> { roomSummary -> NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary) }
RoomListFilter.None -> { _: RoomSummary -> false } RoomListFilter.None -> { _ -> false }
RoomListFilter.Category.Group -> { roomSummary: RoomSummary -> RoomListFilter.Category.Group -> { roomSummary: RoomSummary ->
!roomSummary.info.isDm && !roomSummary.isInvited() !roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
} }
RoomListFilter.Category.People -> { roomSummary: RoomSummary -> RoomListFilter.Category.People -> { roomSummary: RoomSummary ->
roomSummary.info.isDm && !roomSummary.isInvited() roomSummary.info.isDm && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
} }
RoomListFilter.Category.Space -> IsSpacePredicate
RoomListFilter.Favorite -> { roomSummary: RoomSummary -> RoomListFilter.Favorite -> { roomSummary: RoomSummary ->
roomSummary.info.isFavorite && !roomSummary.isInvited() roomSummary.info.isFavorite && NonInvitedPredicate(roomSummary) && NonSpacePredicate(roomSummary)
} }
RoomListFilter.Unread -> { roomSummary: RoomSummary -> RoomListFilter.Unread -> { roomSummary: RoomSummary ->
!roomSummary.isInvited() && (roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread) NonInvitedPredicate(roomSummary) &&
NonSpacePredicate(roomSummary) &&
(roomSummary.info.numUnreadNotifications > 0 || roomSummary.info.isMarkedUnread)
} }
is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary -> is RoomListFilter.NormalizedMatchRoomName -> { roomSummary: RoomSummary ->
roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) roomSummary.info.name?.withoutAccents().orEmpty().contains(normalizedPattern, ignoreCase = true) &&
} (NonSpacePredicate(roomSummary) || IsInvitedPredicate(roomSummary))
RoomListFilter.Invite -> { roomSummary: RoomSummary ->
roomSummary.isInvited()
} }
RoomListFilter.Invite -> IsInvitedPredicate
} }
fun List<RoomSummary>.filter(filter: RoomListFilter): List<RoomSummary> { fun List<RoomSummary>.filter(filter: RoomListFilter): List<RoomSummary> {
return when (filter) { return when (filter) {
is RoomListFilter.All -> { is RoomListFilter.All -> {
val predicates = filter.filters.map { it.predicate } val predicates = if (filter.filters.isNotEmpty()) {
filter.filters.map { it.predicate }
} else {
listOf(filter.predicate)
}
filter { roomSummary -> predicates.all { it(roomSummary) } } filter { roomSummary -> predicates.all { it(roomSummary) } }
} }
is RoomListFilter.Any -> { is RoomListFilter.Any -> {
val predicates = filter.filters.map { it.predicate } val predicates = if (filter.filters.isNotEmpty()) {
filter.filters.map { it.predicate }
} else {
listOf(filter.predicate)
}
filter { roomSummary -> predicates.any { it(roomSummary) } } filter { roomSummary -> predicates.any { it(roomSummary) } }
} }
else -> filter(filter.predicate) else -> filter(filter.predicate)
} }
} }
private fun RoomSummary.isInvited() = info.currentUserMembership == CurrentUserMembership.INVITED private val IsSpacePredicate = { roomSummary: RoomSummary -> roomSummary.info.isSpace }
private val NonSpacePredicate = { roomSummary: RoomSummary -> !IsSpacePredicate(roomSummary) }
private val IsInvitedPredicate = { roomSummary: RoomSummary -> roomSummary.info.currentUserMembership == CurrentUserMembership.INVITED }
private val NonInvitedPredicate = { roomSummary: RoomSummary -> !IsInvitedPredicate(roomSummary) }

View file

@ -41,6 +41,14 @@ class RoomListFilterTest {
currentUserMembership = CurrentUserMembership.INVITED currentUserMembership = CurrentUserMembership.INVITED
) )
private val space = aRoomSummary(
isSpace = true
)
private val invitedSpace = aRoomSummary(
isSpace = true,
currentUserMembership = CurrentUserMembership.INVITED
)
private val roomSummaries = listOf( private val roomSummaries = listOf(
regularRoom, regularRoom,
dmRoom, dmRoom,
@ -49,13 +57,15 @@ class RoomListFilterTest {
unreadNotificationRoom, unreadNotificationRoom,
roomToSearch, roomToSearch,
roomWithAccent, roomWithAccent,
invitedRoom invitedRoom,
space,
invitedSpace,
) )
@Test @Test
fun `Room list filter all empty`() = runTest { fun `Room list filter all empty`() = runTest {
val filter = RoomListFilter.all() val filter = RoomListFilter.all()
assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries) assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries - space)
} }
@Test @Test
@ -83,6 +93,12 @@ class RoomListFilterTest {
) )
} }
@Test
fun `Room list filter space`() = runTest {
val filter = RoomListFilter.Category.Space
assertThat(roomSummaries.filter(filter)).containsExactly(space, invitedSpace)
}
@Test @Test
fun `Room list filter favorite`() = runTest { fun `Room list filter favorite`() = runTest {
val filter = RoomListFilter.Favorite val filter = RoomListFilter.Favorite
@ -98,7 +114,7 @@ class RoomListFilterTest {
@Test @Test
fun `Room list filter invites`() = runTest { fun `Room list filter invites`() = runTest {
val filter = RoomListFilter.Invite val filter = RoomListFilter.Invite
assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom) assertThat(roomSummaries.filter(filter)).containsExactly(invitedRoom, invitedSpace)
} }
@Test @Test
@ -136,10 +152,4 @@ class RoomListFilterTest {
) )
assertThat(roomSummaries.filter(filter)).isEmpty() assertThat(roomSummaries.filter(filter)).isEmpty()
} }
@Test
fun `Room list filter all with empty list`() = runTest {
val filter = RoomListFilter.all()
assertThat(roomSummaries.filter(filter)).isEqualTo(roomSummaries)
}
} }