From b66ea6f2be1818c5983a456586c75e3a4180f267 Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Tue, 25 Mar 2025 07:41:42 -0300 Subject: [PATCH 1/7] refactor: extract large row code to a composable --- .../bitkit/ui/components/BalanceHeaderView.kt | 83 +++++++++---------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index 54a9dcf17..a7c82bd11 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -41,30 +41,13 @@ fun BalanceHeaderView( text = "${converted.symbol} ${converted.formatted}" ) - // large row val btcComponents = converted.bitcoinDisplay(displayUnit) - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.height(62.dp) - ) { - if (prefix != null) { - Display( - text = prefix, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) - ) - } - if (showBitcoinSymbol) { - Display( - text = btcComponents.symbol, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) - ) - } - Display(text = btcComponents.value) - } + LargeRow( + prefix = prefix, + text = btcComponents.value, + symbol = btcComponents.symbol, + showSymbol = showBitcoinSymbol + ) } } else { Column { @@ -73,34 +56,44 @@ fun BalanceHeaderView( prefix = prefix, text = "${btcComponents.symbol} ${btcComponents.value}" ) - - // large row - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.height(62.dp) - ) { - if (prefix != null) { - Display( - text = prefix, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) - ) - } - Display( - text = converted.symbol, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) - ) - Display(text = converted.formatted) - } + LargeRow( + prefix = prefix, + text = converted.formatted, + symbol = converted.symbol, + showSymbol = true + ) } } } } } +@Composable +fun LargeRow(prefix: String?, text: String, symbol: String, showSymbol: Boolean) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.height(62.dp) + ) { + if (prefix != null) { + Display( + text = prefix, + modifier = Modifier + .alpha(0.6f) + .padding(end = 8.dp) + ) + } + if (showSymbol) { + Display( + text = symbol, + modifier = Modifier + .alpha(0.6f) + .padding(end = 8.dp) + ) + } + Display(text = text) + } +} + @Composable private fun SmallRow(prefix: String?, text: String) { Row( From 3310e8272f6810826d723f3e82b532834aa8d3df Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Tue, 25 Mar 2025 09:16:37 -0300 Subject: [PATCH 2/7] refactor: extract code to the BalanceHeader component --- .../bitkit/ui/components/BalanceHeaderView.kt | 131 +++++++++++------- 1 file changed, 84 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index a7c82bd11..9ed6bd74e 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -3,18 +3,23 @@ package to.bitkit.ui.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import to.bitkit.models.ConvertedAmount import to.bitkit.models.PrimaryDisplay import to.bitkit.ui.LocalCurrencies import to.bitkit.ui.currencyViewModel import to.bitkit.ui.shared.util.clickableAlpha +import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors @Composable fun BalanceHeaderView( @@ -27,44 +32,64 @@ fun BalanceHeaderView( val (rates, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies.current val converted: ConvertedAmount? = if (rates.isNotEmpty()) currency.convert(sats = sats) else null + converted?.let { converted -> + val btcComponents = converted.bitcoinDisplay(displayUnit) + + if (primaryDisplay == PrimaryDisplay.BITCOIN) { + BalanceHeader( + modifier = modifier, + smallRowPrefix = prefix, + smallRowText = "${converted.symbol} ${converted.formatted}", + largeRowPrefix = prefix, + largeRowText = btcComponents.value, + largeRowSymbol = btcComponents.symbol, + showSymbol = showBitcoinSymbol, + onClick = { currency.togglePrimaryDisplay() } + ) + } else { + BalanceHeader( + modifier = modifier, + smallRowPrefix = prefix, + smallRowText = "${btcComponents.symbol} ${btcComponents.value}", + largeRowPrefix = prefix, + largeRowText = converted.formatted, + largeRowSymbol = converted.symbol, + showSymbol = true, + onClick = { currency.togglePrimaryDisplay() } + ) + } + } +} + +@Composable +fun BalanceHeader( + smallRowPrefix: String? = null, + smallRowText: String, + largeRowPrefix: String? = null, + largeRowText: String, + largeRowSymbol: String, + showSymbol: Boolean, + modifier: Modifier = Modifier, + onClick: () -> Unit +) { Column( - verticalArrangement = Arrangement.spacedBy(4.dp), + verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.Start, - modifier = modifier - .clickableAlpha { currency.togglePrimaryDisplay() } + modifier = modifier.clickableAlpha { onClick() } ) { - converted?.let { converted -> - if (primaryDisplay == PrimaryDisplay.BITCOIN) { - Column { - SmallRow( - prefix = prefix, - text = "${converted.symbol} ${converted.formatted}" - ) + SmallRow( + prefix = smallRowPrefix, + text = smallRowText + ) - val btcComponents = converted.bitcoinDisplay(displayUnit) - LargeRow( - prefix = prefix, - text = btcComponents.value, - symbol = btcComponents.symbol, - showSymbol = showBitcoinSymbol - ) - } - } else { - Column { - val btcComponents = converted.bitcoinDisplay(displayUnit) - SmallRow( - prefix = prefix, - text = "${btcComponents.symbol} ${btcComponents.value}" - ) - LargeRow( - prefix = prefix, - text = converted.formatted, - symbol = converted.symbol, - showSymbol = true - ) - } - } - } + Spacer(modifier = Modifier.height(16.dp)) + + LargeRow( + prefix = largeRowPrefix, + text = largeRowText, + symbol = largeRowSymbol, + showSymbol = showSymbol + ) } } @@ -72,22 +97,19 @@ fun BalanceHeaderView( fun LargeRow(prefix: String?, text: String, symbol: String, showSymbol: Boolean) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.height(62.dp) ) { if (prefix != null) { Display( text = prefix, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) + color = Colors.White64, + modifier = Modifier.padding(end = 8.dp) ) } if (showSymbol) { Display( text = symbol, - modifier = Modifier - .alpha(0.6f) - .padding(end = 8.dp) + color = Colors.White64, + modifier = Modifier.padding(end = 8.dp) ) } Display(text = text) @@ -97,20 +119,35 @@ fun LargeRow(prefix: String?, text: String, symbol: String, showSymbol: Boolean) @Composable private fun SmallRow(prefix: String?, text: String) { Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .height(24.dp) - .padding(bottom = 4.dp) + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(4.dp), ) { if (prefix != null) { Caption13Up( text = prefix, - modifier = Modifier.alpha(0.6f) + color = Colors.White64, ) } Caption13Up( text = text, - modifier = Modifier.alpha(0.6f) + color = Colors.White64, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview() { + AppThemeSurface { + BalanceHeader( + smallRowPrefix = "$", + smallRowText = "27.36", + largeRowPrefix = "₿", + largeRowText = "136 825", + largeRowSymbol = "sats", + showSymbol = false, + modifier = Modifier.fillMaxWidth(), + onClick = {} ) } } From 4bb6d71ddcfcb052e68e0e83384e7e559f544dcb Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Wed, 26 Mar 2025 08:31:17 -0300 Subject: [PATCH 3/7] feat: create BalanceHeaderEditable WIP --- .../bitkit/ui/components/BalanceHeaderView.kt | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index 9ed6bd74e..85d556ef9 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -8,11 +8,17 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import org.ldk.structs.Amount.currency import to.bitkit.models.ConvertedAmount import to.bitkit.models.PrimaryDisplay import to.bitkit.ui.LocalCurrencies @@ -61,6 +67,80 @@ fun BalanceHeaderView( } } + +@Composable +fun BalanceHeaderEditable( + input: String, + showBitcoinSymbol: Boolean = true, + onSatsChanged: (String) -> Unit, + modifier: Modifier = Modifier, +) { + val (rates, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies.current + val currency = currencyViewModel ?: return + + var satsValue: String by remember { mutableStateOf("") } + var fiatValue: String by remember { mutableStateOf("") } + + var smallRowPrefix: String by remember { mutableStateOf("") } + var smallRowText: String by remember { mutableStateOf("") } + + var largeRowPrefix: String by remember { mutableStateOf("") } + var largeRowText: String by remember { mutableStateOf("") } + var largeRowSymbol: String by remember { mutableStateOf("") } + + + + // Effect to handle input and display unit changes + LaunchedEffect(input, primaryDisplay) { + when (primaryDisplay) { + PrimaryDisplay.BITCOIN -> { + // When primary display is Bitcoin + satsValue += input +// largeRowText = input + + // Convert sats to fiat for small row + val sats = satsValue.toLongOrNull() ?: 0L + + val converted = if (rates.isNotEmpty()) currency.convert(sats = sats) else null + converted?.let { + val btcComponents = converted.bitcoinDisplay(displayUnit) + smallRowPrefix = it.symbol + smallRowText = "${converted.symbol} ${converted.formatted}" + largeRowText = btcComponents.value + largeRowSymbol = btcComponents.symbol + } + } + PrimaryDisplay.FIAT -> { + // When primary display is Fiat + val converted = if (rates.isNotEmpty()) currency.convert(sats = input.toLongOrNull() ?: 0L) else null + converted?.let { + fiatValue = it.formatted + largeRowText = converted.formatted + largeRowSymbol = it.symbol + + // Convert fiat to sats for small row + satsValue = it.sats.toString() + smallRowText = it.sats.toString() + } + } + } + + // Trigger callback with sats value + onSatsChanged(satsValue) + } + + BalanceHeader( + modifier = modifier, + smallRowPrefix = smallRowPrefix, + smallRowText = smallRowText, + largeRowPrefix = largeRowPrefix, + largeRowText = largeRowText, + largeRowSymbol = largeRowSymbol, + showSymbol = showBitcoinSymbol, + onClick = { } + ) +} + @Composable fun BalanceHeader( smallRowPrefix: String? = null, From 1e87042e288a049c8d98dc548f1bfcdfa8c102c7 Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Wed, 26 Mar 2025 08:54:04 -0300 Subject: [PATCH 4/7] feat: create BalanceHeaderEditable WIP --- .../bitkit/ui/components/BalanceHeaderView.kt | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index 85d556ef9..00fb8a06d 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -83,6 +83,7 @@ fun BalanceHeaderEditable( var smallRowPrefix: String by remember { mutableStateOf("") } var smallRowText: String by remember { mutableStateOf("") } + var smallRowSymbol: String by remember { mutableStateOf("") } var largeRowPrefix: String by remember { mutableStateOf("") } var largeRowText: String by remember { mutableStateOf("") } @@ -104,23 +105,26 @@ fun BalanceHeaderEditable( val converted = if (rates.isNotEmpty()) currency.convert(sats = sats) else null converted?.let { val btcComponents = converted.bitcoinDisplay(displayUnit) - smallRowPrefix = it.symbol - smallRowText = "${converted.symbol} ${converted.formatted}" + smallRowSymbol = it.symbol + smallRowText = "${smallRowSymbol} ${converted.formatted}" largeRowText = btcComponents.value largeRowSymbol = btcComponents.symbol } } PrimaryDisplay.FIAT -> { // When primary display is Fiat - val converted = if (rates.isNotEmpty()) currency.convert(sats = input.toLongOrNull() ?: 0L) else null + fiatValue += input + + val converted = if (rates.isNotEmpty()) currency.convertFiatToSats(fiatAmount = (fiatValue + input).toDoubleOrNull() ?: 0.0) else null converted?.let { - fiatValue = it.formatted - largeRowText = converted.formatted - largeRowSymbol = it.symbol + largeRowText = fiatValue + largeRowSymbol = "$" // Convert fiat to sats for small row - satsValue = it.sats.toString() - smallRowText = it.sats.toString() + satsValue = it.toString() + smallRowSymbol = "B" + smallRowText = "$smallRowSymbol $satsValue" + } } } From cc400f8326e49652c61c4b82e473ff80b2df6aac Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Wed, 26 Mar 2025 14:13:59 -0300 Subject: [PATCH 5/7] fix: state update --- .../bitkit/ui/components/BalanceHeaderView.kt | 46 +++++++++---------- .../screens/wallets/send/SendAmountScreen.kt | 16 ++++++- .../to/bitkit/viewmodels/CurrencyViewModel.kt | 1 + 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index 00fb8a06d..ab9f7f814 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -9,16 +9,14 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import org.ldk.structs.Amount.currency import to.bitkit.models.ConvertedAmount import to.bitkit.models.PrimaryDisplay import to.bitkit.ui.LocalCurrencies @@ -45,7 +43,8 @@ fun BalanceHeaderView( BalanceHeader( modifier = modifier, smallRowPrefix = prefix, - smallRowText = "${converted.symbol} ${converted.formatted}", + smallRowSymbol = converted.symbol, + smallRowText = converted.formatted, largeRowPrefix = prefix, largeRowText = btcComponents.value, largeRowSymbol = btcComponents.symbol, @@ -56,7 +55,8 @@ fun BalanceHeaderView( BalanceHeader( modifier = modifier, smallRowPrefix = prefix, - smallRowText = "${btcComponents.symbol} ${btcComponents.value}", + smallRowSymbol = btcComponents.symbol, + smallRowText = btcComponents.value, largeRowPrefix = prefix, largeRowText = converted.formatted, largeRowSymbol = converted.symbol, @@ -91,51 +91,43 @@ fun BalanceHeaderEditable( - // Effect to handle input and display unit changes - LaunchedEffect(input, primaryDisplay) { + LaunchedEffect(input) { //TODO HANDLE PRIMARY DISPLAY CHANGE when (primaryDisplay) { PrimaryDisplay.BITCOIN -> { - // When primary display is Bitcoin satsValue += input -// largeRowText = input - // Convert sats to fiat for small row val sats = satsValue.toLongOrNull() ?: 0L val converted = if (rates.isNotEmpty()) currency.convert(sats = sats) else null converted?.let { val btcComponents = converted.bitcoinDisplay(displayUnit) - smallRowSymbol = it.symbol - smallRowText = "${smallRowSymbol} ${converted.formatted}" - largeRowText = btcComponents.value + smallRowSymbol = converted.symbol + smallRowText = converted.formatted largeRowSymbol = btcComponents.symbol + largeRowText = btcComponents.value } } PrimaryDisplay.FIAT -> { - // When primary display is Fiat fiatValue += input - val converted = if (rates.isNotEmpty()) currency.convertFiatToSats(fiatAmount = (fiatValue + input).toDoubleOrNull() ?: 0.0) else null converted?.let { - largeRowText = fiatValue - largeRowSymbol = "$" - - // Convert fiat to sats for small row satsValue = it.toString() smallRowSymbol = "B" - smallRowText = "$smallRowSymbol $satsValue" + smallRowText = satsValue + largeRowSymbol = "$" + largeRowText = fiatValue } } } - // Trigger callback with sats value onSatsChanged(satsValue) } BalanceHeader( modifier = modifier, smallRowPrefix = smallRowPrefix, + smallRowSymbol = smallRowSymbol, smallRowText = smallRowText, largeRowPrefix = largeRowPrefix, largeRowText = largeRowText, @@ -148,6 +140,7 @@ fun BalanceHeaderEditable( @Composable fun BalanceHeader( smallRowPrefix: String? = null, + smallRowSymbol: String? = null, smallRowText: String, largeRowPrefix: String? = null, largeRowText: String, @@ -163,6 +156,7 @@ fun BalanceHeader( ) { SmallRow( prefix = smallRowPrefix, + symbol = smallRowSymbol, text = smallRowText ) @@ -201,7 +195,7 @@ fun LargeRow(prefix: String?, text: String, symbol: String, showSymbol: Boolean) } @Composable -private fun SmallRow(prefix: String?, text: String) { +private fun SmallRow(prefix: String?, symbol: String?, text: String) { Row( verticalAlignment = Alignment.Bottom, horizontalArrangement = Arrangement.spacedBy(4.dp), @@ -212,6 +206,12 @@ private fun SmallRow(prefix: String?, text: String) { color = Colors.White64, ) } + if (symbol != null) { + Caption13Up( + text = symbol, + color = Colors.White64, + ) + } Caption13Up( text = text, color = Colors.White64, diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt index 8b4f2adf1..c202a0e51 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt @@ -10,6 +10,10 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -18,6 +22,7 @@ import to.bitkit.R import to.bitkit.models.PrimaryDisplay import to.bitkit.ui.LocalBalances import to.bitkit.ui.LocalCurrencies +import to.bitkit.ui.components.BalanceHeaderEditable import to.bitkit.ui.components.BalanceHeaderView import to.bitkit.ui.components.Keyboard import to.bitkit.ui.components.MoneySSB @@ -49,10 +54,17 @@ fun SendAmountScreen( onEvent(SendEvent.AmountReset) onBack() } + + var input: String by remember { mutableStateOf("") } + Column( modifier = Modifier.padding(horizontal = 16.dp) ) { - BalanceHeaderView(sats = uiState.amountInput.toLong(), modifier = Modifier.fillMaxWidth()) + BalanceHeaderEditable( + input = input, + onSatsChanged = { number -> onEvent(SendEvent.AmountChange(number)) }, + modifier = Modifier.fillMaxWidth() + ) Spacer(modifier = Modifier.height(24.dp)) @@ -105,7 +117,7 @@ fun SendAmountScreen( HorizontalDivider(modifier = Modifier.padding(vertical = 24.dp)) Keyboard( - onClick = { number -> onEvent(SendEvent.AmountChange(number)) }, + onClick = { number -> input = number }, isDecimal = currencyUiState.primaryDisplay == PrimaryDisplay.FIAT, modifier = Modifier.fillMaxWidth(), ) diff --git a/app/src/main/java/to/bitkit/viewmodels/CurrencyViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/CurrencyViewModel.kt index 0bb02ef06..817b31729 100644 --- a/app/src/main/java/to/bitkit/viewmodels/CurrencyViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/CurrencyViewModel.kt @@ -160,6 +160,7 @@ class CurrencyViewModel @Inject constructor( } // UI Helpers + /**Convert sats fo fiat*/ fun convert(sats: Long, currency: String? = null): ConvertedAmount? { val targetCurrency = currency ?: uiState.value.selectedCurrency val rate = currencyService.getCurrentRate(targetCurrency, uiState.value.rates) From 43bc75ec07d2aa8a9b68e20dc34d3d5d63751320 Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Thu, 27 Mar 2025 08:07:19 -0300 Subject: [PATCH 6/7] fix: state update WIP --- .../bitkit/ui/components/BalanceHeaderView.kt | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt index ab9f7f814..38fe75e4c 100644 --- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt +++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt @@ -10,6 +10,9 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableDoubleStateOf +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -19,11 +22,13 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import to.bitkit.models.ConvertedAmount import to.bitkit.models.PrimaryDisplay +import to.bitkit.models.formatSats import to.bitkit.ui.LocalCurrencies import to.bitkit.ui.currencyViewModel import to.bitkit.ui.shared.util.clickableAlpha import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.theme.Colors +import to.bitkit.ui.utils.formatFiat @Composable fun BalanceHeaderView( @@ -78,8 +83,8 @@ fun BalanceHeaderEditable( val (rates, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies.current val currency = currencyViewModel ?: return - var satsValue: String by remember { mutableStateOf("") } - var fiatValue: String by remember { mutableStateOf("") } + var satsValue: Long by remember { mutableLongStateOf(0L) } + var fiatValue: Double by remember { mutableDoubleStateOf(0.0) } var smallRowPrefix: String by remember { mutableStateOf("") } var smallRowText: String by remember { mutableStateOf("") } @@ -89,18 +94,17 @@ fun BalanceHeaderEditable( var largeRowText: String by remember { mutableStateOf("") } var largeRowSymbol: String by remember { mutableStateOf("") } - - LaunchedEffect(input) { //TODO HANDLE PRIMARY DISPLAY CHANGE when (primaryDisplay) { PrimaryDisplay.BITCOIN -> { - satsValue += input - val sats = satsValue.toLongOrNull() ?: 0L + (satsValue.toString() + input).toLongOrNull()?.let { updatedValue -> + satsValue = updatedValue + } - val converted = if (rates.isNotEmpty()) currency.convert(sats = sats) else null + val converted = currency.convert(sats = satsValue) converted?.let { - val btcComponents = converted.bitcoinDisplay(displayUnit) + val btcComponents = satsValue.formatSats(displayUnit) smallRowSymbol = converted.symbol smallRowText = converted.formatted largeRowSymbol = btcComponents.symbol @@ -108,20 +112,24 @@ fun BalanceHeaderEditable( } } PrimaryDisplay.FIAT -> { - fiatValue += input - val converted = if (rates.isNotEmpty()) currency.convertFiatToSats(fiatAmount = (fiatValue + input).toDoubleOrNull() ?: 0.0) else null + //CHECK IF HAS VALUE AFTER DOTS + (if (fiatValue == 0.0) input else (fiatValue.toString() + input)).toDoubleOrNull()?.let { updatedValue -> + fiatValue = updatedValue + } + val converted = currency.convertFiatToSats(fiatAmount = fiatValue) converted?.let { - satsValue = it.toString() - smallRowSymbol = "B" - smallRowText = satsValue + val btcValues = converted.formatSats() + satsValue = it + smallRowSymbol = btcValues.symbol + smallRowText = btcValues.value largeRowSymbol = "$" - largeRowText = fiatValue + largeRowText = fiatValue.toString() } } } - onSatsChanged(satsValue) + onSatsChanged(satsValue.toString()) } BalanceHeader( From 30b4e1ed82187d1e0cf856851acb3800d93254da Mon Sep 17 00:00:00 2001 From: Joao Victor Sena Date: Thu, 27 Mar 2025 08:08:24 -0300 Subject: [PATCH 7/7] refactor: create a formatSats method independent of ConvertedAmount class --- .../main/java/to/bitkit/models/Currency.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/src/main/java/to/bitkit/models/Currency.kt b/app/src/main/java/to/bitkit/models/Currency.kt index 7718b310d..784b0499e 100644 --- a/app/src/main/java/to/bitkit/models/Currency.kt +++ b/app/src/main/java/to/bitkit/models/Currency.kt @@ -2,6 +2,7 @@ package to.bitkit.models import kotlinx.datetime.Instant import kotlinx.serialization.Serializable +import to.bitkit.models.ConvertedAmount.BitcoinDisplayComponents import java.math.BigDecimal import java.text.DecimalFormat import java.text.DecimalFormatSymbols @@ -79,6 +80,31 @@ data class ConvertedAmount( } } +/** Format sats to modern or classic format*/ +fun Long.formatSats(unit: BitcoinDisplayUnit = BitcoinDisplayUnit.MODERN): BitcoinDisplayComponents { + val symbol = "₿" + val spaceSeparator = ' ' + val formattedValue = when (unit) { + BitcoinDisplayUnit.MODERN -> { + this.formatToModernDisplay() + } + + BitcoinDisplayUnit.CLASSIC -> { + val formatSymbols = DecimalFormatSymbols(Locale.getDefault()).apply { + groupingSeparator = spaceSeparator + } + val formatter = DecimalFormat("#,###.########", formatSymbols) + val btcValue: BigDecimal = BigDecimal(this).divide(BigDecimal(100_000_000)) + formatter.format(btcValue) + } + } + return BitcoinDisplayComponents( + symbol = symbol, + value = formattedValue, + ) +} + + fun Long.formatToModernDisplay(): String { val sats = this val formatSymbols = DecimalFormatSymbols(Locale.getDefault()).apply {