taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

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:
Mwallet/src/main/java/net/taler/wallet/contacts/AliasRegistrationScreen.kt | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mwallet/src/main/java/net/taler/wallet/contacts/ContactScreen.kt | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mwallet/src/main/res/values/strings.xml | 4++++
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>