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

View file

@ -5,6 +5,20 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
class AuthScreenViewModel : ViewModel() { 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("") private val _displayName = MutableStateFlow("")
val displayName = _displayName.asStateFlow() val displayName = _displayName.asStateFlow()

View file

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

View file

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

View file

@ -1,6 +1,6 @@
#Fri Aug 16 10:33:36 EDT 2024 #Fri Aug 16 10:33:36 EDT 2024
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists