Merge pull request #3083 from element-hq/feature/bma/filterAutoScroll
Improve room filtering behavior.
This commit is contained in:
commit
6c9066d695
2 changed files with 37 additions and 0 deletions
1
changelog.d/3083.bugfix
Normal file
1
changelog.d/3083.bugfix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Improve room filters behavior
|
||||||
|
|
@ -22,6 +22,7 @@ import androidx.compose.animation.core.spring
|
||||||
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.clickable
|
||||||
|
import androidx.compose.foundation.gestures.animateScrollBy
|
||||||
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.PaddingValues
|
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.FilterChip
|
||||||
import androidx.compose.material3.FilterChipDefaults
|
import androidx.compose.material3.FilterChipDefaults
|
||||||
import androidx.compose.runtime.Composable
|
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.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -66,7 +71,31 @@ fun RoomListFiltersView(
|
||||||
state.eventSink(RoomListFiltersEvents.ToggleFilter(filter))
|
state.eventSink(RoomListFiltersEvents.ToggleFilter(filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scrollToStart by remember { mutableIntStateOf(0) }
|
||||||
val lazyListState = rememberLazyListState()
|
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>()) }
|
val previousFilters = remember { mutableStateOf(listOf<RoomListFilter>()) }
|
||||||
LazyRow(
|
LazyRow(
|
||||||
contentPadding = PaddingValues(start = 8.dp, end = 16.dp),
|
contentPadding = PaddingValues(start = 8.dp, end = 16.dp),
|
||||||
|
|
@ -84,6 +113,9 @@ fun RoomListFiltersView(
|
||||||
onClick = {
|
onClick = {
|
||||||
previousFilters.value = state.selectedFilters()
|
previousFilters.value = state.selectedFilters()
|
||||||
onClearFiltersClick()
|
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 = {
|
onClick = {
|
||||||
previousFilters.value = state.selectedFilters()
|
previousFilters.value = state.selectedFilters()
|
||||||
onToggleFilter(it)
|
onToggleFilter(it)
|
||||||
|
// When selecting a filter, we want to scroll to the start of the list
|
||||||
|
if (filterWithSelection.isSelected.not()) {
|
||||||
|
scrollToStart++
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue