Model SpaceFilters ui states
This commit is contained in:
@@ -7,4 +7,22 @@
|
||||
|
||||
package io.element.android.features.home.impl.spacefilters
|
||||
|
||||
sealed interface SpaceFiltersEvent
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||
|
||||
sealed interface SpaceFiltersEvent {
|
||||
// Only valid in Unselected state
|
||||
sealed interface Unselected : SpaceFiltersEvent {
|
||||
data object ShowFilters : Unselected
|
||||
}
|
||||
|
||||
// Only valid in Selecting state
|
||||
sealed interface Selecting : SpaceFiltersEvent {
|
||||
data object Cancel : Selecting
|
||||
data class SelectFilter(val spaceFilter: SpaceServiceFilter) : Selecting
|
||||
}
|
||||
|
||||
// Only valid in Selected state
|
||||
sealed interface Selected : SpaceFiltersEvent {
|
||||
data object ClearSelection : Selected
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,87 @@
|
||||
package io.element.android.features.home.impl.spacefilters
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@Inject
|
||||
class SpaceFiltersPresenter : Presenter<SpaceFiltersState> {
|
||||
class SpaceFiltersPresenter(
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val matrixClient: MatrixClient,
|
||||
) : Presenter<SpaceFiltersState> {
|
||||
@Composable
|
||||
override fun present(): SpaceFiltersState {
|
||||
return SpaceFiltersState(
|
||||
eventSink = {},
|
||||
)
|
||||
val isFeatureEnabled by featureFlagService
|
||||
.isFeatureEnabledFlow(FeatureFlags.RoomListSpaceFilters)
|
||||
.collectAsState(initial = false)
|
||||
|
||||
if (!isFeatureEnabled) {
|
||||
return SpaceFiltersState.Disabled
|
||||
}
|
||||
|
||||
val availableFilters by remember {
|
||||
matrixClient.spaceService.spaceFiltersFlow.map { it.toImmutableList() }
|
||||
}.collectAsState(initial = persistentListOf())
|
||||
|
||||
var selectionMode by remember { mutableStateOf<SelectionMode>(SelectionMode.Unselected) }
|
||||
|
||||
fun handleUnselectedEvent(event: SpaceFiltersEvent.Unselected) {
|
||||
when (event) {
|
||||
SpaceFiltersEvent.Unselected.ShowFilters -> {
|
||||
selectionMode = SelectionMode.Selecting
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun handleSelectingEvent(event: SpaceFiltersEvent.Selecting) {
|
||||
when (event) {
|
||||
SpaceFiltersEvent.Selecting.Cancel -> {
|
||||
selectionMode = SelectionMode.Unselected
|
||||
}
|
||||
is SpaceFiltersEvent.Selecting.SelectFilter -> {
|
||||
selectionMode = SelectionMode.Selected(event.spaceFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun handleSelectedEvent(event: SpaceFiltersEvent.Selected) {
|
||||
when (event) {
|
||||
SpaceFiltersEvent.Selected.ClearSelection -> {
|
||||
selectionMode = SelectionMode.Unselected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return when (val mode = selectionMode) {
|
||||
SelectionMode.Unselected -> SpaceFiltersState.Unselected(
|
||||
eventSink = ::handleUnselectedEvent,
|
||||
)
|
||||
SelectionMode.Selecting -> SpaceFiltersState.Selecting(
|
||||
availableFilters = availableFilters,
|
||||
eventSink = ::handleSelectingEvent,
|
||||
)
|
||||
is SelectionMode.Selected -> SpaceFiltersState.Selected(
|
||||
selectedFilter = mode.filter,
|
||||
eventSink = ::handleSelectedEvent,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed interface SelectionMode {
|
||||
data object Unselected : SelectionMode
|
||||
data object Selecting : SelectionMode
|
||||
data class Selected(val filter: SpaceServiceFilter) : SelectionMode
|
||||
}
|
||||
|
||||
@@ -7,6 +7,23 @@
|
||||
|
||||
package io.element.android.features.home.impl.spacefilters
|
||||
|
||||
data class SpaceFiltersState(
|
||||
val eventSink: (SpaceFiltersEvent) -> Unit,
|
||||
)
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
sealed interface SpaceFiltersState {
|
||||
data object Disabled : SpaceFiltersState
|
||||
|
||||
data class Unselected(
|
||||
val eventSink: (SpaceFiltersEvent.Unselected) -> Unit,
|
||||
) : SpaceFiltersState
|
||||
|
||||
data class Selecting(
|
||||
val availableFilters: ImmutableList<SpaceServiceFilter>,
|
||||
val eventSink: (SpaceFiltersEvent.Selecting) -> Unit,
|
||||
) : SpaceFiltersState
|
||||
|
||||
data class Selected(
|
||||
val selectedFilter: SpaceServiceFilter,
|
||||
val eventSink: (SpaceFiltersEvent.Selected) -> Unit,
|
||||
) : SpaceFiltersState
|
||||
}
|
||||
|
||||
@@ -8,14 +8,56 @@
|
||||
package io.element.android.features.home.impl.spacefilters
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||
import io.element.android.libraries.previewutils.room.aSpaceRoom
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
class SpaceFiltersStateProvider : PreviewParameterProvider<SpaceFiltersState> {
|
||||
override val values: Sequence<SpaceFiltersState>
|
||||
get() = sequenceOf(aSpaceFiltersState())
|
||||
get() = sequenceOf(
|
||||
aDisabledSpaceFiltersState(),
|
||||
anUnselectedSpaceFiltersState(),
|
||||
aSelectingSpaceFiltersState(),
|
||||
aSelectedSpaceFiltersState(),
|
||||
)
|
||||
}
|
||||
|
||||
fun aSpaceFiltersState(
|
||||
eventSink: (SpaceFiltersEvent) -> Unit = {},
|
||||
) = SpaceFiltersState(
|
||||
fun aDisabledSpaceFiltersState() = SpaceFiltersState.Disabled
|
||||
|
||||
fun anUnselectedSpaceFiltersState(
|
||||
eventSink: (SpaceFiltersEvent.Unselected) -> Unit = {},
|
||||
) = SpaceFiltersState.Unselected(
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aSelectingSpaceFiltersState(
|
||||
availableFilters: List<SpaceServiceFilter> = listOf(
|
||||
aSpaceServiceFilter(displayName = "Work"),
|
||||
aSpaceServiceFilter(displayName = "Personal", roomId = RoomId("!personal:example.com")),
|
||||
aSpaceServiceFilter(displayName = "Gaming", roomId = RoomId("!gaming:example.com")),
|
||||
),
|
||||
eventSink: (SpaceFiltersEvent.Selecting) -> Unit = {},
|
||||
) = SpaceFiltersState.Selecting(
|
||||
availableFilters = persistentListOf(*availableFilters.toTypedArray()),
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aSelectedSpaceFiltersState(
|
||||
selectedFilter: SpaceServiceFilter = aSpaceServiceFilter(displayName = "Work"),
|
||||
eventSink: (SpaceFiltersEvent.Selected) -> Unit = {},
|
||||
) = SpaceFiltersState.Selected(
|
||||
selectedFilter = selectedFilter,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
fun aSpaceServiceFilter(
|
||||
displayName: String = "Space",
|
||||
roomId: RoomId = RoomId("!space:example.com"),
|
||||
level: Int = 0,
|
||||
descendants: List<RoomId> = emptyList(),
|
||||
) = SpaceServiceFilter(
|
||||
spaceRoom = aSpaceRoom(displayName = displayName, roomId = roomId),
|
||||
level = level,
|
||||
descendants = descendants,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user