RoomListFilters : improve look and feel

This commit is contained in:
ganfra 2024-03-11 20:25:01 +01:00
parent fbbde977f9
commit 8420866120

View file

@ -16,23 +16,20 @@
package io.element.android.features.roomlist.impl.filters package io.element.android.features.roomlist.impl.filters
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -43,12 +40,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.libraries.designsystem.modifiers.fadingEdge
import io.element.android.libraries.designsystem.modifiers.horizontalFadingEdgesBrush
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag import io.element.android.libraries.testtags.testTag
@ -68,49 +62,40 @@ fun RoomListFiltersView(
state.eventSink(RoomListFiltersEvents.ToggleFilter(filter)) state.eventSink(RoomListFiltersEvents.ToggleFilter(filter))
} }
val startPadding = if (state.hasAnyFilterSelected) 4.dp else 16.dp val lazyListState = rememberLazyListState()
Row( LazyRow(
modifier = modifier.padding(start = startPadding, end = 16.dp), contentPadding = PaddingValues(start = 8.dp, end = 16.dp),
modifier = modifier.fillMaxWidth(),
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
item("clear_filters") {
AnimatedVisibility(visible = state.hasAnyFilterSelected) { if (state.hasAnyFilterSelected) {
RoomListClearFiltersButton( RoomListClearFiltersButton(
modifier = Modifier.testTag(TestTags.homeScreenClearFilters), modifier = Modifier
onClick = ::onClearFiltersClicked .padding(start = 8.dp)
) .testTag(TestTags.homeScreenClearFilters),
onClick = ::onClearFiltersClicked
)
}
} }
for (filterWithSelection in state.filterSelectionStates) {
val lazyListState = rememberLazyListState() item(filterWithSelection.filter) {
val fadingEdgesBrush = horizontalFadingEdgesBrush(
showLeft = lazyListState.canScrollBackward,
showRight = lazyListState.canScrollForward
)
LazyRow(
modifier = Modifier
.fillMaxWidth()
.fadingEdge(fadingEdgesBrush),
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(
items = state.filterSelectionStates,
key = { it.filter.ordinal }
) { filterWithSelection ->
RoomListFilterView( RoomListFilterView(
modifier = Modifier.animateItemPlacement( modifier = Modifier.animateItemPlacement(),
animationSpec = tween(200),
),
roomListFilter = filterWithSelection.filter, roomListFilter = filterWithSelection.filter,
selected = filterWithSelection.isSelected, selected = filterWithSelection.isSelected,
onClick = ::onToggleFilter, onClick = ::onToggleFilter,
) )
} }
} }
LaunchedEffect(state.filterSelectionStates) { }
if (lazyListState.canScrollBackward) { LaunchedEffect(state.filterSelectionStates) {
lazyListState.animateScrollToItem(0) // Checking for canScrollBackward is necessary for the itemPlacementAnimation to work correctly.
} // We don't want the itemPlacementAnimation to be triggered when clearing the filters.
if (!state.hasAnyFilterSelected || lazyListState.canScrollBackward) {
lazyListState.animateScrollToItem(0)
} }
} }
} }
@ -120,22 +105,18 @@ private fun RoomListClearFiltersButton(
onClick: () -> Unit, onClick: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
IconButton( Box(
modifier = modifier, modifier = modifier
onClick = onClick, .clip(CircleShape)
.background(ElementTheme.colors.bgActionPrimaryRest)
.clickable(onClick = onClick)
) { ) {
Box( Icon(
modifier = Modifier modifier = Modifier.align(Alignment.Center),
.clip(CircleShape) imageVector = CompoundIcons.Close(),
.background(ElementTheme.colors.bgActionPrimaryRest) tint = ElementTheme.colors.iconOnSolidPrimary,
) { contentDescription = stringResource(id = io.element.android.libraries.ui.strings.R.string.action_clear),
Icon( )
modifier = Modifier.align(Alignment.Center),
imageVector = CompoundIcons.Close(),
tint = ElementTheme.colors.iconOnSolidPrimary,
contentDescription = stringResource(id = io.element.android.libraries.ui.strings.R.string.action_clear),
)
}
} }
} }
@ -149,9 +130,7 @@ private fun RoomListFilterView(
FilterChip( FilterChip(
selected = selected, selected = selected,
onClick = { onClick(roomListFilter) }, onClick = { onClick(roomListFilter) },
modifier = modifier modifier = modifier.height(36.dp),
.minimumInteractiveComponentSize()
.height(36.dp),
shape = CircleShape, shape = CircleShape,
colors = FilterChipDefaults.filterChipColors( colors = FilterChipDefaults.filterChipColors(
containerColor = ElementTheme.colors.bgCanvasDefault, containerColor = ElementTheme.colors.bgCanvasDefault,