Add room list filter combining based on space selection
This commit is contained in:
parent
eb94015996
commit
915aca9c1d
7 changed files with 48 additions and 49 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
package io.element.android.features.home.impl.filters
|
package io.element.android.features.home.impl.filters
|
||||||
|
|
||||||
import io.element.android.features.home.impl.R
|
import io.element.android.features.home.impl.R
|
||||||
|
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum class representing the different filters that can be applied to the room list.
|
* Enum class representing the different filters that can be applied to the room list.
|
||||||
|
|
@ -30,3 +31,13 @@ enum class RoomListFilter(val stringResource: Int) {
|
||||||
Invites -> setOf(Rooms, People, Unread, Favourites)
|
Invites -> setOf(Rooms, People, Unread, Favourites)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun RoomListFilter.into(): MatrixRoomListFilter {
|
||||||
|
return when (this) {
|
||||||
|
RoomListFilter.Rooms -> MatrixRoomListFilter.Category.Group
|
||||||
|
RoomListFilter.People -> MatrixRoomListFilter.Category.People
|
||||||
|
RoomListFilter.Unread -> MatrixRoomListFilter.Unread
|
||||||
|
RoomListFilter.Favourites -> MatrixRoomListFilter.Favorite
|
||||||
|
RoomListFilter.Invites -> MatrixRoomListFilter.Invite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,17 @@
|
||||||
package io.element.android.features.home.impl.filters
|
package io.element.android.features.home.impl.filters
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.produceState
|
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.home.impl.datasource.RoomListDataSource
|
|
||||||
import io.element.android.features.home.impl.filters.selection.FilterSelectionStrategy
|
import io.element.android.features.home.impl.filters.selection.FilterSelectionStrategy
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter as MatrixRoomListFilter
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
class RoomListFiltersPresenter(
|
class RoomListFiltersPresenter(
|
||||||
private val roomListDataSource: RoomListDataSource,
|
|
||||||
private val filterSelectionStrategy: FilterSelectionStrategy,
|
private val filterSelectionStrategy: FilterSelectionStrategy,
|
||||||
) : Presenter<RoomListFiltersState> {
|
) : Presenter<RoomListFiltersState> {
|
||||||
private val initialFilters = filterSelectionStrategy.filterSelectionStates.value.toImmutableList()
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): RoomListFiltersState {
|
override fun present(): RoomListFiltersState {
|
||||||
fun handleEvent(event: RoomListFiltersEvent) {
|
fun handleEvent(event: RoomListFiltersEvent) {
|
||||||
|
|
@ -40,31 +33,9 @@ class RoomListFiltersPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val filters by produceState(initialValue = initialFilters) {
|
val filters by filterSelectionStrategy.filterSelectionStates.collectAsState()
|
||||||
filterSelectionStrategy.filterSelectionStates
|
|
||||||
.map { filters ->
|
|
||||||
value = filters.toImmutableList()
|
|
||||||
filters.mapNotNull { filterState ->
|
|
||||||
if (!filterState.isSelected) {
|
|
||||||
return@mapNotNull null
|
|
||||||
}
|
|
||||||
when (filterState.filter) {
|
|
||||||
RoomListFilter.Rooms -> MatrixRoomListFilter.Category.Group
|
|
||||||
RoomListFilter.People -> MatrixRoomListFilter.Category.People
|
|
||||||
RoomListFilter.Unread -> MatrixRoomListFilter.Unread
|
|
||||||
RoomListFilter.Favourites -> MatrixRoomListFilter.Favorite
|
|
||||||
RoomListFilter.Invites -> MatrixRoomListFilter.Invite
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.collectLatest { filters ->
|
|
||||||
val result = MatrixRoomListFilter.All(filters)
|
|
||||||
roomListDataSource.updateFilter(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RoomListFiltersState(
|
return RoomListFiltersState(
|
||||||
filterSelectionStates = filters,
|
filterSelectionStates = filters.toImmutableList(),
|
||||||
eventSink = ::handleEvent,
|
eventSink = ::handleEvent,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@ import io.element.android.features.announcement.api.Announcement
|
||||||
import io.element.android.features.announcement.api.AnnouncementService
|
import io.element.android.features.announcement.api.AnnouncementService
|
||||||
import io.element.android.features.home.impl.datasource.RoomListDataSource
|
import io.element.android.features.home.impl.datasource.RoomListDataSource
|
||||||
import io.element.android.features.home.impl.filters.RoomListFiltersState
|
import io.element.android.features.home.impl.filters.RoomListFiltersState
|
||||||
|
import io.element.android.features.home.impl.filters.into
|
||||||
import io.element.android.features.home.impl.search.RoomListSearchEvent
|
import io.element.android.features.home.impl.search.RoomListSearchEvent
|
||||||
import io.element.android.features.home.impl.search.RoomListSearchState
|
import io.element.android.features.home.impl.search.RoomListSearchState
|
||||||
import io.element.android.features.home.impl.spacefilters.SpaceFiltersState
|
import io.element.android.features.home.impl.spacefilters.SpaceFiltersState
|
||||||
|
import io.element.android.features.home.impl.spacefilters.selectedFilter
|
||||||
import io.element.android.features.invite.api.SeenInvitesStore
|
import io.element.android.features.invite.api.SeenInvitesStore
|
||||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.AcceptInvite
|
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.AcceptInvite
|
||||||
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.DeclineInvite
|
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents.DeclineInvite
|
||||||
|
|
@ -45,6 +47,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||||
import io.element.android.libraries.matrix.api.roomlist.RoomList
|
import io.element.android.libraries.matrix.api.roomlist.RoomList
|
||||||
|
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter
|
||||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||||
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
|
import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar
|
||||||
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||||
|
|
@ -153,6 +156,21 @@ class RoomListPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(filtersState.filterSelectionStates, spaceFiltersState.selectedFilter()) {
|
||||||
|
val selectedFilters = filtersState.filterSelectionStates.mapNotNull { filterState ->
|
||||||
|
if (!filterState.isSelected) {
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
filterState.filter.into()
|
||||||
|
}
|
||||||
|
val selectedSpaceFilter = when (spaceFiltersState) {
|
||||||
|
is SpaceFiltersState.Selected -> RoomListFilter.Identifiers(spaceFiltersState.selectedFilter.descendants)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val allFilters = RoomListFilter.All(selectedFilters + listOfNotNull(selectedSpaceFilter))
|
||||||
|
roomListDataSource.updateFilter(allFilters)
|
||||||
|
}
|
||||||
|
|
||||||
val contentState = roomListContentState(
|
val contentState = roomListContentState(
|
||||||
securityBannerDismissed,
|
securityBannerDismissed,
|
||||||
showNewNotificationSoundBanner,
|
showNewNotificationSoundBanner,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
package io.element.android.features.home.impl.spacefilters
|
package io.element.android.features.home.impl.spacefilters
|
||||||
|
|
||||||
import androidx.compose.foundation.text.input.TextFieldState
|
import androidx.compose.foundation.text.input.TextFieldState
|
||||||
|
import io.element.android.features.home.impl.filters.RoomListFilter
|
||||||
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
@ -40,3 +41,10 @@ sealed interface SpaceFiltersState {
|
||||||
val eventSink: (SpaceFiltersEvent.Selected) -> Unit,
|
val eventSink: (SpaceFiltersEvent.Selected) -> Unit,
|
||||||
) : SpaceFiltersState
|
) : SpaceFiltersState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SpaceFiltersState.selectedFilter(): SpaceServiceFilter? {
|
||||||
|
return when (this) {
|
||||||
|
is SpaceFiltersState.Selected -> this.selectedFilter
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
package io.element.android.features.home.impl.filters
|
package io.element.android.features.home.impl.filters
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.home.impl.FakeDateTimeObserver
|
|
||||||
import io.element.android.features.home.impl.datasource.RoomListDataSource
|
|
||||||
import io.element.android.features.home.impl.datasource.aRoomListRoomSummaryFactory
|
|
||||||
import io.element.android.features.home.impl.filters.selection.DefaultFilterSelectionStrategy
|
import io.element.android.features.home.impl.filters.selection.DefaultFilterSelectionStrategy
|
||||||
import io.element.android.features.home.impl.filters.selection.FilterSelectionState
|
import io.element.android.features.home.impl.filters.selection.FilterSelectionState
|
||||||
import io.element.android.libraries.dateformatter.api.DateFormatter
|
import io.element.android.libraries.dateformatter.api.DateFormatter
|
||||||
|
|
@ -22,10 +19,8 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification
|
||||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||||
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
|
||||||
import io.element.android.tests.testutils.awaitLastSequentialItem
|
import io.element.android.tests.testutils.awaitLastSequentialItem
|
||||||
import io.element.android.tests.testutils.test
|
import io.element.android.tests.testutils.test
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.advanceUntilIdle
|
import kotlinx.coroutines.test.advanceUntilIdle
|
||||||
|
|
@ -117,18 +112,6 @@ private fun TestScope.createRoomListFiltersPresenter(
|
||||||
roomLatestEventFormatter: RoomLatestEventFormatter = FakeRoomLatestEventFormatter(),
|
roomLatestEventFormatter: RoomLatestEventFormatter = FakeRoomLatestEventFormatter(),
|
||||||
): RoomListFiltersPresenter {
|
): RoomListFiltersPresenter {
|
||||||
return RoomListFiltersPresenter(
|
return RoomListFiltersPresenter(
|
||||||
roomListDataSource = RoomListDataSource(
|
|
||||||
roomListService = roomListService,
|
|
||||||
roomListRoomSummaryFactory = aRoomListRoomSummaryFactory(
|
|
||||||
dateFormatter = dateFormatter,
|
|
||||||
roomLatestEventFormatter = roomLatestEventFormatter,
|
|
||||||
),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(),
|
|
||||||
notificationSettingsService = notificationSettingsService,
|
|
||||||
sessionCoroutineScope = backgroundScope,
|
|
||||||
dateTimeObserver = FakeDateTimeObserver(),
|
|
||||||
analyticsService = FakeAnalyticsService(),
|
|
||||||
),
|
|
||||||
filterSelectionStrategy = DefaultFilterSelectionStrategy(),
|
filterSelectionStrategy = DefaultFilterSelectionStrategy(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.roomlist
|
package io.element.android.libraries.matrix.api.roomlist
|
||||||
|
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
sealed interface RoomListFilter {
|
sealed interface RoomListFilter {
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,6 +43,10 @@ sealed interface RoomListFilter {
|
||||||
val filters: List<RoomListFilter>
|
val filters: List<RoomListFilter>
|
||||||
) : RoomListFilter
|
) : RoomListFilter
|
||||||
|
|
||||||
|
data class Identifiers(
|
||||||
|
val values : List<RoomId>,
|
||||||
|
): RoomListFilter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A filter that matches rooms that are unread.
|
* A filter that matches rooms that are unread.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Any
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Category
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Category
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.DeduplicateVersions
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.DeduplicateVersions
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Favourite
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Favourite
|
||||||
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Identifiers
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Invite
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.Invite
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.NonLeft
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.NonLeft
|
||||||
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.NonSpace
|
import org.matrix.rustcomponents.sdk.RoomListEntriesDynamicFilterKind.NonSpace
|
||||||
|
|
@ -60,6 +61,7 @@ internal object RoomListFilterMapper {
|
||||||
return when (filter) {
|
return when (filter) {
|
||||||
is RoomListFilter.All -> All(filters = filter.filters.map { mapFilter(it) })
|
is RoomListFilter.All -> All(filters = filter.filters.map { mapFilter(it) })
|
||||||
is RoomListFilter.Any -> Any(filters = filter.filters.map { mapFilter(it) })
|
is RoomListFilter.Any -> Any(filters = filter.filters.map { mapFilter(it) })
|
||||||
|
is RoomListFilter.Identifiers -> Identifiers(identifiers = filter.values.map { it.value })
|
||||||
RoomListFilter.None -> None
|
RoomListFilter.None -> None
|
||||||
RoomListFilter.Category.Group -> Category(RoomListFilterCategory.GROUP)
|
RoomListFilter.Category.Group -> Category(RoomListFilterCategory.GROUP)
|
||||||
RoomListFilter.Category.People -> Category(RoomListFilterCategory.PEOPLE)
|
RoomListFilter.Category.People -> Category(RoomListFilterCategory.PEOPLE)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue