diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/BankingRepository.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/BankingRepository.kt index 99af25d..4e4ddc3 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/BankingRepository.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/BankingRepository.kt @@ -9,6 +9,7 @@ import net.codinux.banking.dataaccess.entities.HoldingEntity import net.codinux.banking.dataaccess.entities.BankAccessEntity import net.codinux.banking.ui.model.AccountTransactionViewModel import net.codinux.banking.ui.model.settings.AppSettings +import net.codinux.banking.ui.settings.UiSettings interface BankingRepository { @@ -16,6 +17,10 @@ interface BankingRepository { suspend fun saveAppSettings(settings: AppSettings) + fun getUiSettings(settings: UiSettings) + + suspend fun saveUiSettings(settings: UiSettings) + fun getAllBanks(): List diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/InMemoryBankingRepository.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/InMemoryBankingRepository.kt index e174e8d..955f4a3 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/InMemoryBankingRepository.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/InMemoryBankingRepository.kt @@ -9,6 +9,7 @@ import net.codinux.banking.dataaccess.entities.HoldingEntity import net.codinux.banking.dataaccess.entities.BankAccessEntity import net.codinux.banking.ui.model.AccountTransactionViewModel import net.codinux.banking.ui.model.settings.AppSettings +import net.codinux.banking.ui.settings.UiSettings class InMemoryBankingRepository( banks: Collection = emptyList(), @@ -22,6 +23,8 @@ class InMemoryBankingRepository( private val transactions = transactions.map { map(it) }.toMutableList() + private lateinit var uiSettings: UiSettings + override fun getAppSettings(): AppSettings? = appSettings @@ -29,6 +32,14 @@ class InMemoryBankingRepository( this.appSettings = settings } + override fun getUiSettings(settings: UiSettings) { + this.uiSettings = settings + } + + override suspend fun saveUiSettings(settings: UiSettings) { + this.uiSettings = settings + } + override fun getAllBanks(): List = banks.toList() diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt index 3a86cd9..5758f89 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/dataaccess/SqliteBankingRepository.kt @@ -8,8 +8,10 @@ import net.codinux.banking.client.model.securitiesaccount.Holding import net.codinux.banking.client.model.tan.* import net.codinux.banking.dataaccess.entities.* import net.codinux.banking.ui.model.AccountTransactionViewModel +import net.codinux.banking.ui.model.TransactionsGrouping import net.codinux.banking.ui.model.settings.AppAuthenticationMethod import net.codinux.banking.ui.model.settings.AppSettings +import net.codinux.banking.ui.settings.UiSettings import net.codinux.log.logger import kotlin.enums.EnumEntries import kotlin.js.JsName @@ -40,6 +42,21 @@ open class SqliteBankingRepository( } + override fun getUiSettings(settings: UiSettings) { + settingsQueries.getUiSettings { _, transactionsGrouping, showBalance, showBankIcons, showColoredAmounts, showTransactionsInAlternatingColors -> + settings.transactionsGrouping.value = mapToEnum(transactionsGrouping, TransactionsGrouping.entries) + settings.showBalance.value = showBalance + settings.showBankIcons.value = showBankIcons + settings.showColoredAmounts.value = showColoredAmounts + settings.showTransactionsInAlternatingColors.value = showTransactionsInAlternatingColors + }.executeAsOneOrNull() + } + + override suspend fun saveUiSettings(settings: UiSettings) { + settingsQueries.upsertUiSettings(mapEnum(settings.transactionsGrouping.value), settings.showBalance.value, settings.showBankIcons.value, settings.showColoredAmounts.value, settings.showTransactionsInAlternatingColors.value) + } + + override fun getAllBanks(): List { val bankAccounts = getAllBankAccounts().groupBy { it.bankId } val tanMethods = getAllTanMethods().groupBy { it.bankId }.mapValues { it.value.toMutableList() } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/settings/UiSettings.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/settings/UiSettings.kt index 1cb53a9..61bead8 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/settings/UiSettings.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/settings/UiSettings.kt @@ -23,7 +23,7 @@ fun UiSettings(modifier: Modifier, textColor: Color = Color.Unspecified) { val transactionsGrouping by uiSettings.transactionsGrouping.collectAsState() - val zebraStripes by uiSettings.zebraStripes.collectAsState() + val showTransactionsInAlternatingColors by uiSettings.showTransactionsInAlternatingColors.collectAsState() val showBankIcons by uiSettings.showBankIcons.collectAsState() @@ -33,7 +33,7 @@ fun UiSettings(modifier: Modifier, textColor: Color = Color.Unspecified) { Column(modifier) { BooleanOption("Kontostand anzeigen", showBalance, textColor = textColor) { uiSettings.showBalance.value = it } - BooleanOption("Zebra Stripes", zebraStripes, textColor = textColor) { uiSettings.zebraStripes.value = it } + BooleanOption("Umsätze in alternierenden Farben anzeigen", showTransactionsInAlternatingColors, textColor = textColor) { uiSettings.showTransactionsInAlternatingColors.value = it } BooleanOption("Bank Icons anzeigen", showBankIcons, textColor = textColor) { uiSettings.showBankIcons.value = it } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/HoldingListItem.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/HoldingListItem.kt index bc1d73e..1c6a036 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/HoldingListItem.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/HoldingListItem.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import net.codinux.banking.client.model.Amount @@ -32,11 +31,11 @@ fun HoldingListItem(holding: Holding, isOddItem: Boolean = false, isNotLastItem: // TODO: also regard showBalance? val showColoredAmounts by uiSettings.showColoredAmounts.collectAsState() - val zebraStripes by uiSettings.zebraStripes.collectAsState() + val showTransactionsInAlternatingColors by uiSettings.showTransactionsInAlternatingColors.collectAsState() val showBankIcons by uiSettings.showBankIcons.collectAsState() - val backgroundColor = if (zebraStripes && isOddItem) Colors.ZebraStripesColor else Color.White + val backgroundColor = if (showTransactionsInAlternatingColors && isOddItem) Colors.ZebraStripesColor else Color.White val currency = holding.currency ?: fallbackCurrency diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt index 929460a..e2d1ecc 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/transactions/TransactionListItem.kt @@ -28,13 +28,13 @@ private val formatUtil = DI.formatUtil @Composable fun TransactionListItem(bank: BankAccess?, transaction: AccountTransactionViewModel, itemIndex: Int, countItems: Int) { - val zebraStripes by uiSettings.zebraStripes.collectAsState() + val showTransactionsInAlternatingColors by uiSettings.showTransactionsInAlternatingColors.collectAsState() val showBankIcons by uiSettings.showBankIcons.collectAsState() val showColoredAmounts by uiSettings.showColoredAmounts.collectAsState() - val backgroundColor = if (zebraStripes && itemIndex % 2 == 1) Colors.ZebraStripesColor else Color.White + val backgroundColor = if (showTransactionsInAlternatingColors && itemIndex % 2 == 1) Colors.ZebraStripesColor else Color.White val bottomPadding = 56.dp diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/DI.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/DI.kt index 101b158..4865136 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/DI.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/DI.kt @@ -36,7 +36,7 @@ object DI { var bankingRepository: BankingRepository = InMemoryBankingRepository(emptyList()) - val bankingService by lazy { BankingService(uiState, bankingRepository, bankFinder) } + val bankingService by lazy { BankingService(uiState, uiSettings, bankingRepository, bankFinder) } fun setRepository(sqlDriver: SqlDriver) = setRepository(SqliteBankingRepository(sqlDriver)) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt index 6f70167..3227679 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/BankingService.kt @@ -1,7 +1,9 @@ package net.codinux.banking.ui.service +import androidx.lifecycle.viewModelScope import bankmeister.composeapp.generated.resources.Res import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.datetime.LocalDate import net.codinux.banking.client.SimpleBankingClientCallback import net.codinux.banking.client.fints4k.FinTs4kBankingClient @@ -23,6 +25,7 @@ import net.codinux.banking.ui.model.error.* import net.codinux.banking.ui.model.events.AccountTransactionsRetrievedEvent import net.codinux.banking.ui.model.events.TransferredMoneyEvent import net.codinux.banking.ui.model.settings.AppSettings +import net.codinux.banking.ui.settings.UiSettings import net.codinux.banking.ui.state.UiState import net.codinux.csv.reader.CsvReader import net.codinux.log.logger @@ -31,6 +34,7 @@ import org.jetbrains.compose.resources.ExperimentalResourceApi @OptIn(ExperimentalResourceApi::class) class BankingService( private val uiState: UiState, + private val uiSettings: UiSettings, private val bankingRepository: BankingRepository, private val bankFinder: BankFinder ) { @@ -53,6 +57,10 @@ class BankingService( } uiState.appSettings.value = appSettings + bankingRepository.getUiSettings(uiSettings) + + updateOnChanges(uiSettings) + uiState.banks.value = getAllBanks() @@ -68,6 +76,8 @@ class BankingService( suspend fun saveAppSettings(settings: AppSettings) = bankingRepository.saveAppSettings(settings) + suspend fun saveUiSettings(settings: UiSettings) = bankingRepository.saveUiSettings(settings) + fun getAllBanks() = bankingRepository.getAllBanks() @@ -281,6 +291,24 @@ class BankingService( } + private suspend fun updateOnChanges(uiSettings: UiSettings) { + updateOnChanges(uiSettings, uiSettings.transactionsGrouping) + + updateOnChanges(uiSettings, uiSettings.showBalance) + updateOnChanges(uiSettings, uiSettings.showBankIcons) + updateOnChanges(uiSettings, uiSettings.showColoredAmounts) + updateOnChanges(uiSettings, uiSettings.showTransactionsInAlternatingColors) + } + + private suspend fun updateOnChanges(uiSettings: UiSettings, state: MutableStateFlow<*>) { + uiSettings.viewModelScope.launch(Dispatchers.Unconfined) { + state.collect { + saveUiSettings(uiSettings) + } + } + } + + private suspend fun readTransactionsFromCsv(): List { val csv = Res.readBytes("files/transactions.csv").decodeToString() val csvReader = CsvReader(hasHeaderRow = true, reuseRowInstance = true, skipEmptyRows = true).read(csv) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/settings/UiSettings.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/settings/UiSettings.kt index a82d39f..7fed82f 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/settings/UiSettings.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/settings/UiSettings.kt @@ -10,7 +10,7 @@ class UiSettings : ViewModel() { val transactionsGrouping = MutableStateFlow(TransactionsGrouping.Month) - val zebraStripes = MutableStateFlow(true) + val showTransactionsInAlternatingColors = MutableStateFlow(true) val showBankIcons = MutableStateFlow(true) diff --git a/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/Settings.sq b/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/Settings.sq index b618a6e..e978ea1 100644 --- a/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/Settings.sq +++ b/composeApp/src/commonMain/sqldelight/net/codinux/banking/ui/Settings.sq @@ -1,5 +1,6 @@ import kotlin.Boolean; + CREATE TABLE IF NOT EXISTS AppSettings ( id INTEGER PRIMARY KEY, @@ -17,3 +18,24 @@ SELECT * FROM AppSettings WHERE id = 1; upsertAppSettings: INSERT OR REPLACE INTO AppSettings(id, authenticationMethod, hashedPassword, updateAccountsOnAppStart, updateAccountsIfNoUpdatedForHours) VALUES (1, ?, ?, ?, ?); + + + +CREATE TABLE IF NOT EXISTS UiSettings ( + id INTEGER PRIMARY KEY, + + transactionsGrouping TEXT NOT NULL, + + showBalance INTEGER AS Boolean NOT NULL, + showBankIcons INTEGER AS Boolean NOT NULL, + showColoredAmounts INTEGER AS Boolean NOT NULL, + showTransactionsInAlternatingColors INTEGER AS Boolean NOT NULL +); + + +getUiSettings: +SELECT * FROM UiSettings WHERE id = 1; + +upsertUiSettings: +INSERT OR REPLACE INTO UiSettings(id, transactionsGrouping, showBalance, showBankIcons, showColoredAmounts, showTransactionsInAlternatingColors) +VALUES (1, ?, ?, ?, ?, ?);