From f29e4b5fcc64521a7f33b65292a0f5f6f7401dc7 Mon Sep 17 00:00:00 2001 From: dankito Date: Fri, 6 Sep 2024 16:58:27 +0200 Subject: [PATCH] Added autocomplete also for amount to e.g. do the same transfer again; had to fix AutocompleteTextField's value setting for this --- .../banking/ui/dialogs/AddAccountDialog.kt | 9 ++++-- .../banking/ui/dialogs/TransferMoneyDialog.kt | 28 +++++++++++++++---- .../banking/ui/forms/AutocompleteTextField.kt | 24 ++++++++-------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/AddAccountDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/AddAccountDialog.kt index 59e9e86..06cab19 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/AddAccountDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/AddAccountDialog.kt @@ -26,6 +26,7 @@ private val bankingService = DI.bankingService fun AddAccountDialog( onDismiss: () -> Unit, ) { + var enteredBankSearchQuery by remember { mutableStateOf("") } var selectedBank by remember { mutableStateOf(null) } var loginName by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } @@ -39,11 +40,11 @@ fun AddAccountDialog( val coroutineScope = rememberCoroutineScope() fun confirmCalled() { - selectedBank?.let { + selectedBank?.let { bank -> isAddingAccount = true coroutineScope.launch(Dispatchers.IOorDefault) { - val successful = DI.bankingService.addAccount(selectedBank!!, loginName, password) + val successful = DI.bankingService.addAccount(bank, loginName, password) withContext(Dispatchers.Main) { isAddingAccount = false @@ -71,8 +72,10 @@ fun AddAccountDialog( Column { AutocompleteTextField( - onSelectedItemChanged = { selectedBank = it }, label = "Bank (Suche mit Name, Bankleitzahl oder Ort)", + value = enteredBankSearchQuery, + onEnteredTextChanged = { enteredBankSearchQuery = it }, + onSelectedItemChanged = { selectedBank = it }, getItemTitle = { bank -> bank.name }, fetchSuggestions = { query -> bankingService.findBanks(query) } ) { bank -> diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/TransferMoneyDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/TransferMoneyDialog.kt index cb4b516..8f1b499 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/TransferMoneyDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/TransferMoneyDialog.kt @@ -181,13 +181,29 @@ fun TransferMoneyDialog( ) Row(Modifier.padding(vertical = verticalSpace).fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { - OutlinedTextField( - value = amount, - onValueChange = { amount = it }, - label = { Text("Betrag") }, + AutocompleteTextField( + "Betrag", + amount, + dropdownMaxHeight = 250.dp, + minTextLengthForSearch = 0, modifier = Modifier.weight(1f).focusRequester(amountFocus), - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal, imeAction = ImeAction.Next) - ) + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal, imeAction = ImeAction.Next), + getItemTitle = { suggestion -> suggestion.amount.amount }, + onEnteredTextChanged = { amount = it }, + onSelectedItemChanged = { + amount = it?.amount?.amount ?: "" + if (it != null) { + paymentReference = it.reference + } + }, + fetchSuggestions = { recipientFinder.findPaymentDataForIban(recipientAccountIdentifier) } + ) { paymentDataSuggestion -> + Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { + Text(formatUtil.formatAmount(paymentDataSuggestion.amount, paymentDataSuggestion.currency), Modifier.widthIn(min = 60.dp), textAlign = TextAlign.End) + + Text(paymentDataSuggestion.reference, Modifier.padding(start = 6.dp), maxLines = 1, overflow = TextOverflow.Ellipsis) + } + } Text(formatUtil.formatCurrency(senderAccount.currency), Modifier.padding(start = 4.dp)) } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextField.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextField.kt index 3e634a0..619d302 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextField.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/forms/AutocompleteTextField.kt @@ -2,6 +2,7 @@ package net.codinux.banking.ui.forms import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close @@ -19,18 +20,19 @@ import net.codinux.banking.ui.config.Colors @Composable fun AutocompleteTextField( label: String, - initialValue: String? = null, + value: String, + onEnteredTextChanged: (String) -> Unit, onSelectedItemChanged: (T?) -> Unit, - onEnteredTextChanged: ((String) -> Unit)? = null, minTextLengthForSearch: Int = 1, showDividersBetweenItems: Boolean = true, getItemTitle: ((T) -> String)? = null, dropdownMaxHeight: Dp = 400.dp, + modifier: Modifier = Modifier, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, leadingIcon: @Composable (() -> Unit)? = null, fetchSuggestions: suspend (query: String) -> Collection = { emptyList() }, suggestionContent: @Composable (T) -> Unit ) { - var searchQuery by remember { mutableStateOf(initialValue ?: "") } var expanded by remember { mutableStateOf(false) } var isLoading by remember { mutableStateOf(false) } var suggestions by remember { mutableStateOf>(emptyList()) } @@ -47,7 +49,7 @@ fun AutocompleteTextField( suggestionsFetchJob = coroutineScope.launch { isLoading = true - suggestions = fetchSuggestions(searchQuery) + suggestions = fetchSuggestions(value) isLoading = false if (expanded == false && suggestions.isNotEmpty()) { @@ -57,13 +59,12 @@ fun AutocompleteTextField( } - ExposedDropdownMenuBox(expanded, { isExpanded -> expanded = isExpanded }, Modifier.fillMaxWidth()) { + ExposedDropdownMenuBox(expanded, { isExpanded -> expanded = isExpanded }, modifier.fillMaxWidth()) { OutlinedTextField( - value = searchQuery, + value = value, onValueChange = { query -> - searchQuery = query onSelectedItemChanged(null) - onEnteredTextChanged?.invoke(query) + onEnteredTextChanged(query) if (query.length >= minTextLengthForSearch) { fetchSuggestionsAsync() @@ -79,6 +80,7 @@ fun AutocompleteTextField( }, label = { Text(label) }, maxLines = 1, + keyboardOptions = keyboardOptions, trailingIcon = { if (isLoading) { CircularProgressIndicator( @@ -90,7 +92,7 @@ fun AutocompleteTextField( imageVector = Icons.Default.Close, contentDescription = "Sucheingabe löschen", modifier = Modifier.clickable { - searchQuery = "" + onEnteredTextChanged("") suggestions = emptyList() expanded = false onSelectedItemChanged(null) @@ -114,9 +116,7 @@ fun AutocompleteTextField( Column( Modifier.fillMaxWidth().padding(8.dp).clickable { onSelectedItemChanged(item) - getItemTitle?.let { - searchQuery = it.invoke(item) - } + onEnteredTextChanged(getItemTitle?.invoke(item) ?: "") expanded = false } ) {