diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptScreen.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptScreen.kt
index 41687985..3dc2a401 100644
--- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptScreen.kt
+++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptScreen.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.unit.dp
import app.passwordstore.R
import app.passwordstore.data.passfile.PasswordEntry
import app.passwordstore.ui.APSAppBar
+import app.passwordstore.ui.compose.PasswordField
import app.passwordstore.ui.compose.theme.APSThemePreview
import app.passwordstore.util.time.UserClock
import app.passwordstore.util.totp.UriTotpFinder
@@ -56,13 +57,7 @@ fun PasswordEntryScreen(
style = MaterialTheme.typography.headlineSmall,
)
if (entry.password != null) {
- TextField(
- value = entry.password!!,
- onValueChange = {},
- readOnly = true,
- label = { Text("Password") },
- trailingIcon = { CopyButton { clipboard.setText(AnnotatedString(entry.password!!)) } },
- )
+ PasswordField(value = entry.password!!, label = "Password", initialVisibility = false)
}
if (entry.hasTotp()) {
val totp by entry.totp.collectAsState(runBlocking { entry.totp.first() })
@@ -97,7 +92,7 @@ private fun PasswordEntryPreview() {
APSThemePreview { PasswordEntryScreen("Test Entry", createTestEntry()) }
}
-fun createTestEntry() =
+private fun createTestEntry() =
PasswordEntry(
UserClock(),
UriTotpFinder(),
diff --git a/ui-compose/src/main/kotlin/app/passwordstore/ui/compose/PasswordField.kt b/ui-compose/src/main/kotlin/app/passwordstore/ui/compose/PasswordField.kt
new file mode 100644
index 00000000..81255979
--- /dev/null
+++ b/ui-compose/src/main/kotlin/app/passwordstore/ui/compose/PasswordField.kt
@@ -0,0 +1,61 @@
+package app.passwordstore.ui.compose
+
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+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.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.VisualTransformation
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+public fun PasswordField(
+ value: String,
+ label: String,
+ initialVisibility: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ var visible by remember { mutableStateOf(initialVisibility) }
+ TextField(
+ value = value,
+ onValueChange = {},
+ readOnly = true,
+ label = { Text(label) },
+ visualTransformation =
+ if (visible) VisualTransformation.None else PasswordVisualTransformation(),
+ trailingIcon = {
+ ToggleButton(
+ visible = visible,
+ contentDescription = "Toggle password visibility",
+ onButtonClick = { visible = !visible },
+ )
+ },
+ modifier = modifier,
+ )
+}
+
+@Composable
+private fun ToggleButton(
+ visible: Boolean,
+ contentDescription: String,
+ onButtonClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ IconButton(onClick = onButtonClick, modifier = modifier) {
+ val icon =
+ if (visible) painterResource(id = R.drawable.baseline_visibility_off_24)
+ else painterResource(id = R.drawable.baseline_visibility_24)
+ Icon(
+ painter = icon,
+ contentDescription = contentDescription,
+ )
+ }
+}
diff --git a/ui-compose/src/main/res/drawable/baseline_visibility_24.xml b/ui-compose/src/main/res/drawable/baseline_visibility_24.xml
new file mode 100644
index 00000000..e732f005
--- /dev/null
+++ b/ui-compose/src/main/res/drawable/baseline_visibility_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/ui-compose/src/main/res/drawable/baseline_visibility_off_24.xml b/ui-compose/src/main/res/drawable/baseline_visibility_off_24.xml
new file mode 100644
index 00000000..a5cad715
--- /dev/null
+++ b/ui-compose/src/main/res/drawable/baseline_visibility_off_24.xml
@@ -0,0 +1,10 @@
+
+
+