Keep the cursor position in room list search when going back (#5570)

Also, make sure disposing a `MessagesView` doesn't accidentally hide the keyboard once the transition animation is done
This commit is contained in:
Jorge Martin Espinosa
2025-10-21 11:25:46 +02:00
committed by GitHub
parent cd375cafba
commit cbeb58f00e
2 changed files with 13 additions and 10 deletions

View File

@@ -24,6 +24,7 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -33,6 +34,8 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.compound.tokens.generated.CompoundIcons
@@ -41,7 +44,6 @@ import io.element.android.features.home.impl.contentType
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.roomlist.RoomListEvents
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.form.textFieldState
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.FilledTextField
@@ -111,18 +113,18 @@ private fun RoomListSearchContent(
},
navigationIcon = { BackButton(onClick = ::onBackButtonClick) },
title = {
var filter by textFieldState(state.query)
var value by remember { mutableStateOf(TextFieldValue(state.query)) }
val focusRequester = remember { FocusRequester() }
FilledTextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester),
value = filter,
value = value,
singleLine = true,
onValueChange = {
filter = it
state.eventSink(RoomListSearchEvents.QueryChanged(it))
value = it
state.eventSink(RoomListSearchEvents.QueryChanged(it.text))
},
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
@@ -134,7 +136,7 @@ private fun RoomListSearchContent(
errorIndicatorColor = Color.Transparent,
),
trailingIcon = {
if (filter.isNotEmpty()) {
if (value.text.isNotEmpty()) {
IconButton(onClick = {
state.eventSink(RoomListSearchEvents.ClearQuery)
}) {
@@ -148,7 +150,11 @@ private fun RoomListSearchContent(
)
LaunchedEffect(Unit) {
focusRequester.requestFocus()
value = value.copy(selection = TextRange(value.text.length))
if (!focusRequester.restoreFocusedChild()) {
focusRequester.requestFocus()
}
focusRequester.saveFocusedChild()
}
},
windowInsets = TopAppBarDefaults.windowInsets.copy(top = 0)

View File

@@ -84,7 +84,6 @@ import io.element.android.libraries.designsystem.text.toAnnotatedString
import io.element.android.libraries.designsystem.theme.components.BottomSheetDragHandle
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.HideKeyboardWhenDisposed
import io.element.android.libraries.designsystem.utils.KeepScreenOn
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
@@ -124,8 +123,6 @@ fun MessagesView(
KeepScreenOn(state.voiceMessageComposerState.keepScreenOn)
HideKeyboardWhenDisposed()
val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
// This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose