From bec549cc444328c8b46594c67a84d25dcc1aca6f Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Sat, 7 Sep 2024 14:11:14 +0600 Subject: [PATCH] Use TextFieldState in BasicTextField where applicable (#1201) Co-authored-by: p --- .../settings/screen/SettingsSearchScreen.kt | 27 +++++++++---------- .../presentation/track/TrackerSearch.kt | 23 ++++++++-------- .../track/TrackerSearchPreviewProvider.kt | 11 +++----- .../ui/manga/track/TrackInfoDialog.kt | 9 +++---- .../core/components/WheelPicker.kt | 13 ++++----- 5 files changed, 38 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt index a173effc0..1d7293b55 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt @@ -13,8 +13,10 @@ import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.clearText +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material3.HorizontalDivider @@ -28,11 +30,8 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.NonRestartableComposable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -43,7 +42,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp @@ -88,7 +86,7 @@ class SettingsSearchScreen : Screen() { focusRequester.requestFocus() } - var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) } + val textFieldState = rememberTextFieldState() Scaffold( topBar = { Column { @@ -103,20 +101,19 @@ class SettingsSearchScreen : Screen() { }, title = { BasicTextField( - value = textFieldValue, - onValueChange = { textFieldValue = it }, + state = textFieldState, modifier = Modifier .fillMaxWidth() .focusRequester(focusRequester) .runOnEnterKeyPressed(action = focusManager::clearFocus), textStyle = MaterialTheme.typography.bodyLarge .copy(color = MaterialTheme.colorScheme.onSurface), - singleLine = true, + lineLimits = TextFieldLineLimits.SingleLine, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onSearch = { focusManager.clearFocus() }), + onKeyboardAction = { focusManager.clearFocus() }, cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - decorationBox = { - if (textFieldValue.text.isEmpty()) { + decorator = { + if (textFieldState.text.isEmpty()) { Text( text = stringResource(MR.strings.action_search_settings), color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -128,8 +125,8 @@ class SettingsSearchScreen : Screen() { ) }, actions = { - if (textFieldValue.text.isNotEmpty()) { - IconButton(onClick = { textFieldValue = TextFieldValue() }) { + if (textFieldState.text.isNotEmpty()) { + IconButton(onClick = { textFieldState.clearText() }) { Icon( imageVector = Icons.Outlined.Close, contentDescription = null, @@ -144,7 +141,7 @@ class SettingsSearchScreen : Screen() { }, ) { contentPadding -> SearchResult( - searchKey = textFieldValue.text, + searchKey = textFieldState.text.toString(), listState = listState, contentPadding = contentPadding, ) { result -> diff --git a/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt b/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt index 175141208..512d7e268 100644 --- a/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt +++ b/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt @@ -25,8 +25,10 @@ import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.TextFieldState +import androidx.compose.foundation.text.input.clearText import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.CheckCircle @@ -59,7 +61,6 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.toLowerCase @@ -84,8 +85,7 @@ import tachiyomi.presentation.core.util.secondaryItemAlpha @Composable fun TrackerSearch( - query: TextFieldValue, - onQueryChange: (TextFieldValue) -> Unit, + state: TextFieldState, onDispatchQuery: () -> Unit, queryResult: Result>?, selected: TrackSearch?, @@ -115,20 +115,19 @@ fun TrackerSearch( }, title = { BasicTextField( - value = query, - onValueChange = onQueryChange, + state = state, modifier = Modifier .fillMaxWidth() .focusRequester(focusRequester) .runOnEnterKeyPressed(action = dispatchQueryAndClearFocus), textStyle = MaterialTheme.typography.bodyLarge .copy(color = MaterialTheme.colorScheme.onSurface), - singleLine = true, + lineLimits = TextFieldLineLimits.SingleLine, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onSearch = { dispatchQueryAndClearFocus() }), + onKeyboardAction = { dispatchQueryAndClearFocus() }, cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - decorationBox = { - if (query.text.isEmpty()) { + decorator = { + if (state.text.isEmpty()) { Text( text = stringResource(MR.strings.action_search_hint), color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -140,10 +139,10 @@ fun TrackerSearch( ) }, actions = { - if (query.text.isNotEmpty()) { + if (state.text.isNotEmpty()) { IconButton( onClick = { - onQueryChange(TextFieldValue()) + state.clearText() focusRequester.requestFocus() }, ) { diff --git a/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt b/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt index 808f41f7d..d79762a2a 100644 --- a/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt +++ b/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt @@ -1,7 +1,7 @@ package eu.kanade.presentation.track +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.datasource.LoremIpsum import eu.kanade.tachiyomi.data.track.model.TrackSearch @@ -13,8 +13,7 @@ internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composab private val fullPageWithSecondSelected = @Composable { val items = someTrackSearches().take(30).toList() TrackerSearch( - query = TextFieldValue(text = "search text"), - onQueryChange = {}, + state = TextFieldState(initialText = "search text"), onDispatchQuery = {}, queryResult = Result.success(items), selected = items[1], @@ -25,8 +24,7 @@ internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composab } private val fullPageWithoutSelected = @Composable { TrackerSearch( - query = TextFieldValue(text = ""), - onQueryChange = {}, + state = TextFieldState(), onDispatchQuery = {}, queryResult = Result.success(someTrackSearches().take(30).toList()), selected = null, @@ -37,8 +35,7 @@ internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composab } private val loading = @Composable { TrackerSearch( - query = TextFieldValue(), - onQueryChange = {}, + state = TextFieldState(), onDispatchQuery = {}, queryResult = null, selected = null, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt index e8c919c9d..4dd6310f3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material3.ButtonDefaults @@ -28,7 +29,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.StateScreenModel @@ -666,11 +666,10 @@ data class TrackerSearchScreen( val state by screenModel.state.collectAsState() - var textFieldValue by remember { mutableStateOf(TextFieldValue(initialQuery)) } + val textFieldState = rememberTextFieldState(initialQuery) TrackerSearch( - query = textFieldValue, - onQueryChange = { textFieldValue = it }, - onDispatchQuery = { screenModel.trackingSearch(textFieldValue.text) }, + state = textFieldState, + onDispatchQuery = { screenModel.trackingSearch(textFieldState.text.toString()) }, queryResult = state.queryResult, selected = state.selected, onSelectedChange = screenModel::updateSelection, diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/WheelPicker.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/WheelPicker.kt index bb0287881..c4cf6e471 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/WheelPicker.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/WheelPicker.kt @@ -16,6 +16,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldLineLimits +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -25,6 +27,7 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment @@ -37,7 +40,6 @@ import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp @@ -141,9 +143,9 @@ private fun WheelPicker( var showManualInput by remember { mutableStateOf(false) } if (showManualInput) { - var value by remember { + val value = rememberSaveable(saver = TextFieldState.Saver) { val currentString = items[internalIndex].toString() - mutableStateOf(TextFieldValue(text = currentString, selection = TextRange(currentString.length))) + TextFieldState(initialText = currentString, initialSelection = TextRange(currentString.length)) } val scope = rememberCoroutineScope() @@ -164,9 +166,8 @@ private fun WheelPicker( showManualInput = false } }, - value = value, - onValueChange = { value = it }, - singleLine = true, + state = value, + lineLimits = TextFieldLineLimits.SingleLine, keyboardOptions = KeyboardOptions( keyboardType = manualInputType!!, imeAction = ImeAction.Done,