Migrate to the new semantics-based Autofill APIs

This commit is contained in:
FooIbar committed 2025-02-12 17:42:53 +08:00
1 parent db064e788b
commit bf6085bdf9
2 files changed
+14 -47

No files matched your search

@@ -19,7 +19,6 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.TextObfuscationMode
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Info
@@ -43,11 +42,13 @@ 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.autofill.AutofillType
import androidx.compose.ui.autofill.ContentType
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentType
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.ImeAction
@@ -65,8 +66,9 @@ import com.hippo.ehviewer.ui.Screen
import com.hippo.ehviewer.ui.destinations.WebViewSignInScreenDestination
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.LocalWindowSizeClass
import com.hippo.ehviewer.ui.tools.autofill
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.displayString
import com.jamal.composeprefs3.ui.ifTrueThen
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
@@ -136,25 +138,23 @@ fun AnimatedVisibilityScope.SignInScreen(navigator: DestinationsNavigator) = Scr
fun UsernameAndPasswordTextField() {
OutlinedTextField(
state = username,
modifier = Modifier.width(dimensionResource(id = R.dimen.single_max_width)).autofill(
autofillTypes = listOf(AutofillType.Username),
onFill = { username.setTextAndPlaceCursorAtEnd(it) },
),
modifier = Modifier.width(dimensionResource(id = R.dimen.single_max_width))
.semantics { contentType = ContentType.Username }
.thenIf(!showUsernameError) { padding(bottom = 16.dp) },
label = { Text(stringResource(R.string.username)) },
supportingText = { if (showUsernameError) Text(stringResource(R.string.error_username_cannot_empty)) },
trailingIcon = { if (showUsernameError) Icon(imageVector = Icons.Filled.Info, contentDescription = null) },
supportingText = showUsernameError.ifTrueThen { Text(stringResource(R.string.error_username_cannot_empty)) },
trailingIcon = showUsernameError.ifTrueThen { Icon(imageVector = Icons.Filled.Info, contentDescription = null) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
lineLimits = TextFieldLineLimits.SingleLine,
isError = showUsernameError,
)
OutlinedSecureTextField(
state = password,
modifier = Modifier.width(dimensionResource(id = R.dimen.single_max_width)).autofill(
autofillTypes = listOf(AutofillType.Password),
onFill = { password.setTextAndPlaceCursorAtEnd(it) },
),
modifier = Modifier.width(dimensionResource(id = R.dimen.single_max_width))
.semantics { contentType = ContentType.Password }
.thenIf(!showPasswordError) { padding(bottom = 16.dp) },
label = { Text(stringResource(R.string.password)) },
supportingText = { if (showPasswordError) Text(stringResource(R.string.error_password_cannot_empty)) },
supportingText = showPasswordError.ifTrueThen { Text(stringResource(R.string.error_password_cannot_empty)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
onKeyboardAction = { signIn() },
trailingIcon = {
@@ -1,33 +0,0 @@
package com.hippo.ehviewer.ui.tools
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.autofill.AutofillNode
import androidx.compose.ui.autofill.AutofillType
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalAutofill
import androidx.compose.ui.platform.LocalAutofillTree
@Composable
fun Modifier.autofill(
autofillTypes: List<AutofillType>,
onFill: ((String) -> Unit),
): Modifier {
val autofill = LocalAutofill.current
val autofillNode = AutofillNode(onFill = onFill, autofillTypes = autofillTypes)
LocalAutofillTree.current += autofillNode
return onGloballyPositioned {
autofillNode.boundingBox = it.boundsInWindow()
}.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNode)
} else {
cancelAutofillForNode(autofillNode)
}
}
}
}