Requires users to accept terms of use as per Google Play requirement.

This commit is contained in:
Vitor Pamplona
2023-01-27 11:53:21 -03:00
parent 7399afa648
commit 88a82b3fbc

View File

@@ -4,6 +4,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -15,8 +16,11 @@ import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Checkbox
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text import androidx.compose.material.Text
@@ -30,7 +34,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
@@ -43,16 +49,29 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.components.sendMail
@Composable @Composable
fun LoginPage(accountViewModel: AccountStateViewModel) { fun LoginPage(accountViewModel: AccountStateViewModel) {
val key = remember { mutableStateOf(TextFieldValue("")) }
var errorMessage by remember { mutableStateOf("") }
val acceptedTerms = remember { mutableStateOf(false) }
var termsAcceptanceIsRequired by remember { mutableStateOf("") }
val uri = LocalUriHandler.current
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
ClickableText( ClickableText(
text = AnnotatedString("Generate a new key"), text = AnnotatedString("Generate a new key"),
modifier = Modifier modifier = Modifier
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.padding(20.dp), .padding(20.dp),
onClick = { accountViewModel.newKey() }, onClick = {
if (acceptedTerms.value) {
accountViewModel.newKey()
} else {
termsAcceptanceIsRequired = "Acceptance of terms is required"
}
},
style = TextStyle( style = TextStyle(
fontSize = 14.sp, fontSize = 14.sp,
textDecoration = TextDecoration.Underline, textDecoration = TextDecoration.Underline,
@@ -66,19 +85,14 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
val key = remember { mutableStateOf(TextFieldValue("")) }
var errorMessage by remember { mutableStateOf("") }
Image( Image(
painterResource(id = R.drawable.amethyst), painterResource(id = R.drawable.amethyst),
contentDescription = "App Logo", contentDescription = "App Logo",
modifier = Modifier.size(300.dp), modifier = Modifier.size(250.dp),
contentScale = ContentScale.Inside contentScale = ContentScale.Inside
) )
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(40.dp))
//Text(text = "Insert your private or public key (view-only)")
var showPassword by remember { var showPassword by remember {
mutableStateOf(false) mutableStateOf(false)
@@ -119,7 +133,32 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
) )
if (errorMessage.isNotBlank()) { if (errorMessage.isNotBlank()) {
Text( Text(
text = "${errorMessage}", text = errorMessage,
color = MaterialTheme.colors.error,
style = MaterialTheme.typography.caption
)
}
Spacer(modifier = Modifier.height(20.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = acceptedTerms.value,
onCheckedChange = { acceptedTerms.value = it }
)
Text(text = "I accept the ")
ClickableText(
text = AnnotatedString("terms of use"),
onClick = { runCatching { uri.openUri("https://github.com/vitorpamplona/amethyst/blob/main/PRIVACY.md") } },
style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary),
)
}
if (termsAcceptanceIsRequired.isNotBlank()) {
Text(
text = termsAcceptanceIsRequired,
color = MaterialTheme.colors.error, color = MaterialTheme.colors.error,
style = MaterialTheme.typography.caption style = MaterialTheme.typography.caption
) )
@@ -130,16 +169,30 @@ fun LoginPage(accountViewModel: AccountStateViewModel) {
Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) { Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
Button( Button(
onClick = { onClick = {
if (!acceptedTerms.value) {
termsAcceptanceIsRequired = "Acceptance of terms is required"
}
if (key.value.text.isBlank()) {
errorMessage = "Key is required"
}
if (acceptedTerms.value && key.value.text.isNotBlank()) {
try { try {
accountViewModel.login(key.value.text) accountViewModel.login(key.value.text)
} catch (e: Exception) { } catch (e: Exception) {
errorMessage = "Invalid key" errorMessage = "Invalid key"
} }
}
}, },
shape = RoundedCornerShape(35.dp), shape = RoundedCornerShape(35.dp),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(50.dp) .height(50.dp),
colors = ButtonDefaults
.buttonColors(
backgroundColor = if (acceptedTerms.value) MaterialTheme.colors.primary else Color.Gray
)
) { ) {
Text(text = "Login") Text(text = "Login")
} }