Improve room filtering behavior.
This commit is contained in:
parent
0cf5a41c61
commit
f3a5d65808
1 changed files with 37 additions and 0 deletions
|
|
@ -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
|
||||||
|
|
@ -51,6 +56,7 @@ import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
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
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -66,7 +72,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 +114,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 +133,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