Implemented LoginScreen
This commit is contained in:
parent
6e6449e956
commit
4697119c58
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
|
@ -9,6 +9,8 @@ import androidx.compose.ui.unit.sp
|
|||
import kotlinx.coroutines.launch
|
||||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.model.settings.AppAuthenticationMethod
|
||||
import net.codinux.banking.ui.screens.LoginScreen
|
||||
import net.codinux.banking.ui.screens.MainScreen
|
||||
import net.codinux.log.LoggerFactory
|
||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||
|
@ -25,13 +27,23 @@ fun App() {
|
|||
val colors = MaterialTheme.colors.copy(primary = Colors.Primary, primaryVariant = Colors.PrimaryDark, onPrimary = Color.White,
|
||||
secondary = Colors.Accent, secondaryVariant = Colors.Accent, onSecondary = Color.White)
|
||||
|
||||
val appSettings = DI.uiState.appSettings.collectAsState().value
|
||||
|
||||
var isLoggedIn by remember(appSettings.authenticationMethod) { mutableStateOf(appSettings.authenticationMethod == AppAuthenticationMethod.None) }
|
||||
|
||||
var isInitialized by remember { mutableStateOf(false) }
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
|
||||
MaterialTheme(colors = colors, typography = typography) {
|
||||
MainScreen()
|
||||
if (isLoggedIn == false) {
|
||||
LoginScreen(appSettings) {
|
||||
isLoggedIn = true
|
||||
}
|
||||
} else {
|
||||
MainScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ object DI {
|
|||
|
||||
fun setRepository(repository: BankingRepository) {
|
||||
this.bankingRepository = repository
|
||||
|
||||
repository.getAppSettings()?.let { // otherwise it's the first app start, BankingService will take care of this case
|
||||
uiState.appSettings.value = it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,16 @@ import androidx.compose.ui.text.input.VisualTransformation
|
|||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable // try BasicSecureTextField
|
||||
fun PasswordTextField(password: String = "", label: String = "Passwort", modifier: Modifier = Modifier, keyboardOptions: KeyboardOptions? = null, forceHidePassword: Boolean? = null, onEnterPressed: (() -> Unit)? = null, onChange: (String) -> Unit) {
|
||||
fun PasswordTextField(
|
||||
password: String = "",
|
||||
label: String = "Passwort",
|
||||
modifier: Modifier = Modifier,
|
||||
keyboardOptions: KeyboardOptions? = null,
|
||||
isError: Boolean = false,
|
||||
forceHidePassword: Boolean? = null,
|
||||
onEnterPressed: (() -> Unit)? = null,
|
||||
onChange: (String) -> Unit
|
||||
) {
|
||||
|
||||
var passwordVisible by remember { mutableStateOf(false) }
|
||||
|
||||
|
@ -30,6 +39,7 @@ fun PasswordTextField(password: String = "", label: String = "Passwort", modifie
|
|||
onValueChange = { onChange(it) },
|
||||
label = { Text(label) },
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
isError = isError,
|
||||
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
trailingIcon = {
|
||||
val visibilityIcon = if (passwordVisible) {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package net.codinux.banking.ui.screens
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import bankmeister.composeapp.generated.resources.*
|
||||
import bankmeister.composeapp.generated.resources.Res
|
||||
import net.codinux.banking.ui.forms.PasswordTextField
|
||||
import net.codinux.banking.ui.model.settings.AppAuthenticationMethod
|
||||
import net.codinux.banking.ui.model.settings.AppSettings
|
||||
import net.codinux.banking.ui.service.PasswordService
|
||||
import org.jetbrains.compose.resources.imageResource
|
||||
|
||||
@Composable
|
||||
fun LoginScreen(appSettings: AppSettings, onLoginSuccess: () -> Unit) {
|
||||
|
||||
var password by remember { mutableStateOf("") }
|
||||
|
||||
var showError by remember { mutableStateOf(false) }
|
||||
|
||||
|
||||
fun checkPassword() {
|
||||
if (appSettings.hashedPassword != null && PasswordService.checkPassword(password, appSettings.hashedPassword!!)) {
|
||||
onLoginSuccess()
|
||||
} else {
|
||||
showError = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Image(imageResource(Res.drawable.AppIcon_round), "Bankmeister's app icon", Modifier.size(144.dp).padding(bottom = 32.dp))
|
||||
|
||||
if (appSettings.authenticationMethod == AppAuthenticationMethod.Password) {
|
||||
Text("Bitte geben Sie Ihr Passwort ein um die App zu entsperren", style = MaterialTheme.typography.h5, textAlign = TextAlign.Center)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
PasswordTextField(
|
||||
password = password,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
onEnterPressed = { checkPassword() },
|
||||
isError = showError
|
||||
) {
|
||||
password = it
|
||||
showError = false
|
||||
}
|
||||
|
||||
if (showError) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text("Passwort ist falsch", color = MaterialTheme.colors.error, fontSize = 18.sp)
|
||||
}
|
||||
|
||||
Button(modifier = Modifier.padding(top = 24.dp).width(300.dp).height(50.dp), onClick = { checkPassword() }) {
|
||||
Text("Login", color = Color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue