Model SpaceFilters ui states
This commit is contained in:
parent
908616e8e8
commit
e2e49ba384
4 changed files with 161 additions and 12 deletions
|
|
@ -7,4 +7,22 @@
|
||||||
|
|
||||||
package io.element.android.features.home.impl.spacefilters
|
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
|
package io.element.android.features.home.impl.spacefilters
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
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 dev.zacsweers.metro.Inject
|
||||||
import io.element.android.libraries.architecture.Presenter
|
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
|
@Inject
|
||||||
class SpaceFiltersPresenter : Presenter<SpaceFiltersState> {
|
class SpaceFiltersPresenter(
|
||||||
|
private val featureFlagService: FeatureFlagService,
|
||||||
|
private val matrixClient: MatrixClient,
|
||||||
|
) : Presenter<SpaceFiltersState> {
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): SpaceFiltersState {
|
override fun present(): SpaceFiltersState {
|
||||||
return SpaceFiltersState(
|
val isFeatureEnabled by featureFlagService
|
||||||
eventSink = {},
|
.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
|
package io.element.android.features.home.impl.spacefilters
|
||||||
|
|
||||||
data class SpaceFiltersState(
|
import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter
|
||||||
val eventSink: (SpaceFiltersEvent) -> Unit,
|
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
|
package io.element.android.features.home.impl.spacefilters
|
||||||
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
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> {
|
class SpaceFiltersStateProvider : PreviewParameterProvider<SpaceFiltersState> {
|
||||||
override val values: Sequence<SpaceFiltersState>
|
override val values: Sequence<SpaceFiltersState>
|
||||||
get() = sequenceOf(aSpaceFiltersState())
|
get() = sequenceOf(
|
||||||
|
aDisabledSpaceFiltersState(),
|
||||||
|
anUnselectedSpaceFiltersState(),
|
||||||
|
aSelectingSpaceFiltersState(),
|
||||||
|
aSelectedSpaceFiltersState(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun aSpaceFiltersState(
|
fun aDisabledSpaceFiltersState() = SpaceFiltersState.Disabled
|
||||||
eventSink: (SpaceFiltersEvent) -> Unit = {},
|
|
||||||
) = SpaceFiltersState(
|
fun anUnselectedSpaceFiltersState(
|
||||||
|
eventSink: (SpaceFiltersEvent.Unselected) -> Unit = {},
|
||||||
|
) = SpaceFiltersState.Unselected(
|
||||||
eventSink = eventSink,
|
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,
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue