Update login screen to prompt for regular credentials

This commit is contained in:
Z. Charles Dziura 2024-10-08 14:14:42 -04:00
parent f7972b4365
commit 6879012cf5
6 changed files with 66 additions and 51 deletions

View file

@ -75,6 +75,8 @@ dependencies {
implementation(libs.retrofit)
implementation(libs.retrofit.gson)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.okhttp)
// implementation(libs.okhttp.logging)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)

View file

@ -14,9 +14,9 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Key
import androidx.compose.material.icons.outlined.Mail
import androidx.compose.material.icons.outlined.Password
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.PersonAdd
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
@ -58,18 +58,18 @@ fun AuthScreen(
.weight(3f)
.padding(16.dp)
) {
val displayName = viewModel.displayName.collectAsState()
val emailAddress = viewModel.emailAddress.collectAsState()
RegistrationScreen(
displayName,
onDisplayNameUpdate = viewModel::updateDisplayName,
emailAddress,
onEmailAddressUpdate = viewModel::updateEmailAddress
val username = viewModel.username.collectAsState()
val password = viewModel.password.collectAsState()
LoginComponent(
username,
onUpdateUsername = viewModel::updateUsername,
password,
onUpdatePassword = viewModel::updatePassword
)
Separator(modifier = Modifier.padding(PaddingValues(top = 24.dp, bottom = 24.dp)))
PassKeyButton()
RegisterButton()
}
}
}
@ -114,19 +114,18 @@ private fun Separator(modifier: Modifier = Modifier) {
}
@Composable
private fun RegistrationScreen(
displayName: State<String>,
onDisplayNameUpdate: (String) -> Unit,
emailAddress: State<String>,
onEmailAddressUpdate: (String) -> Unit,
private fun LoginComponent(
username: State<String>,
onUpdateUsername: (String) -> Unit,
password: State<String>,
onUpdatePassword: (String) -> Unit,
modifier: Modifier = Modifier
) {
Column(modifier.verticalScroll(rememberScrollState()))
{
Column(modifier.verticalScroll(rememberScrollState())) {
OutlinedTextField(
value = displayName.value,
label = { Text(stringResource(id = R.string.auth_screen__display_name)) },
placeholder = { Text(stringResource(id = R.string.auth_screen__display_name)) },
value = username.value,
label = { Text(stringResource(id = R.string.auth_screen__username)) },
placeholder = { Text(stringResource(id = R.string.auth_screen__username)) },
leadingIcon = { Icon(Icons.Outlined.Person, "person") },
singleLine = true,
keyboardOptions = KeyboardOptions(
@ -134,25 +133,22 @@ private fun RegistrationScreen(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
onValueChange = onDisplayNameUpdate,
onValueChange = onUpdateUsername,
modifier = Modifier.fillMaxWidth()
)
OutlinedTextField(
value = emailAddress.value,
label = { Text(stringResource(id = R.string.auth_screen__email)) },
placeholder = { Text(stringResource(id = R.string.auth_screen__email)) },
leadingIcon = { Icon(Icons.Outlined.Mail, "email") },
value = username.value,
label = { Text(stringResource(id = R.string.auth_screen__password)) },
placeholder = { Text(stringResource(id = R.string.auth_screen__password)) },
leadingIcon = { Icon(Icons.Outlined.Password, "password") },
singleLine = true,
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Unspecified,
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Go
),
onValueChange = onEmailAddressUpdate,
modifier = Modifier
.fillMaxWidth()
.padding(PaddingValues(top = 8.dp))
onValueChange = onUpdatePassword,
modifier = Modifier.fillMaxWidth()
)
Button(
@ -161,22 +157,22 @@ private fun RegistrationScreen(
.padding(PaddingValues(top = 16.dp))
.fillMaxWidth()
) {
Text(stringResource(id = R.string.auth_screen__register))
Text(stringResource(id = R.string.auth_screen__login))
}
}
}
@Composable
private fun PassKeyButton() {
private fun RegisterButton() {
OutlinedButton(
onClick = { /*TODO*/ },
modifier = Modifier
.fillMaxWidth()
) {
Box(modifier = Modifier.fillMaxWidth()) {
Icon(Icons.Outlined.Key, "passkey")
Icon(Icons.Outlined.PersonAdd, "register")
Text(
stringResource(id = R.string.auth_screen__sign_in),
stringResource(id = R.string.auth_screen__register),
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()

View file

@ -5,6 +5,20 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class AuthScreenViewModel : ViewModel() {
private val _username = MutableStateFlow("")
val username = _username.asStateFlow()
private val _password = MutableStateFlow("")
val password = _password.asStateFlow()
fun updateUsername(username: String) {
_username.value = username
}
fun updatePassword(password: String) {
_password.value = password
}
private val _displayName = MutableStateFlow("")
val displayName = _displayName.asStateFlow()

View file

@ -2,9 +2,9 @@
<string name="app_name">Debt Pirate</string>
<!-- Auth Screen -->
<string name="auth_screen__register">Register</string>
<string name="auth_screen__sign_in">Sign in with a Passkey</string>
<string name="auth_screen__email">Email Address</string>
<string name="auth_screen__display_name">Display Name</string>
<string name="auth_screen__username">Username</string>
<string name="auth_screen__password">Password</string>
<string name="auth_screen__login">Login</string>
<string name="auth_screen__register">Register a New Account</string>
</resources>

View file

@ -1,24 +1,25 @@
[versions]
activityCompose = "1.9.1"
agp = "8.6.0"
activityCompose = "1.9.2"
agp = "8.7.0"
appcompat = "1.7.0"
composeBom = "2024.08.00"
composeBom = "2024.09.03"
coreKtx = "1.13.1"
datastore = "1.1.1"
espressoCore = "3.6.1"
iconsExtended = "1.7.0-rc01"
iconsExtended = "1.7.3"
junit = "4.13.2"
junitVersion = "1.2.1"
kotlin = "2.0.10"
kotlinxSerializationJson = "1.7.1"
lifecycleRuntimeCompose = "2.8.4"
lifecycleRuntimeKtx = "2.8.4"
lifecycleViewModelKtx = "2.8.4"
lifecycleViewmodelCompose = "2.8.4"
lifecycleRuntimeCompose = "2.8.6"
lifecycleRuntimeKtx = "2.8.6"
lifecycleViewModelKtx = "2.8.6"
lifecycleViewmodelCompose = "2.8.6"
material = "1.12.0"
material3 = "1.3.0-rc01"
navigation = "2.8.0-rc01"
material3 = "1.3.0"
navigation = "2.8.2"
retrofit = "2.9.0"
okhttp = "4.10.0"
[libraries]
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
@ -47,6 +48,8 @@ material = { group = "com.google.android.material", name = "material", version.r
material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
okttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

View file

@ -1,6 +1,6 @@
#Fri Aug 16 10:33:36 EDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists