From 2a82b9e6ca633206635e7b34bcabf5d4cd07e780 Mon Sep 17 00:00:00 2001 From: Oleg Koretsky Date: Mon, 6 Mar 2023 18:09:41 +0200 Subject: [PATCH] Fix word wrapping in terms checkbox on the login screen --- .../ui/screen/loggedOff/LoginScreen.kt | 72 +++++++++---------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt index 10c7563ca..b4f948321 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt @@ -1,39 +1,18 @@ package com.vitorpamplona.amethyst.ui.screen import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -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.layout.size +import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Button -import androidx.compose.material.ButtonDefaults -import androidx.compose.material.Checkbox -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.LocalTextStyle -import androidx.compose.material.MaterialTheme -import androidx.compose.material.OutlinedTextField -import androidx.compose.material.Text +import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Visibility import androidx.compose.material.icons.outlined.VisibilityOff -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -50,18 +29,14 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.text.* +import androidx.compose.ui.text.input.* import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R +import java.util.* @OptIn(ExperimentalComposeUiApi::class) @Composable @@ -143,7 +118,8 @@ fun LoginPage(accountViewModel: AccountStateViewModel) { Icon( imageVector = if (showPassword) Icons.Outlined.VisibilityOff else Icons.Outlined.Visibility, contentDescription = if (showPassword) stringResource(R.string.show_password) else stringResource( - R.string.hide_password) + R.string.hide_password + ) ) } }, @@ -174,13 +150,29 @@ fun LoginPage(accountViewModel: AccountStateViewModel) { onCheckedChange = { acceptedTerms.value = it } ) - Text(text = stringResource(R.string.i_accept_the)) + val clickableTextStyle = + SpanStyle(color = MaterialTheme.colors.primary.copy(alpha = 0.52f)) + + val annotatedTermsString = buildAnnotatedString { + append(stringResource(R.string.i_accept_the)) + + withStyle(clickableTextStyle) { + pushStringAnnotation("openTerms", "") + append(stringResource(R.string.terms_of_use)) + } + } ClickableText( - text = AnnotatedString(stringResource(R.string.terms_of_use)), - onClick = { runCatching { uri.openUri("https://github.com/vitorpamplona/amethyst/blob/main/PRIVACY.md") } }, - style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary), - ) + text = annotatedTermsString, + ) { spanOffset -> + annotatedTermsString.getStringAnnotations(spanOffset, spanOffset) + .firstOrNull() + ?.also { span -> + if (span.tag == "openTerms") { + runCatching { uri.openUri("https://github.com/vitorpamplona/amethyst/blob/main/PRIVACY.md") } + } + } + } } if (termsAcceptanceIsRequired.isNotBlank()) { @@ -197,7 +189,8 @@ fun LoginPage(accountViewModel: AccountStateViewModel) { Button( onClick = { if (!acceptedTerms.value) { - termsAcceptanceIsRequired = context.getString(R.string.acceptance_of_terms_is_required) + termsAcceptanceIsRequired = + context.getString(R.string.acceptance_of_terms_is_required) } if (key.value.text.isBlank()) { @@ -236,7 +229,8 @@ fun LoginPage(accountViewModel: AccountStateViewModel) { if (acceptedTerms.value) { accountViewModel.newKey() } else { - termsAcceptanceIsRequired = context.getString(R.string.acceptance_of_terms_is_required) + termsAcceptanceIsRequired = + context.getString(R.string.acceptance_of_terms_is_required) } }, style = TextStyle(