Added option to set if TransactionsList should be shown in zebra stripes or not
This commit is contained in:
parent
d1687e894b
commit
89bc373476
|
@ -40,6 +40,10 @@ fun App() {
|
||||||
// we want to place the FAB half size into the BottomBar so we have to add some top padding to it
|
// we want to place the FAB half size into the BottomBar so we have to add some top padding to it
|
||||||
val fabPositionAdjustment = 44.dp // FabSpacing = 16.dp + FAB height (= 56.dp) / 2
|
val fabPositionAdjustment = 44.dp // FabSpacing = 16.dp + FAB height (= 56.dp) / 2
|
||||||
|
|
||||||
|
val uiState = DI.uiState
|
||||||
|
|
||||||
|
val uiSettings = DI.uiSettings
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
|
@ -56,13 +60,13 @@ fun App() {
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
shape = CircleShape,
|
shape = CircleShape,
|
||||||
modifier = Modifier.offset(x = 4.dp, y = fabPositionAdjustment),
|
modifier = Modifier.offset(x = 4.dp, y = fabPositionAdjustment),
|
||||||
onClick = { DI.uiState.showAddAccountDialog.value = true }
|
onClick = { uiState.showAddAccountDialog.value = true }
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Add, contentDescription = "Add a bank account")
|
Icon(Icons.Filled.Add, contentDescription = "Add a bank account")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
snackbarHost = { snackbarHostState ->
|
snackbarHost = { snackbarHostState ->
|
||||||
StateHandler(DI.uiState, snackbarHostState)
|
StateHandler(uiState, snackbarHostState)
|
||||||
|
|
||||||
SnackbarHost(
|
SnackbarHost(
|
||||||
hostState = snackbarHostState
|
hostState = snackbarHostState
|
||||||
|
@ -83,7 +87,7 @@ fun App() {
|
||||||
}
|
}
|
||||||
) { scaffoldPadding ->
|
) { scaffoldPadding ->
|
||||||
Column(Modifier.fillMaxSize().padding(scaffoldPadding), horizontalAlignment = Alignment.CenterHorizontally) {
|
Column(Modifier.fillMaxSize().padding(scaffoldPadding), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
TransactionsList(DI.uiState)
|
TransactionsList(uiState, uiSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package net.codinux.banking.ui.appskeleton
|
package net.codinux.banking.ui.appskeleton
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.Send
|
import androidx.compose.material.icons.automirrored.filled.Send
|
||||||
|
@ -21,9 +18,9 @@ import bankmeister.composeapp.generated.resources.Res
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.codinux.banking.ui.composables.BanksList
|
import net.codinux.banking.ui.composables.BanksList
|
||||||
import net.codinux.banking.ui.composables.NavigationMenuItem
|
import net.codinux.banking.ui.composables.NavigationMenuItem
|
||||||
|
import net.codinux.banking.ui.composables.settings.UiSettings
|
||||||
import net.codinux.banking.ui.config.Colors
|
import net.codinux.banking.ui.config.Colors
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import net.codinux.banking.ui.model.BankAccountFilter
|
|
||||||
import org.jetbrains.compose.resources.imageResource
|
import org.jetbrains.compose.resources.imageResource
|
||||||
|
|
||||||
private val uiState = DI.uiState
|
private val uiState = DI.uiState
|
||||||
|
@ -48,7 +45,7 @@ private val itemModifier = Modifier.height(ItemHeight).widthIn(min = 350.dp)
|
||||||
|
|
||||||
private val iconSize = 24.dp
|
private val iconSize = 24.dp
|
||||||
|
|
||||||
private val VerticalSpacing = 12.dp
|
private val VerticalSpacing = 8.dp
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -118,7 +115,8 @@ fun SideMenu(appContent: @Composable () -> Unit) {
|
||||||
if (accounts.isNotEmpty()) {
|
if (accounts.isNotEmpty()) {
|
||||||
Divider(color = Colors.DrawerDivider)
|
Divider(color = Colors.DrawerDivider)
|
||||||
|
|
||||||
Spacer(Modifier.height(VerticalSpacing))
|
Column(Modifier.padding(16.dp)) {
|
||||||
|
UiSettings(Modifier.fillMaxWidth().padding(bottom = VerticalSpacing))
|
||||||
|
|
||||||
NavigationMenuItem(itemModifier, "Daten exportieren", textColor, horizontalPadding = ItemHorizontalPadding, icon = { Icon(Icons.AutoMirrored.Filled.Send, "Konto hinzufügen", Modifier.size(iconSize)) }) {
|
NavigationMenuItem(itemModifier, "Daten exportieren", textColor, horizontalPadding = ItemHorizontalPadding, icon = { Icon(Icons.AutoMirrored.Filled.Send, "Konto hinzufügen", Modifier.size(iconSize)) }) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
|
@ -130,5 +128,6 @@ fun SideMenu(appContent: @Composable () -> Unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package net.codinux.banking.ui.composables.settings
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import net.codinux.banking.ui.config.DI
|
||||||
|
import net.codinux.banking.ui.forms.BooleanOption
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun UiSettings(modifier: Modifier) {
|
||||||
|
val uiSettings = DI.uiSettings
|
||||||
|
|
||||||
|
val zebraStripes by uiSettings.zebraStripes.collectAsState()
|
||||||
|
|
||||||
|
|
||||||
|
Column(modifier) {
|
||||||
|
BooleanOption("Zebra Stripes", zebraStripes) { uiSettings.zebraStripes.value = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import net.codinux.banking.ui.config.Colors
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import net.codinux.banking.ui.forms.RoundedCornersCard
|
import net.codinux.banking.ui.forms.RoundedCornersCard
|
||||||
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
import net.codinux.banking.ui.model.AccountTransactionViewModel
|
||||||
|
import net.codinux.banking.ui.settings.UiSettings
|
||||||
|
|
||||||
private val calculator = DI.calculator
|
private val calculator = DI.calculator
|
||||||
|
|
||||||
|
@ -29,13 +30,17 @@ private val formatUtil = DI.formatUtil
|
||||||
fun GroupedTransactionsListItems(
|
fun GroupedTransactionsListItems(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
transactionsToDisplay: List<AccountTransactionViewModel>,
|
transactionsToDisplay: List<AccountTransactionViewModel>,
|
||||||
userAccountsId: Map<Long, UserAccountEntity>
|
userAccountsId: Map<Long, UserAccountEntity>,
|
||||||
|
uiSettings: UiSettings
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val groupedByMonth by remember(transactionsToDisplay) {
|
val groupedByMonth by remember(transactionsToDisplay) {
|
||||||
derivedStateOf { transactionsToDisplay.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } }
|
derivedStateOf { transactionsToDisplay.groupBy { LocalDate(it.valueDate.year, it.valueDate.monthNumber, 1) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val zebraStripes by uiSettings.zebraStripes.collectAsState()
|
||||||
|
|
||||||
|
|
||||||
LazyColumn(modifier) {
|
LazyColumn(modifier) {
|
||||||
items(groupedByMonth.keys.sortedDescending()) { month ->
|
items(groupedByMonth.keys.sortedDescending()) { month ->
|
||||||
Column(Modifier.fillMaxWidth()) {
|
Column(Modifier.fillMaxWidth()) {
|
||||||
|
@ -54,7 +59,7 @@ fun GroupedTransactionsListItems(
|
||||||
RoundedCornersCard {
|
RoundedCornersCard {
|
||||||
Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed
|
Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed
|
||||||
monthTransactions.forEachIndexed { index, transaction ->
|
monthTransactions.forEachIndexed { index, transaction ->
|
||||||
val backgroundColor = if (index % 2 == 1) Colors.Zinc100_50 else Color.Transparent
|
val backgroundColor = if (zebraStripes && index % 2 == 1) Colors.Zinc100_50 else Color.Transparent
|
||||||
TransactionListItem(userAccountsId[transaction.userAccountId], transaction, backgroundColor)
|
TransactionListItem(userAccountsId[transaction.userAccountId], transaction, backgroundColor)
|
||||||
|
|
||||||
if (index < monthTransactions.size - 1) {
|
if (index < monthTransactions.size - 1) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import net.codinux.banking.ui.config.Colors
|
import net.codinux.banking.ui.config.Colors
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
|
import net.codinux.banking.ui.settings.UiSettings
|
||||||
import net.codinux.banking.ui.state.UiState
|
import net.codinux.banking.ui.state.UiState
|
||||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ private val calculator = DI.calculator
|
||||||
private val formatUtil = DI.formatUtil
|
private val formatUtil = DI.formatUtil
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TransactionsList(uiState: UiState) {
|
fun TransactionsList(uiState: UiState, uiSettings: UiSettings) {
|
||||||
val userAccounts by uiState.userAccounts.collectAsState()
|
val userAccounts by uiState.userAccounts.collectAsState()
|
||||||
val userAccountsId by remember(userAccounts) {
|
val userAccountsId by remember(userAccounts) {
|
||||||
derivedStateOf { userAccounts.associateBy { it.id } }
|
derivedStateOf { userAccounts.associateBy { it.id } }
|
||||||
|
@ -46,7 +47,7 @@ fun TransactionsList(uiState: UiState) {
|
||||||
Text(formatUtil.formatAmount(balance, "EUR"), color = formatUtil.getColorForAmount(balance))
|
Text(formatUtil.formatAmount(balance, "EUR"), color = formatUtil.getColorForAmount(balance))
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupedTransactionsListItems(transactionsListModifier, transactionsToDisplay, userAccountsId)
|
GroupedTransactionsListItems(transactionsListModifier, transactionsToDisplay, userAccountsId, uiSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +55,6 @@ fun TransactionsList(uiState: UiState) {
|
||||||
@Composable
|
@Composable
|
||||||
fun TransactionsListPreview() {
|
fun TransactionsListPreview() {
|
||||||
MaterialTheme {
|
MaterialTheme {
|
||||||
TransactionsList(UiState())
|
TransactionsList(UiState(), UiSettings())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,15 @@ import net.codinux.banking.dataaccess.SqliteBankingRepository
|
||||||
import net.codinux.banking.ui.Platform
|
import net.codinux.banking.ui.Platform
|
||||||
import net.codinux.banking.ui.getPlatform
|
import net.codinux.banking.ui.getPlatform
|
||||||
import net.codinux.banking.ui.service.*
|
import net.codinux.banking.ui.service.*
|
||||||
|
import net.codinux.banking.ui.settings.UiSettings
|
||||||
import net.codinux.banking.ui.state.UiState
|
import net.codinux.banking.ui.state.UiState
|
||||||
|
|
||||||
object DI {
|
object DI {
|
||||||
|
|
||||||
val uiState = UiState()
|
val uiState = UiState()
|
||||||
|
|
||||||
|
val uiSettings = UiSettings()
|
||||||
|
|
||||||
val platform: Platform = getPlatform()
|
val platform: Platform = getPlatform()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.codinux.banking.ui.forms
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.Switch
|
||||||
|
import androidx.compose.material.SwitchDefaults
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import net.codinux.banking.ui.config.Colors
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BooleanOption(label: String, isChecked: Boolean, enabled: Boolean = true, checkChanged: (Boolean) -> Unit) {
|
||||||
|
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Switch(checked = isChecked, onCheckedChange = checkChanged, enabled = enabled, colors = SwitchDefaults.colors(checkedThumbColor = Colors.CodinuxSecondaryColor))
|
||||||
|
|
||||||
|
Text(label, Modifier.fillMaxWidth().clickable { checkChanged(!!!isChecked) }.padding(start = 6.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package net.codinux.banking.ui.settings
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
class UiSettings : ViewModel() {
|
||||||
|
|
||||||
|
val zebraStripes = MutableStateFlow(true)
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue