From 29970d68999d7aa93cff92a8bdfde1a399785bad Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 20 Nov 2023 15:28:32 +0100 Subject: [PATCH] Create separate `PasswordField` --- .../twom/ui/login/LoginActivityControl.kt | 24 +++- .../eu/steffo/twom/ui/login/PasswordField.kt | 108 ++++++++++++++++++ app/src/main/res/values/strings.xml | 10 +- 3 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/eu/steffo/twom/ui/login/PasswordField.kt diff --git a/app/src/main/java/eu/steffo/twom/ui/login/LoginActivityControl.kt b/app/src/main/java/eu/steffo/twom/ui/login/LoginActivityControl.kt index e75dd50..644a856 100644 --- a/app/src/main/java/eu/steffo/twom/ui/login/LoginActivityControl.kt +++ b/app/src/main/java/eu/steffo/twom/ui/login/LoginActivityControl.kt @@ -7,6 +7,10 @@ import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.Preview @@ -21,6 +25,10 @@ fun LoginActivityControl( onSelectHomeserver: () -> Unit = {}, onComplete: () -> Unit = {}, ) { + + var username by rememberSaveable { mutableStateOf("") } + var password by rememberSaveable { mutableStateOf("") } + Column(modifier) { Row(BASE_PADDING) { Text(LocalContext.current.getString(R.string.login_text)) @@ -37,8 +45,11 @@ fun LoginActivityControl( Row(BASE_PADDING) { TextField( modifier = Modifier.fillMaxWidth(), - value = "", - onValueChange = {}, + value = username, + onValueChange = { username = it }, + label = { + Text(LocalContext.current.getString(R.string.login_username_label)) + }, placeholder = { Text(LocalContext.current.getString(R.string.login_username_placeholder)) }, @@ -48,10 +59,13 @@ fun LoginActivityControl( ) } Row(BASE_PADDING) { - TextField( + PasswordField( modifier = Modifier.fillMaxWidth(), - value = "", - onValueChange = {}, + value = password, + onValueChange = { password = it }, + label = { + Text(LocalContext.current.getString(R.string.login_password_label)) + }, placeholder = { Text(LocalContext.current.getString(R.string.login_password_placeholder)) }, diff --git a/app/src/main/java/eu/steffo/twom/ui/login/PasswordField.kt b/app/src/main/java/eu/steffo/twom/ui/login/PasswordField.kt new file mode 100644 index 0000000..3997a8c --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/login/PasswordField.kt @@ -0,0 +1,108 @@ +package eu.steffo.twom.ui.login + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldColors +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import eu.steffo.twom.R + +@Composable +@Preview +fun PasswordField( + modifier: Modifier = Modifier, + value: String = "", + onValueChange: (String) -> Unit = {}, + enabled: Boolean = true, + readOnly: Boolean = false, + textStyle: TextStyle = LocalTextStyle.current, + label: @Composable (() -> Unit)? = null, + placeholder: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, + prefix: @Composable (() -> Unit)? = null, + suffix: @Composable (() -> Unit)? = null, + supportingText: @Composable (() -> Unit)? = null, + isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + shape: Shape = TextFieldDefaults.shape, + colors: TextFieldColors = TextFieldDefaults.colors() +) { + var showPassword by rememberSaveable { mutableStateOf(false) } + + TextField( + modifier = modifier, + value = value, + onValueChange = onValueChange, + enabled = enabled, + readOnly = readOnly, + textStyle = textStyle, + label = label, + placeholder = placeholder, + leadingIcon = leadingIcon, + prefix = prefix, + suffix = suffix, + supportingText = supportingText, + isError = isError, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + singleLine = singleLine, + maxLines = maxLines, + minLines = minLines, + interactionSource = interactionSource, + shape = shape, + colors = colors, + + visualTransformation = if(showPassword) VisualTransformation.None else PasswordVisualTransformation(), + + trailingIcon = { + IconButton( + onClick = { + showPassword = !showPassword + } + ) { + Icon( + // TODO: Replace with better icons when possible + if(showPassword) { + Icons.Filled.Favorite + } + else { + Icons.Filled.FavoriteBorder + }, + if(showPassword) { + LocalContext.current.getString(R.string.password_hide) + } + else { + LocalContext.current.getString(R.string.password_show) + } + ) + } + } + ) +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3ab092..f046f15 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,11 +20,15 @@ Select homeserver Log into Matrix Go back - To use TwoM, you need to log into a Matrix homeserver. - Continue + To use TwoM, you need to log into a Matrix homeserver. Currently, TwoM supports only username and password authentication. + Log in Select homeserver \@steffo:candy.steffo.eu The Matrix ID to login as, including the @ symbol and the homeserver name. - •••••••• + p4ssw0rd! The password of the Matrix account. + Username + Password + Show password + Hide password \ No newline at end of file