Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
Fix signup screen
Browse files Browse the repository at this point in the history
  • Loading branch information
M3DZIK committed Jul 15, 2024
1 parent 96decb2 commit 24f2306
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,20 @@ package dev.medzik.librepass.android.ui.auth

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.input.InputTransformation.Companion.keyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Password
import androidx.compose.material.icons.filled.QuestionMark
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand All @@ -40,16 +34,19 @@ import dev.medzik.android.compose.ui.textfield.AnimatedTextField
import dev.medzik.android.compose.ui.textfield.PasswordAnimatedTextField
import dev.medzik.android.compose.ui.textfield.TextFieldValue
import dev.medzik.librepass.android.ui.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable

@Serializable
object Signup

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignupScreen(navController: NavController) {
fun SignupScreen(
navController: NavController,
viewModel: SignupViewModel = hiltViewModel()
) {
val context = LocalContext.current

Scaffold(
topBar = {
TopAppBar(
Expand All @@ -62,98 +59,87 @@ fun SignupScreen(navController: NavController) {
)
}
) { innerPadding ->
SignupScreenContent(navController, innerPadding)
}
}

@Composable
fun SignupScreenContent(
navController: NavController,
innerPadding: PaddingValues,
viewModel: SignupViewModel = hiltViewModel()
) {
val context = LocalContext.current

LazyColumn(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween
) {
item {
Column(
modifier = Modifier.regularHorizontalPadding(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
EmailTextField(
value = TextFieldValue.fromMutableState(
state = viewModel.email
LazyColumn(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween
) {
item {
Column(
modifier = Modifier.regularHorizontalPadding(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
EmailTextField(
value = TextFieldValue.fromMutableState(
state = viewModel.email
)
)
)

PasswordAnimatedTextField(
label = stringResource(R.string.Password),
value = TextFieldValue.fromMutableState(
state = viewModel.password,
valueLabel = TextFieldValue.ValueLabel(
type = TextFieldValue.ValueLabel.Type.WARNING,
text = context.getString(R.string.PasswordLabel_WontBeRecover)
PasswordAnimatedTextField(
label = stringResource(R.string.Password),
value = TextFieldValue.fromMutableState(
state = viewModel.password,
valueLabel = TextFieldValue.ValueLabel(
type = TextFieldValue.ValueLabel.Type.WARNING,
text = context.getString(R.string.PasswordLabel_WontBeRecover)
)
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
)
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
)
)

PasswordAnimatedTextField(
label = stringResource(R.string.RetypePassword),
value = TextFieldValue.fromMutableState(
state = viewModel.retypePassword,
error = if (!viewModel.retypePasswordIsValid) {
"Passwords mismatch"
} else null
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
PasswordAnimatedTextField(
label = stringResource(R.string.RetypePassword),
value = TextFieldValue.fromMutableState(
state = viewModel.retypePassword,
error = if (viewModel.password.value.isNotEmpty() && viewModel.retypePasswordError) {
"Passwords mismatch"
} else null
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
)
)
)

AnimatedTextField(
label = stringResource(R.string.PasswordHint),
value = TextFieldValue.fromMutableState(
state = viewModel.passwordHint,
valueLabel = TextFieldValue.ValueLabel(
type = TextFieldValue.ValueLabel.Type.INFO,
text = context.getString(R.string.PasswordHintLabel)
AnimatedTextField(
label = stringResource(R.string.PasswordHint),
value = TextFieldValue.fromMutableState(
state = viewModel.passwordHint,
valueLabel = TextFieldValue.ValueLabel(
type = TextFieldValue.ValueLabel.Type.INFO,
text = context.getString(R.string.PasswordHintLabel)
)
),
leading = { IconBox(Icons.Default.QuestionMark) },
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
)
),
leading = { IconBox(Icons.Default.QuestionMark) },
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email
)
)

ChoiceServer(viewModel.server)
ChoiceServer(viewModel.server)
}
}
}

item {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
LoadingButton(
modifier = Modifier
.padding(vertical = 12.dp)
.height(50.dp)
.fillMaxWidth(0.85f),
onClick = { viewModel.register(context, navController) },
enabled = viewModel.canLogin
item {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.Signup),
style = MaterialTheme.typography.titleMedium
)
LoadingButton(
modifier = Modifier
.padding(vertical = 12.dp)
.height(50.dp)
.fillMaxWidth(0.85f),
onClick = { viewModel.register(navController) },
enabled = viewModel.canSignup
) {
Text(
text = stringResource(R.string.Signup),
style = MaterialTheme.typography.titleMedium
)
}
}
}
}
Expand All @@ -164,6 +150,9 @@ fun SignupScreenContent(
@Composable
fun SignupPreview() {
MaterialTheme {
SignupScreen(rememberNavController())
SignupScreen(
navController = rememberNavController(),
viewModel = SignupViewModel(context = LocalContext.current)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,36 @@ import android.content.Context
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.navigation.NavController
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import dev.medzik.android.utils.showToast
import dev.medzik.librepass.android.common.haveNetworkConnection
import dev.medzik.librepass.android.ui.R
import dev.medzik.librepass.client.Server
import dev.medzik.librepass.client.api.AuthClient
import javax.inject.Inject

class SignupViewModel : ViewModel() {
@HiltViewModel
class SignupViewModel @Inject constructor(
@ApplicationContext private val context: Context
) : ViewModel() {
val email = mutableStateOf("")
val password = mutableStateOf("")
val retypePassword = mutableStateOf("")
val retypePasswordIsValid = password.value.isNotEmpty() &&
retypePassword.value == password.value
val passwordHint = mutableStateOf("")
val canLogin = email.value.isNotEmpty() &&
password.value.isNotEmpty() &&
retypePassword.value == password.value

val retypePasswordError: Boolean
get() = retypePassword.value != password.value
val canSignup: Boolean
get() = email.value.isNotEmpty() &&
password.value.isNotEmpty() &&
!retypePasswordError

val server = mutableStateOf(Server.PRODUCTION)

private val authClient = AuthClient(apiUrl = server.value)

fun register(context: Context, navController: NavController) {
fun register(navController: NavController) {
if (!context.haveNetworkConnection()) {
context.showToast(R.string.NoInternetConnection)
return
Expand All @@ -40,7 +48,7 @@ class SignupViewModel : ViewModel() {
// TODO: disable back
navController.navigate(Login)
} catch (e: Exception) {

// TODO
}
}
}

0 comments on commit 24f2306

Please sign in to comment.