Added menu button and side navigation menu with all accounts
This commit is contained in:
parent
5cf086485e
commit
572bd8e9d8
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,24C18.6274,24 24,18.6274 24,12C24,5.3726 18.6274,0 12,0C5.3726,0 0,5.3726 0,12C0,18.6274 5.3726,24 12,24ZM6,7.5C6,6.9477 6.4477,6.5 7,6.5H17C17.5523,6.5 18,6.9477 18,7.5V16.5C18,17.0523 17.5523,17.5 17,17.5H7C6.4477,17.5 6,17.0523 6,16.5V7.5ZM7.5,12.9C7.5,12.6791 7.6791,12.5 7.9,12.5H16.1C16.3209,12.5 16.5,12.6791 16.5,12.9V13.1C16.5,13.3209 16.3209,13.5 16.1,13.5H7.9C7.6791,13.5 7.5,13.3209 7.5,13.1V12.9ZM13.9,8.5C13.6791,8.5 13.5,8.6791 13.5,8.9V9.3C13.5,9.5209 13.6791,9.7 13.9,9.7H16.1C16.3209,9.7 16.5,9.5209 16.5,9.3V8.9C16.5,8.6791 16.3209,8.5 16.1,8.5H13.9ZM7.5,14.9C7.5,14.6791 7.6791,14.5 7.9,14.5H16.1C16.3209,14.5 16.5,14.6791 16.5,14.9V15.1C16.5,15.3209 16.3209,15.5 16.1,15.5H7.9C7.6791,15.5 7.5,15.3209 7.5,15.1V14.9Z"
|
||||||
|
android:fillColor="#989792"
|
||||||
|
android:fillType="evenOdd"/>
|
||||||
|
</vector>
|
|
@ -14,11 +14,13 @@ import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import net.codinux.banking.ui.appskeleton.BottomBar
|
||||||
|
import net.codinux.banking.ui.appskeleton.SideMenu
|
||||||
import net.codinux.banking.ui.composables.StateHandler
|
import net.codinux.banking.ui.composables.StateHandler
|
||||||
import net.codinux.banking.ui.composables.TransactionsList
|
import net.codinux.banking.ui.composables.TransactionsList
|
||||||
import net.codinux.banking.ui.dialogs.AddAccountDialog
|
|
||||||
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.dialogs.AddAccountDialog
|
||||||
import net.codinux.log.LoggerFactory
|
import net.codinux.log.LoggerFactory
|
||||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
|
@ -31,7 +33,7 @@ private val typography = Typography(
|
||||||
fun App() {
|
fun App() {
|
||||||
LoggerFactory.defaultLoggerName = "net.codinux.banking.ui.Bankmeister"
|
LoggerFactory.defaultLoggerName = "net.codinux.banking.ui.Bankmeister"
|
||||||
|
|
||||||
val colors = MaterialTheme.colors.copy(secondary = Colors.CodinuxSecondaryColor, onSecondary = Color.White)
|
val colors = MaterialTheme.colors.copy(primary = Colors.Primary, primaryVariant = Colors.PrimaryDark, secondary = Colors.Accent, onSecondary = Color.White)
|
||||||
|
|
||||||
var showAddAccountDialog by remember { mutableStateOf(false) }
|
var showAddAccountDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
@ -43,29 +45,34 @@ fun App() {
|
||||||
|
|
||||||
|
|
||||||
MaterialTheme(colors = colors, typography = typography) {
|
MaterialTheme(colors = colors, typography = typography) {
|
||||||
Box {
|
SideMenu {
|
||||||
Column(
|
Box(modifier = Modifier.background(Colors.CodinuxSecondaryColor).padding(0.dp)) {
|
||||||
Modifier.fillMaxWidth().fillMaxHeight().background(color = Colors.Zinc100),
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
Modifier.fillMaxWidth().fillMaxHeight().background(color = Colors.Zinc100)
|
||||||
) {
|
|
||||||
TransactionsList(DI.uiState)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(Modifier.align(Alignment.BottomEnd)) {
|
|
||||||
FloatingActionButton(
|
|
||||||
shape = CircleShape,
|
|
||||||
modifier = Modifier.offset((-12).dp, (-12).dp),
|
|
||||||
onClick = { showAddAccountDialog = true }
|
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Add, contentDescription = "Add a bank account")
|
Column(Modifier.fillMaxWidth().weight(1f), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
TransactionsList(DI.uiState)
|
||||||
|
}
|
||||||
|
|
||||||
|
BottomBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(Modifier.align(Alignment.BottomEnd)) {
|
||||||
|
FloatingActionButton(
|
||||||
|
shape = CircleShape,
|
||||||
|
modifier = Modifier.offset((-12).dp, (-26).dp),
|
||||||
|
onClick = { showAddAccountDialog = true }
|
||||||
|
) {
|
||||||
|
Icon(Icons.Filled.Add, contentDescription = "Add a bank account")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showAddAccountDialog) {
|
||||||
|
AddAccountDialog { showAddAccountDialog = false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showAddAccountDialog) {
|
StateHandler(DI.uiState)
|
||||||
AddAccountDialog { showAddAccountDialog = false }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHandler(DI.uiState)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package net.codinux.banking.ui.appskeleton
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material.BottomAppBar
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Menu
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import net.codinux.banking.ui.config.Colors
|
||||||
|
import net.codinux.banking.ui.config.DI
|
||||||
|
import net.codinux.banking.ui.extensions.toggle
|
||||||
|
|
||||||
|
private val uiState = DI.uiState
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BottomBar() {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
||||||
|
BottomAppBar(modifier = Modifier.background(Colors.Accent)) {
|
||||||
|
IconButton(
|
||||||
|
onClick = { coroutineScope.launch {
|
||||||
|
uiState.drawerState.value.toggle()
|
||||||
|
} }
|
||||||
|
) {
|
||||||
|
Icon(Icons.Filled.Menu, contentDescription = "Open Navigation Drawer with sidebar menu")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
|
||||||
|
Spacer(Modifier.width(72.dp)) // space for Floating Action Button
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package net.codinux.banking.ui.appskeleton
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import bankmeister.composeapp.generated.resources.AppIcon
|
||||||
|
import bankmeister.composeapp.generated.resources.Res
|
||||||
|
import net.codinux.banking.ui.composables.BanksList
|
||||||
|
import net.codinux.banking.ui.config.Colors
|
||||||
|
import net.codinux.banking.ui.config.DI
|
||||||
|
import org.jetbrains.compose.resources.imageResource
|
||||||
|
|
||||||
|
private val uiState = DI.uiState
|
||||||
|
|
||||||
|
private val HeaderHeight = 160f
|
||||||
|
|
||||||
|
private val HeaderBackground = Brush.linearGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color(0xFF00695C), // endColor: #00695C
|
||||||
|
Color(0xFF009688), // centerColor: #009688
|
||||||
|
Color(0xFF4DB6AC), // startColor: #4DB6AC
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SideMenu(appContent: @Composable () -> Unit) {
|
||||||
|
val drawerState = uiState.drawerState.collectAsState().value
|
||||||
|
|
||||||
|
ModalDrawer(
|
||||||
|
modifier = Modifier.fillMaxHeight(),
|
||||||
|
drawerState = drawerState,
|
||||||
|
content = appContent,
|
||||||
|
drawerBackgroundColor = Colors.DrawerContentBackground,
|
||||||
|
drawerContentColor = Colors.DrawerPrimaryText, // seems to have no effect
|
||||||
|
drawerContent = {
|
||||||
|
Column(Modifier) {
|
||||||
|
Column(Modifier.fillMaxWidth().height(HeaderHeight.dp).background(HeaderBackground).padding(16.dp)) {
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
|
||||||
|
Image(imageResource(Res.drawable.AppIcon), "Bankmeister's app icon", Modifier.size(48.dp))
|
||||||
|
|
||||||
|
Text("Bankmeister", color = Color.White, modifier = Modifier.padding(top = 16.dp, bottom = 8.dp))
|
||||||
|
|
||||||
|
Text("Version 1.0.0 Alpha 12", color = Color.LightGray)
|
||||||
|
}
|
||||||
|
|
||||||
|
Divider(color = Colors.DrawerDivider)
|
||||||
|
|
||||||
|
Column(Modifier.padding(horizontal = 16.dp, vertical = 24.dp)) {
|
||||||
|
Column(Modifier.height(40.dp), verticalArrangement = Arrangement.Center) {
|
||||||
|
Text("Konten", color = Colors.DrawerPrimaryText)
|
||||||
|
}
|
||||||
|
|
||||||
|
BanksList(textColor = Colors.DrawerPrimaryText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
package net.codinux.banking.ui.composables
|
package net.codinux.banking.ui.composables
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
@ -14,37 +14,45 @@ import net.codinux.banking.client.model.UserAccountViewInfo
|
||||||
import net.codinux.banking.ui.config.DI
|
import net.codinux.banking.ui.config.DI
|
||||||
import net.codinux.banking.ui.model.BankInfo
|
import net.codinux.banking.ui.model.BankInfo
|
||||||
import net.dankito.banking.banklistcreator.prettifier.BankingGroupMapper
|
import net.dankito.banking.banklistcreator.prettifier.BankingGroupMapper
|
||||||
|
import org.jetbrains.compose.resources.DrawableResource
|
||||||
|
import org.jetbrains.compose.resources.vectorResource
|
||||||
|
|
||||||
private val bankIconService = DI.bankIconService
|
private val bankIconService = DI.bankIconService
|
||||||
|
|
||||||
|
private val DefaultIconModifier: Modifier = Modifier.size(16.dp)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(userAccount: UserAccount?, modifier: Modifier = Modifier) {
|
fun BankIcon(userAccount: UserAccount?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, fallbackIcon: DrawableResource? = null) {
|
||||||
val iconUrl by remember(userAccount?.bic) { mutableStateOf(userAccount?.let { bankIconService.findIconForBank(it) }) }
|
val iconUrl by remember(userAccount?.bic) { mutableStateOf(userAccount?.let { bankIconService.findIconForBank(it) }) }
|
||||||
|
|
||||||
BankIcon(iconUrl, modifier)
|
BankIcon(iconUrl, modifier, iconModifier, fallbackIcon = fallbackIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val bankingGroupMapper = BankingGroupMapper()
|
private val bankingGroupMapper = BankingGroupMapper()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(bank: BankInfo, modifier: Modifier = Modifier) {
|
fun BankIcon(bank: BankInfo, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, fallbackIcon: DrawableResource? = null) {
|
||||||
val iconUrl by remember(bank.bic) { mutableStateOf(bankIconService.findIconForBank(bank.name, bankingGroupMapper.getBankingGroup(bank.name, bank.bic))) }
|
val iconUrl by remember(bank.bic) { mutableStateOf(bankIconService.findIconForBank(bank.name, bankingGroupMapper.getBankingGroup(bank.name, bank.bic))) }
|
||||||
|
|
||||||
BankIcon(iconUrl, modifier)
|
BankIcon(iconUrl, modifier, iconModifier, fallbackIcon = fallbackIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(userAccount: UserAccountViewInfo?, modifier: Modifier = Modifier) {
|
fun BankIcon(userAccount: UserAccountViewInfo?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, fallbackIcon: DrawableResource? = null) {
|
||||||
val iconUrl = userAccount?.let { bankIconService.findIconForBank(it.bankName, it.bankingGroup) }
|
val iconUrl = userAccount?.let { bankIconService.findIconForBank(it.bankName, it.bankingGroup) }
|
||||||
|
|
||||||
BankIcon(iconUrl, modifier)
|
BankIcon(iconUrl, modifier, iconModifier, fallbackIcon = fallbackIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BankIcon(iconUrl: String?, modifier: Modifier = Modifier) {
|
fun BankIcon(iconUrl: String?, modifier: Modifier = Modifier, iconModifier: Modifier = DefaultIconModifier, contentDescription: String = "Favicon of this bank", fallbackIcon: DrawableResource? = null) {
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
iconUrl?.let {
|
if (iconUrl != null) {
|
||||||
IconForUrl(iconUrl, "Favicon of this bank", Modifier.width(16.dp).height(16.dp))
|
IconForUrl(iconUrl, contentDescription, modifier = iconModifier)
|
||||||
|
} else if (fallbackIcon != null) {
|
||||||
|
Image(vectorResource(fallbackIcon), contentDescription, iconModifier)
|
||||||
|
} else {
|
||||||
|
Column(iconModifier) { } // show a placeholder for consistent layout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package net.codinux.banking.ui.composables
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import bankmeister.composeapp.generated.resources.Res
|
||||||
|
import bankmeister.composeapp.generated.resources.account
|
||||||
|
import net.codinux.banking.ui.config.DI
|
||||||
|
|
||||||
|
private val uiState = DI.uiState
|
||||||
|
|
||||||
|
private val IconTextSpacing = 36.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BanksList(modifier: Modifier = Modifier, itemModifier: Modifier = Modifier.height(48.dp).widthIn(min = 300.dp).padding(start = 8.dp), iconSize: Dp = 24.dp, textColor: Color = Color.White) {
|
||||||
|
val userAccounts = uiState.userAccounts.collectAsState()
|
||||||
|
|
||||||
|
Column(modifier) {
|
||||||
|
Row(itemModifier, verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
BankIcon(null as? String?, Modifier.padding(end = IconTextSpacing), Modifier.size(iconSize), fallbackIcon = Res.drawable.account)
|
||||||
|
|
||||||
|
Text("Alle Konten", color = textColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
userAccounts.value.forEach { userAccount ->
|
||||||
|
Spacer(Modifier.fillMaxWidth().height(12.dp))
|
||||||
|
|
||||||
|
Row(itemModifier, verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
BankIcon(userAccount, Modifier.padding(end = IconTextSpacing), Modifier.size(iconSize), fallbackIcon = Res.drawable.account)
|
||||||
|
|
||||||
|
Text(userAccount.bankName, color = textColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
userAccount.accounts.sortedBy { it.displayIndex }.forEach { account ->
|
||||||
|
Column(itemModifier.padding(start = iconSize + IconTextSpacing), verticalArrangement = Arrangement.Center) {
|
||||||
|
Text(account.productName ?: account.identifier, color = textColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,9 +27,9 @@ private val formatUtil = DI.formatUtil
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TransactionsList(uiState: UiState) {
|
fun TransactionsList(uiState: UiState) {
|
||||||
val users by uiState.userAccounts.collectAsState()
|
val userAccounts by uiState.userAccounts.collectAsState()
|
||||||
val usersById by remember(users) {
|
val userAccountsId by remember(userAccounts) {
|
||||||
derivedStateOf { users.associateBy { it.id } }
|
derivedStateOf { userAccounts.associateBy { it.id } }
|
||||||
}
|
}
|
||||||
|
|
||||||
val transactions by uiState.transactions.collectAsState()
|
val transactions by uiState.transactions.collectAsState()
|
||||||
|
@ -58,7 +58,7 @@ fun TransactionsList(uiState: UiState) {
|
||||||
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 (index % 2 == 1) Colors.Zinc100_50 else Color.Transparent
|
||||||
TransactionListItem(usersById[transaction.userAccountId], transaction, backgroundColor)
|
TransactionListItem(userAccountsId[transaction.userAccountId], transaction, backgroundColor)
|
||||||
|
|
||||||
if (index < monthTransactions.size - 1) {
|
if (index < monthTransactions.size - 1) {
|
||||||
Divider(color = Colors.Zinc200, thickness = 1.dp)
|
Divider(color = Colors.Zinc200, thickness = 1.dp)
|
||||||
|
|
|
@ -1,9 +1,32 @@
|
||||||
package net.codinux.banking.ui.config
|
package net.codinux.banking.ui.config
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import net.codinux.banking.ui.extensions.Color
|
||||||
|
|
||||||
object Colors {
|
object Colors {
|
||||||
|
|
||||||
|
val Primary = Color("#014e45")
|
||||||
|
|
||||||
|
val PrimaryDark = Color("#FF042204")
|
||||||
|
|
||||||
|
val Accent = Color("#00786a")
|
||||||
|
|
||||||
|
val PrimaryTextColorDark = Color("#BABABA")
|
||||||
|
|
||||||
|
val PrimaryTextColorLight = Color("#000000")
|
||||||
|
|
||||||
|
val BackgroundColorDark = Color("#303030")
|
||||||
|
|
||||||
|
val BackgroundColorLight = Color("#FFFFFF")
|
||||||
|
|
||||||
|
|
||||||
|
val DrawerContentBackground = BackgroundColorDark
|
||||||
|
|
||||||
|
val DrawerPrimaryText = PrimaryTextColorDark
|
||||||
|
|
||||||
|
val DrawerDivider = PrimaryTextColorDark
|
||||||
|
|
||||||
|
|
||||||
val CodinuxPrimaryColor = Color(30, 54, 78)
|
val CodinuxPrimaryColor = Color(30, 54, 78)
|
||||||
|
|
||||||
val CodinuxSecondaryColor = Color(251, 187, 33)
|
val CodinuxSecondaryColor = Color(251, 187, 33)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package net.codinux.banking.ui.extensions
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
fun Color(hex: String): Color {
|
||||||
|
val colorInt = parseColor(hex)
|
||||||
|
return Color(colorInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun parseColor(colorString: String): Int {
|
||||||
|
val colorString2 = if (colorString[0] == '#') colorString.substring(1) else colorString
|
||||||
|
|
||||||
|
if (colorString2.length == 6 || colorString2.length == 8) {
|
||||||
|
// Use a long to avoid rollovers on #ffXXXXXX
|
||||||
|
var color = colorString2.toLong(16)
|
||||||
|
if (colorString2.length == 6) {
|
||||||
|
// Set the alpha value
|
||||||
|
color = color or 0x00000000ff000000L
|
||||||
|
}
|
||||||
|
|
||||||
|
return color.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
throw IllegalArgumentException("Unknown color: $colorString")
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package net.codinux.banking.ui.extensions
|
||||||
|
|
||||||
|
import androidx.compose.material.DrawerState
|
||||||
|
|
||||||
|
suspend fun DrawerState.toggle() {
|
||||||
|
if (this.isClosed) {
|
||||||
|
this.open()
|
||||||
|
} else {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package net.codinux.banking.ui.state
|
package net.codinux.banking.ui.state
|
||||||
|
|
||||||
|
import androidx.compose.material.DrawerState
|
||||||
|
import androidx.compose.material.DrawerValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
import net.codinux.banking.dataaccess.entities.UserAccountEntity
|
||||||
|
@ -15,6 +17,10 @@ class UiState : ViewModel() {
|
||||||
|
|
||||||
val transactions = MutableStateFlow<List<AccountTransactionViewModel>>(emptyList())
|
val transactions = MutableStateFlow<List<AccountTransactionViewModel>>(emptyList())
|
||||||
|
|
||||||
|
|
||||||
|
val drawerState = MutableStateFlow(DrawerState(DrawerValue.Open))
|
||||||
|
|
||||||
|
|
||||||
val applicationErrorOccurred = MutableStateFlow<ApplicationError?>(null)
|
val applicationErrorOccurred = MutableStateFlow<ApplicationError?>(null)
|
||||||
|
|
||||||
val bankingClientErrorOccurred = MutableStateFlow<BankingClientError?>(null)
|
val bankingClientErrorOccurred = MutableStateFlow<BankingClientError?>(null)
|
||||||
|
|
Loading…
Reference in New Issue