commit d190428bb911352f71185b45a07336a68671d9e0
parent 5b7794fabca29617602ba90e44a44ea4fd386b8d
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Fri, 4 Sep 2026 15:50:29 +0200
use drop downs for alias types
Diffstat:
3 files changed, 112 insertions(+), 15 deletions(-)
diff --git a/wallet/src/main/java/net/taler/wallet/contacts/AliasRegistrationScreen.kt b/wallet/src/main/java/net/taler/wallet/contacts/AliasRegistrationScreen.kt
@@ -26,7 +26,10 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
+import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExposedDropdownMenuBox
+import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -55,7 +58,8 @@ fun AliasRegistrationScreen(
model: MainViewModel,
onNavigateBack: () -> Unit,
) {
- var aliasType by remember { mutableStateOf("") }
+ var aliasType by remember { mutableStateOf("email") }
+ var aliasTypeExpanded by remember { mutableStateOf(false) }
var alias by remember { mutableStateOf("") }
var durationMonths by remember { mutableStateOf("12") }
var solution by remember { mutableStateOf("") }
@@ -64,6 +68,11 @@ fun AliasRegistrationScreen(
val mailboxState by model.mailboxManager.mailbox.collectAsState()
val registerResult by model.contactManager.registerResult.collectAsState()
+ val aliasTypeOptions = listOf(
+ stringResource(R.string.alias_registration_alias_email),
+ stringResource(R.string.alias_registration_alias_phone),
+ )
+
DisposableEffect(Unit) {
onDispose {
model.contactManager.resetRegistration()
@@ -97,19 +106,55 @@ fun AliasRegistrationScreen(
}
if (registerResult is RegisterResult.Idle || registerResult is RegisterResult.Loading || registerResult is RegisterResult.Error) {
- OutlinedTextField(
- value = aliasType,
- onValueChange = { aliasType = it },
- label = { Text(stringResource(R.string.alias_registration_alias_type)) },
+ ExposedDropdownMenuBox(
+ expanded = aliasTypeExpanded,
+ onExpandedChange = { aliasTypeExpanded = !aliasTypeExpanded },
modifier = Modifier
.fillMaxWidth()
- .padding(bottom = 8.dp),
- enabled = registerResult !is RegisterResult.Loading
- )
+ .padding(bottom = 8.dp)
+ ) {
+ OutlinedTextField(
+ value = aliasType,
+ onValueChange = {},
+ readOnly = true,
+ label = { Text(stringResource(R.string.alias_registration_alias_type)) },
+ trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = aliasTypeExpanded) },
+ colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
+ modifier = Modifier
+ .menuAnchor()
+ .fillMaxWidth(),
+ enabled = registerResult !is RegisterResult.Loading
+ )
+ ExposedDropdownMenu(
+ expanded = aliasTypeExpanded,
+ onDismissRequest = { aliasTypeExpanded = false }
+ ) {
+ aliasTypeOptions.forEach { selectionOption ->
+ DropdownMenuItem(
+ text = { Text(selectionOption) },
+ onClick = {
+ aliasType = selectionOption
+ aliasTypeExpanded = false
+ },
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
+ }
+ }
+
OutlinedTextField(
value = alias,
onValueChange = { alias = it },
label = { Text(stringResource(R.string.alias_registration_alias)) },
+ placeholder = {
+ Text(
+ if (aliasType == stringResource(R.string.alias_registration_alias_email)) {
+ stringResource(R.string.alias_registration_alias_hint_email)
+ } else if (aliasType == stringResource(R.string.alias_registration_alias_phone)) {
+ stringResource(R.string.alias_registration_alias_hint_phone)
+ } else ""
+ )
+ },
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp),
diff --git a/wallet/src/main/java/net/taler/wallet/contacts/ContactScreen.kt b/wallet/src/main/java/net/taler/wallet/contacts/ContactScreen.kt
@@ -34,7 +34,10 @@ import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExposedDropdownMenuBox
+import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@@ -245,6 +248,7 @@ fun ContactScreen(
}
}
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddContactDialog(
initialAlias: String = "",
@@ -261,12 +265,18 @@ fun AddContactDialog(
) {
var alias by remember { mutableStateOf(initialAlias) }
var aliasType by remember { mutableStateOf(initialAliasType) }
+ var aliasTypeExpanded by remember { mutableStateOf(false) }
var mailbox by remember {
mutableStateOf(if (initialMailboxBaseUri.isEmpty()) "" else "$initialMailboxBaseUri$initialMailboxAddress")
}
var source by remember { mutableStateOf(initialSource) }
var petname by remember { mutableStateOf(initialPetname) }
+ val aliasTypeOptions = listOf(
+ stringResource(R.string.alias_registration_alias_email),
+ stringResource(R.string.alias_registration_alias_phone),
+ )
+
val isDuplicate = existingContacts.any { it.alias == alias && it.aliasType == aliasType }
LaunchedEffect(initialAlias) { alias = initialAlias }
@@ -292,16 +302,54 @@ fun AddContactDialog(
value = alias,
onValueChange = { alias = it },
label = { Text("Alias") },
+ placeholder = {
+ Text(
+ if (aliasType == stringResource(R.string.alias_registration_alias_email)) {
+ stringResource(R.string.alias_registration_alias_hint_email)
+ } else if (aliasType == stringResource(R.string.alias_registration_alias_phone)) {
+ stringResource(R.string.alias_registration_alias_hint_phone)
+ } else ""
+ )
+ },
isError = isDuplicate,
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
)
- OutlinedTextField(
- value = aliasType,
- onValueChange = { aliasType = it },
- label = { Text("Alias Type") },
- isError = isDuplicate,
- modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
- )
+
+ ExposedDropdownMenuBox(
+ expanded = aliasTypeExpanded,
+ onExpandedChange = { aliasTypeExpanded = !aliasTypeExpanded },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 8.dp)
+ ) {
+ OutlinedTextField(
+ value = aliasType,
+ onValueChange = {},
+ readOnly = true,
+ label = { Text("Alias Type") },
+ trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = aliasTypeExpanded) },
+ colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
+ modifier = Modifier
+ .menuAnchor()
+ .fillMaxWidth(),
+ isError = isDuplicate,
+ )
+ ExposedDropdownMenu(
+ expanded = aliasTypeExpanded,
+ onDismissRequest = { aliasTypeExpanded = false }
+ ) {
+ aliasTypeOptions.forEach { selectionOption ->
+ DropdownMenuItem(
+ text = { Text(selectionOption) },
+ onClick = {
+ aliasType = selectionOption
+ aliasTypeExpanded = false
+ },
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
+ }
+ }
if (isDuplicate) {
Text(
diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml
@@ -103,6 +103,10 @@ GNU Taler is immune to many types of fraud such as credit card data theft, phish
<string name="alias_registration_title">Alias Registration</string>
<string name="alias_registration_alias_type">Alias Type</string>
<string name="alias_registration_alias">Alias</string>
+ <string name="alias_registration_alias_email">email</string>
+ <string name="alias_registration_alias_phone">phone</string>
+ <string name="alias_registration_alias_hint_email">user@example.com</string>
+ <string name="alias_registration_alias_hint_phone">+1234567890</string>
<string name="alias_registration_duration">Duration (months)</string>
<string name="alias_registration_button">Register Alias</string>
<string name="alias_registration_exists">Registration already exists.</string>