Compare commits
4 Commits
0a46dd931f
...
f87375b8dd
Author | SHA1 | Date |
---|---|---|
dankito | f87375b8dd | |
dankito | 43f15fa662 | |
dankito | 1c7fa49de5 | |
dankito | f547b76c7b |
|
@ -31,7 +31,7 @@ interface BankingRepository {
|
|||
|
||||
suspend fun updateBank(bank: BankAccessEntity, loginName: String, password: String, bankName: String?)
|
||||
|
||||
suspend fun updateBank(bank: BankAccessEntity, clientData: String?)
|
||||
suspend fun updateBank(bank: BankAccessEntity, serializedClientData: String?)
|
||||
|
||||
suspend fun updateAccount(account: BankAccountEntity, userSetDisplayName: String?, hideAccount: Boolean, includeInAutomaticAccountsUpdate: Boolean)
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class InMemoryBankingRepository(
|
|||
// no-op
|
||||
}
|
||||
|
||||
override suspend fun updateBank(bank: BankAccessEntity, clientData: String?) {
|
||||
override suspend fun updateBank(bank: BankAccessEntity, serializedClientData: String?) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
|
|
@ -95,9 +95,9 @@ open class SqliteBankingRepository : BankingRepository {
|
|||
val tanMedia = getAllTanMedia().groupBy { it.bankId }.mapValues { it.value.toMutableList() }
|
||||
val holdings = getAllHoldings().groupBy { it.accountId }
|
||||
|
||||
return bankQueries.getAllBanks { id, domesticBankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodIdentifier, selectedTanMediumIdentifier, bankingGroup, serverAddress, countryCode, clientData, userSetDisplayName, displayIndex, iconUrl, wrongCredentialsEntered ->
|
||||
return bankQueries.getAllBanks { id, domesticBankCode, loginName, password, bankName, bic, customerName, userId, selectedTanMethodIdentifier, selectedTanMediumIdentifier, bankingGroup, serverAddress, countryCode, serializedClientData, userSetDisplayName, displayIndex, iconUrl, wrongCredentialsEntered ->
|
||||
BankAccessEntity(id, domesticBankCode, loginName, password, bankName, bic, customerName, userId, getAccountsOfBank(id, bankAccounts, holdings), selectedTanMethodIdentifier, tanMethods[id] ?: mutableListOf(), selectedTanMediumIdentifier, tanMedia[id] ?: mutableListOf(),
|
||||
bankingGroup?.let { BankingGroup.valueOf(it) }, serverAddress, countryCode, userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered, clientData)
|
||||
bankingGroup?.let { BankingGroup.valueOf(it) }, serverAddress, countryCode, userSetDisplayName, displayIndex.toInt(), iconUrl, wrongCredentialsEntered, null, serializedClientData)
|
||||
}.executeAsList()
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ open class SqliteBankingRepository : BankingRepository {
|
|||
return bankQueries.transactionWithResult {
|
||||
bankQueries.insertBank(bank.domesticBankCode, bank.loginName, bank.password, bank.bankName, bank.bic,
|
||||
bank.customerName, bank.userId, bank.selectedTanMethodIdentifier, bank.selectedTanMediumIdentifier,
|
||||
bank.bankingGroup?.name, bank.serverAddress, bank.countryCode, bank.clientData, bank.userSetDisplayName, bank.displayIndex.toLong(), bank.iconUrl, bank.wrongCredentialsEntered
|
||||
bank.bankingGroup?.name, bank.serverAddress, bank.countryCode, bank.serializedClientData, bank.userSetDisplayName, bank.displayIndex.toLong(), bank.iconUrl, bank.wrongCredentialsEntered
|
||||
)
|
||||
|
||||
val bankId = getLastInsertedId() // getLastInsertedId() / last_insert_rowid() has to be called in a transaction with the insert operation, otherwise it will not work
|
||||
|
@ -141,10 +141,10 @@ open class SqliteBankingRepository : BankingRepository {
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun updateBank(bank: BankAccessEntity, clientData: String?) {
|
||||
override suspend fun updateBank(bank: BankAccessEntity, serializedClientData: String?) {
|
||||
bankQueries.transaction {
|
||||
if (clientData != null) {
|
||||
bankQueries.updateBankClientData(clientData, bank.id)
|
||||
if (serializedClientData != null) {
|
||||
bankQueries.updateBankClientData(serializedClientData, bank.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ class BankAccessEntity(
|
|||
iconUrl: String? = null,
|
||||
wrongCredentialsEntered: Boolean = false,
|
||||
|
||||
clientData: String? = null
|
||||
clientData: Any? = null,
|
||||
serializedClientData: String? = null
|
||||
) : BankAccess(domesticBankCode, loginName, password, bankName, bic, customerName, userId, accounts, selectedTanMethodIdentifier, tanMethods, selectedTanMediumIdentifier, tanMedia, bankingGroup, serverAddress, countryCode) {
|
||||
|
||||
init {
|
||||
|
@ -45,6 +46,7 @@ class BankAccessEntity(
|
|||
this.wrongCredentialsEntered = wrongCredentialsEntered
|
||||
|
||||
this.clientData = clientData
|
||||
this.serializedClientData = serializedClientData
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import net.codinux.banking.ui.composables.settings.UiSettings
|
|||
import net.codinux.banking.ui.composables.text.ItemDivider
|
||||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.verticalScroll
|
||||
import net.codinux.banking.ui.extensions.rememberVerticalScroll
|
||||
import org.jetbrains.compose.resources.imageResource
|
||||
|
||||
private val uiState = DI.uiState
|
||||
|
@ -60,7 +60,7 @@ fun SideMenuContent() {
|
|||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Column(Modifier.fillMaxSize().background(Colors.DrawerContentBackground).verticalScroll()) {
|
||||
Column(Modifier.fillMaxSize().background(Colors.DrawerContentBackground).rememberVerticalScroll()) {
|
||||
Column(Modifier.fillMaxWidth().height(HeaderHeight.dp).background(HeaderBackground).padding(16.dp)) {
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package net.codinux.banking.ui.extensions
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
@ -14,8 +12,14 @@ import net.codinux.log.Log
|
|||
|
||||
fun Modifier.verticalScroll() = this.verticalScroll(ScrollState(0), enabled = true)
|
||||
|
||||
@Composable
|
||||
fun Modifier.rememberVerticalScroll() = this.verticalScroll(rememberScrollState())
|
||||
|
||||
fun Modifier.horizontalScroll() = this.horizontalScroll(ScrollState(0), enabled = true)
|
||||
|
||||
@Composable
|
||||
fun Modifier.rememberHorizontalScroll() = this.horizontalScroll(rememberScrollState())
|
||||
|
||||
|
||||
@Composable
|
||||
// we need to support three different cases:
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package net.codinux.banking.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -12,7 +10,7 @@ import kotlinx.coroutines.launch
|
|||
import net.codinux.banking.client.model.isNegative
|
||||
import net.codinux.banking.persistence.entities.AccountTransactionEntity
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.verticalScroll
|
||||
import net.codinux.banking.ui.extensions.rememberVerticalScroll
|
||||
import net.codinux.banking.ui.forms.LabelledValue
|
||||
import net.codinux.banking.ui.forms.OutlinedTextField
|
||||
import net.codinux.banking.ui.forms.SectionHeader
|
||||
|
@ -72,7 +70,7 @@ fun AccountTransactionDetailsScreen(transaction: AccountTransactionEntity, onClo
|
|||
onClosed = onClosed
|
||||
) {
|
||||
SelectionContainer {
|
||||
Column(Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
||||
Column(Modifier.fillMaxSize().rememberVerticalScroll()) {
|
||||
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
SectionHeader(if (isExpense) "Empfänger*in" else "Zahlende*r", false)
|
||||
|
|
|
@ -2,9 +2,7 @@ package net.codinux.banking.ui.screens
|
|||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
|
@ -21,6 +19,7 @@ import net.codinux.banking.ui.composables.tan.ImageSizeControls
|
|||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.ImeNext
|
||||
import net.codinux.banking.ui.extensions.rememberVerticalScroll
|
||||
import net.codinux.banking.ui.forms.CaptionText
|
||||
import net.codinux.banking.ui.forms.OutlinedTextField
|
||||
import net.codinux.banking.ui.forms.Select
|
||||
|
@ -88,7 +87,7 @@ fun CreateEpcQrCodeScreen(onClosed: () -> Unit) {
|
|||
|
||||
|
||||
FullscreenViewBase("EPC QR Code erstellen", "Schließen", onClosed = onClosed) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
Column(Modifier.fillMaxWidth().rememberVerticalScroll()) {
|
||||
if (epcQrCodeGeneratingError != null) {
|
||||
Text("QR Code konnte nicht erstellt werden:${NewLine}$epcQrCodeGeneratingError", color = MaterialTheme.colors.error, modifier = Modifier.padding(vertical = 8.dp))
|
||||
} else if (epcQrCodeBytes == null) {
|
||||
|
|
|
@ -5,26 +5,46 @@ import androidx.compose.foundation.text.selection.SelectionContainer
|
|||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import net.codinux.banking.ui.IOorDefault
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import net.codinux.banking.client.model.BankAccount
|
||||
import net.codinux.banking.persistence.entities.BankAccountEntity
|
||||
import net.codinux.banking.ui.composables.BankIcon
|
||||
import net.codinux.banking.ui.config.Colors
|
||||
import net.codinux.banking.ui.config.DI
|
||||
import net.codinux.banking.ui.extensions.horizontalScroll
|
||||
import net.codinux.banking.ui.extensions.verticalScroll
|
||||
import net.codinux.banking.ui.forms.SectionHeader
|
||||
import net.codinux.banking.ui.forms.Select
|
||||
import net.codinux.banking.ui.model.Config.NewLine
|
||||
|
||||
|
||||
@Composable
|
||||
fun FeedbackScreen(onClosed: () -> Unit) {
|
||||
|
||||
val banks = DI.uiState.banks.collectAsState().value
|
||||
|
||||
val messageLog by remember { mutableStateOf(DI.bankingService.getMessageLog()) }
|
||||
|
||||
val displayedLogEntries by remember { derivedStateOf { messageLog.sortedBy { it.messageNumber } } }
|
||||
val accountsWithMessageLog: List<BankAccount?> by remember(messageLog) { derivedStateOf {
|
||||
listOf<BankAccount?>(null) + messageLog.mapNotNull { it.account }.toSet().toList()
|
||||
} }
|
||||
|
||||
var selectedAccount by remember { mutableStateOf<BankAccount?>(null) }
|
||||
|
||||
val bankOfSelectedAccount by remember(selectedAccount) {
|
||||
// TODO: MessageLogEntries of added accounts contain a BankAccount instead of a BankAccountEntity object
|
||||
derivedStateOf { banks.firstOrNull { it.id == (selectedAccount as? BankAccountEntity)?.bankId } }
|
||||
}
|
||||
|
||||
val displayedLogEntries by remember(messageLog, selectedAccount) { derivedStateOf {
|
||||
messageLog.filter { selectedAccount == null || it.account == selectedAccount }.sortedBy { it.messageNumber }
|
||||
} }
|
||||
|
||||
val displayedLogEntriesText by remember(displayedLogEntries) {
|
||||
derivedStateOf { displayedLogEntries.map {
|
||||
|
@ -34,27 +54,50 @@ fun FeedbackScreen(onClosed: () -> Unit) {
|
|||
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
coroutineScope.launch(Dispatchers.IOorDefault) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
FullscreenViewBase("Feedback", onClosed = onClosed) {
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
|
||||
Text("Man kann uns direkt aus der App heraus noch kein Feedback schicken (kommt noch), aber schon mal das Nachrichten-Protokoll, das ihr bei Fehlern an die (unfähgigen) Entwickler schicken könnt:", modifier = Modifier.padding(horizontal = 24.dp).padding(top = 8.dp), textAlign = TextAlign.Center)
|
||||
|
||||
SectionHeader("Nachrichten-Protokoll:") // TODO: add a Switch "Add message protocol"
|
||||
|
||||
if (messageLog.isEmpty()) {
|
||||
Row(Modifier.fillMaxSize().padding(24.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) {
|
||||
Text("Sie haben noch keine Aktion wie das Abrufen der Kontoumsätze ausgeführt, deshalb gibt es noch kein Nachrichtenprotokoll zu diesen Aktionen", textAlign = TextAlign.Center)
|
||||
}
|
||||
} else {
|
||||
Row(Modifier.fillMaxWidth().padding(top = 6.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Select(
|
||||
"Konto",
|
||||
accountsWithMessageLog,
|
||||
selectedAccount,
|
||||
{ account -> selectedAccount = account },
|
||||
{ account -> account?.displayName ?: "Alle Konten" },
|
||||
Modifier.weight(0.9f),
|
||||
leadingIcon = bankOfSelectedAccount?.let { { BankIcon(bankOfSelectedAccount) } },
|
||||
dropDownItemContent = { account ->
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
BankIcon(banks.firstOrNull { it.id == (account as? BankAccountEntity)?.bankId }, Modifier.padding(end = 6.dp))
|
||||
|
||||
Text(account?.displayName ?: "")
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
Spacer(Modifier.weight(0.1f))
|
||||
|
||||
TextButton({ clipboardManager.setText(AnnotatedString(displayedLogEntriesText))}) {
|
||||
Text("Kopieren", color = Colors.CodinuxSecondaryColor)
|
||||
}
|
||||
}
|
||||
|
||||
Column(Modifier.verticalScroll().horizontalScroll()) {
|
||||
Column(Modifier.verticalScroll().horizontalScroll().padding(top = 8.dp)) {
|
||||
SelectionContainer(modifier = Modifier.fillMaxSize()) {
|
||||
Text(displayedLogEntriesText, fontFamily = FontFamily.Monospace)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -291,7 +291,7 @@ class BankingService(
|
|||
bankingRepository.updateAccount(account, response.balance ?: account.balance, response.transactionsRetrievalTime, response.retrievedTransactionsFrom ?: account.retrievedTransactionsFrom)
|
||||
}
|
||||
|
||||
bankingRepository.updateBank(bank, bank.clientData)
|
||||
bankingRepository.updateBank(bank, bank.serializedClientData)
|
||||
|
||||
notifyBanksListUpdated() // notify about updated values like account balance
|
||||
} catch (e: Throwable) {
|
||||
|
|
Loading…
Reference in New Issue