mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-04 20:01:55 +00:00
RoomSelectView: improve scroll behavior
Ref: https://www.figma.com/design/kEAcfun9iSpszeUDvdKZ6b/ER-351--Multi-account-in-EX?node-id=195-40292
This commit is contained in:
+29
-14
@@ -33,6 +33,8 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.material3.rememberTopAppBarState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.key
|
import androidx.compose.runtime.key
|
||||||
@@ -42,6 +44,7 @@ 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.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.semantics.stateDescription
|
import androidx.compose.ui.semantics.stateDescription
|
||||||
@@ -51,6 +54,7 @@ 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.components.TopAppBarScrollBehaviorLayout
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarRow
|
import io.element.android.libraries.designsystem.components.avatar.AvatarRow
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||||
@@ -133,6 +137,11 @@ fun RoomSelectView(
|
|||||||
|
|
||||||
// Use a new list state when the selected account changes, so that the list of rooms is scrolled to the top
|
// Use a new list state when the selected account changes, so that the list of rooms is scrolled to the top
|
||||||
val lazyListState = key(state.selectedAccount.userId) { rememberLazyListState() }
|
val lazyListState = key(state.selectedAccount.userId) { rememberLazyListState() }
|
||||||
|
// Hide the account switch section when the room list is scrolled up, and show it again as soon as it is scrolled down.
|
||||||
|
// Use a new state when the selected account changes, so that the section is fully displayed again.
|
||||||
|
val accountSwitchScrollBehavior = key(state.selectedAccount.userId) {
|
||||||
|
TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
|
||||||
|
}
|
||||||
OnVisibleRangeChangeEffect(lazyListState) { visibleRange ->
|
OnVisibleRangeChangeEffect(lazyListState) { visibleRange ->
|
||||||
state.eventSink(RoomSelectEvent.UpdateVisibleRange(visibleRange))
|
state.eventSink(RoomSelectEvent.UpdateVisibleRange(visibleRange))
|
||||||
}
|
}
|
||||||
@@ -166,6 +175,7 @@ fun RoomSelectView(
|
|||||||
Modifier
|
Modifier
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
.consumeWindowInsets(paddingValues)
|
.consumeWindowInsets(paddingValues)
|
||||||
|
.nestedScroll(accountSwitchScrollBehavior.nestedScrollConnection)
|
||||||
) {
|
) {
|
||||||
SearchBar(
|
SearchBar(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -213,13 +223,17 @@ fun RoomSelectView(
|
|||||||
|
|
||||||
if (!state.isSearchActive) {
|
if (!state.isSearchActive) {
|
||||||
if (state.showAccountSwitch) {
|
if (state.showAccountSwitch) {
|
||||||
AccountSwitchSection(
|
// Keep this space outside the collapsing section, so that the section does not touch the search bar when it is collapsing
|
||||||
selectedAccount = state.selectedAccount,
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
otherAccounts = state.otherAccounts,
|
TopAppBarScrollBehaviorLayout(scrollBehavior = accountSwitchScrollBehavior) {
|
||||||
isExpanded = state.isAccountListExpanded,
|
AccountSwitchSection(
|
||||||
onToggleExpand = { state.eventSink(RoomSelectEvent.ToggleAccountListExpanded) },
|
selectedAccount = state.selectedAccount,
|
||||||
onSelectAccount = { state.eventSink(RoomSelectEvent.SelectAccount(it)) },
|
otherAccounts = state.otherAccounts,
|
||||||
)
|
isExpanded = state.isAccountListExpanded,
|
||||||
|
onToggleExpand = { state.eventSink(RoomSelectEvent.ToggleAccountListExpanded) },
|
||||||
|
onSelectAccount = { state.eventSink(RoomSelectEvent.SelectAccount(it)) },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SelectedRoomsHelper(
|
SelectedRoomsHelper(
|
||||||
selectedRooms = state.selectedRooms,
|
selectedRooms = state.selectedRooms,
|
||||||
@@ -227,16 +241,18 @@ fun RoomSelectView(
|
|||||||
showVerticalSpace = !state.showAccountSwitch,
|
showVerticalSpace = !state.showAccountSwitch,
|
||||||
)
|
)
|
||||||
if (state.resultState is SearchBarResultState.Results) {
|
if (state.resultState is SearchBarResultState.Results) {
|
||||||
if (state.resultState.results.isNotEmpty()) {
|
|
||||||
ListSectionHeader(
|
|
||||||
title = stringResource(CommonStrings.common_header_rooms),
|
|
||||||
hasDivider = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
contentPadding = lazyColumnContentPadding,
|
contentPadding = lazyColumnContentPadding,
|
||||||
) {
|
) {
|
||||||
|
if (state.resultState.results.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
ListSectionHeader(
|
||||||
|
title = stringResource(CommonStrings.common_header_rooms),
|
||||||
|
hasDivider = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
items(state.resultState.results, key = { it.roomId.value }) { roomSummary ->
|
items(state.resultState.results, key = { it.roomId.value }) { roomSummary ->
|
||||||
RoomSummaryView(
|
RoomSummaryView(
|
||||||
roomSummary,
|
roomSummary,
|
||||||
@@ -267,7 +283,6 @@ private fun AccountSwitchSection(
|
|||||||
onSelectAccount: (SessionId) -> Unit,
|
onSelectAccount: (SessionId) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
MatrixUserHeader(
|
MatrixUserHeader(
|
||||||
matrixUser = selectedAccount,
|
matrixUser = selectedAccount,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user