Merge pull request #3345 from gannonlawlor/android/autofill-support
Add autofill to login and signup page
This commit is contained in:
@ -0,0 +1,39 @@
|
||||
package app.omnivore.omnivore.ui.auth
|
||||
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.autofill.AutofillNode
|
||||
import androidx.compose.ui.autofill.AutofillType
|
||||
import androidx.compose.ui.composed
|
||||
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
|
||||
|
||||
|
||||
object AuthUtils {
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun Modifier.autofill(
|
||||
autofillTypes: List<AutofillType>,
|
||||
onFill: ((String) -> Unit),
|
||||
) = composed {
|
||||
val autofill = LocalAutofill.current
|
||||
val autofillNode = AutofillNode(onFill = onFill, autofillTypes = autofillTypes)
|
||||
LocalAutofillTree.current += autofillNode
|
||||
|
||||
this
|
||||
.onGloballyPositioned {
|
||||
autofillNode.boundingBox = it.boundsInWindow()
|
||||
}
|
||||
.onFocusChanged { focusState ->
|
||||
autofill?.run {
|
||||
if (focusState.isFocused) {
|
||||
requestAutofillForNode(autofillNode)
|
||||
} else {
|
||||
cancelAutofillForNode(autofillNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,9 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.autofill.AutofillType
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
@ -25,6 +27,7 @@ import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.BuildConfig
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.auth.AuthUtils.autofill
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
@ -86,6 +89,7 @@ fun EmailLoginView(viewModel: LoginViewModel) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun LoginFields(
|
||||
email: String,
|
||||
@ -105,6 +109,12 @@ fun LoginFields(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier.autofill(
|
||||
autofillTypes = listOf(
|
||||
AutofillType.EmailAddress,
|
||||
),
|
||||
onFill = { onEmailChange(it) }
|
||||
),
|
||||
value = email,
|
||||
placeholder = { Text(stringResource(R.string.email_login_field_placeholder_email)) },
|
||||
label = { Text(stringResource(R.string.email_login_field_label_email)) },
|
||||
@ -112,11 +122,17 @@ fun LoginFields(
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Done,
|
||||
keyboardType = KeyboardType.Email,
|
||||
),
|
||||
),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
modifier = Modifier.autofill(
|
||||
autofillTypes = listOf(
|
||||
AutofillType.Password,
|
||||
),
|
||||
onFill = { onPasswordChange(it) }
|
||||
),
|
||||
value = password,
|
||||
placeholder = { Text(stringResource(R.string.email_login_field_placeholder_password)) },
|
||||
label = { Text(stringResource(R.string.email_login_field_label_password)) },
|
||||
@ -129,21 +145,22 @@ fun LoginFields(
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
)
|
||||
|
||||
Button(onClick = {
|
||||
if (email.isNotBlank() && password.isNotBlank()) {
|
||||
onLoginClick()
|
||||
focusManager.clearFocus()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.email_login_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}, colors = ButtonDefaults.buttonColors(
|
||||
contentColor = Color(0xFF3D3D3D),
|
||||
containerColor = Color(0xffffd234)
|
||||
)
|
||||
Button(
|
||||
onClick = {
|
||||
if (email.isNotBlank() && password.isNotBlank()) {
|
||||
onLoginClick()
|
||||
focusManager.clearFocus()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.email_login_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}, colors = ButtonDefaults.buttonColors(
|
||||
contentColor = Color(0xFF3D3D3D),
|
||||
containerColor = Color(0xffffd234)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.email_login_action_login),
|
||||
|
||||
@ -14,7 +14,9 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.autofill.AutofillType
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
@ -27,6 +29,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.auth.AuthUtils.autofill
|
||||
|
||||
@Composable
|
||||
fun EmailSignUpView(viewModel: LoginViewModel) {
|
||||
@ -140,6 +143,7 @@ fun EmailSignUpForm(viewModel: LoginViewModel) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun EmailSignUpFields(
|
||||
email: String,
|
||||
@ -165,6 +169,12 @@ fun EmailSignUpFields(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier.autofill(
|
||||
autofillTypes = listOf(
|
||||
AutofillType.EmailAddress,
|
||||
),
|
||||
onFill = { onEmailChange(it) }
|
||||
),
|
||||
value = email,
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_email)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_email)) },
|
||||
@ -174,6 +184,12 @@ fun EmailSignUpFields(
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
modifier = Modifier.autofill(
|
||||
autofillTypes = listOf(
|
||||
AutofillType.Password,
|
||||
),
|
||||
onFill = { onPasswordChange(it) }
|
||||
),
|
||||
value = password,
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_password)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_password)) },
|
||||
|
||||
@ -54,8 +54,8 @@
|
||||
<string name="email_signup_field_label_password">Password</string>
|
||||
<string name="email_signup_field_placeholder_name">Name</string>
|
||||
<string name="email_signup_field_label_name">Name</string>
|
||||
<string name="email_signup_field_placeholder_username">Name</string>
|
||||
<string name="email_signup_field_label_username">Name</string>
|
||||
<string name="email_signup_field_placeholder_username">Username</string>
|
||||
<string name="email_signup_field_label_username">Username</string>
|
||||
<string name="email_signup_error_msg">Please complete all fields.</string>
|
||||
|
||||
<!-- Google Auth -->
|
||||
|
||||
Reference in New Issue
Block a user