Merge pull request #3083 from element-hq/feature/bma/filterAutoScroll

Improve room filtering behavior.
This commit is contained in:
Benoit Marty 2024-06-26 09:46:44 +02:00 committed by GitHub
commit e7f7493ad0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 0 deletions

1
changelog.d/3083.bugfix Normal file
View file

@ -0,0 +1 @@
Improve room filters behavior

View file

@ -22,6 +22,7 @@ import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
@ -34,8 +35,12 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -66,7 +71,31 @@ fun RoomListFiltersView(
state.eventSink(RoomListFiltersEvents.ToggleFilter(filter))
}
var scrollToStart by remember { mutableIntStateOf(0) }
val lazyListState = rememberLazyListState()
LaunchedEffect(scrollToStart) {
// Scroll until the first item start to be displayed
// Since all items have different size, there is no way to compute the amount of
// pixel to scroll to go directly to the start of the row.
// But IRL it should only happen for one item.
while (lazyListState.firstVisibleItemIndex > 0) {
lazyListState.animateScrollBy(
value = -(lazyListState.firstVisibleItemScrollOffset + 1f),
animationSpec = spring(
stiffness = Spring.StiffnessMediumLow,
)
)
}
// Then scroll to the start of the list, a bit faster, to fully reveal the first
// item, which can be the close button to reset filter, or the first item
// if the user has scroll a bit before clicking on the close button.
lazyListState.animateScrollBy(
value = -lazyListState.firstVisibleItemScrollOffset.toFloat(),
animationSpec = spring(
stiffness = Spring.StiffnessMedium,
)
)
}
val previousFilters = remember { mutableStateOf(listOf<RoomListFilter>()) }
LazyRow(
contentPadding = PaddingValues(start = 8.dp, end = 16.dp),
@ -84,6 +113,9 @@ fun RoomListFiltersView(
onClick = {
previousFilters.value = state.selectedFilters()
onClearFiltersClick()
// When clearing filter, we want to ensure that the list
// of filters is scrolled to the start.
scrollToStart++
}
)
}
@ -100,6 +132,10 @@ fun RoomListFiltersView(
onClick = {
previousFilters.value = state.selectedFilters()
onToggleFilter(it)
// When selecting a filter, we want to scroll to the start of the list
if (filterWithSelection.isSelected.not()) {
scrollToStart++
}
},
)
}