[#1047] Consistent Zatoshi amounts representation
* [#1047] Consistent Zatoshi amounts representation - Closes #1047 - Tests - Changelog update * Address review comment
This commit is contained in:
parent
b53eda1347
commit
e1ab2e2af6
|
@ -9,6 +9,9 @@ directly impact users rather than highlighting other key architectural updates.*
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Proper ZEC amount abbreviation has been added across the entire app as described by the design document
|
||||||
|
|
||||||
## [1.1.2 (676)] - 2024-06-24
|
## [1.1.2 (676)] - 2024-06-24
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package cash.z.ecc.sdk.extension
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
||||||
|
import cash.z.ecc.android.sdk.model.Zatoshi.Companion.ZATOSHI_PER_ZEC
|
||||||
|
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class ZatoshiExtTest {
|
||||||
|
@Test
|
||||||
|
@SmallTest
|
||||||
|
fun to_zec_string_full_basic_test() {
|
||||||
|
val input = ZatoshiFixture.new(ZATOSHI_PER_ZEC)
|
||||||
|
|
||||||
|
val output = input.toZecStringFull()
|
||||||
|
|
||||||
|
assertEquals("1${MonetarySeparators.current().decimal}000", output)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SmallTest
|
||||||
|
fun to_zec_string_full_decimals_test() {
|
||||||
|
val input = ZatoshiFixture.new((1.12345678 * ZATOSHI_PER_ZEC).toLong())
|
||||||
|
|
||||||
|
val output = input.toZecStringFull()
|
||||||
|
|
||||||
|
assertEquals("1${MonetarySeparators.current().decimal}12345678", output)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SmallTest
|
||||||
|
fun to_zec_string_abbreviated_suffix_no_dots_no_decimals_test() {
|
||||||
|
val input = ZatoshiFixture.new(ZATOSHI_PER_ZEC)
|
||||||
|
|
||||||
|
val output = input.toZecStringAbbreviated("...")
|
||||||
|
|
||||||
|
assertEquals("1${MonetarySeparators.current().decimal}000", output.main)
|
||||||
|
assertNotEquals("...", output.suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SmallTest
|
||||||
|
fun to_zec_string_abbreviated_suffix_no_dots_some_decimals_test() {
|
||||||
|
val input = ZatoshiFixture.new((1.12345678 * ZATOSHI_PER_ZEC).toLong())
|
||||||
|
|
||||||
|
val output = input.toZecStringAbbreviated("...")
|
||||||
|
|
||||||
|
assertEquals("1${MonetarySeparators.current().decimal}123", output.main)
|
||||||
|
assertNotEquals("...", output.suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SmallTest
|
||||||
|
fun to_zec_string_abbreviated_suffix_has_dots_test() {
|
||||||
|
val input = ZatoshiFixture.new((0.000123456 * ZATOSHI_PER_ZEC).toLong())
|
||||||
|
|
||||||
|
val output = input.toZecStringAbbreviated("...")
|
||||||
|
|
||||||
|
assertEquals("0${MonetarySeparators.current().decimal}000", output.main)
|
||||||
|
assertEquals("...", output.suffix)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package cash.z.ecc.sdk.extension
|
||||||
|
|
||||||
|
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
||||||
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
|
||||||
|
private const val DECIMALS_MAX_LONG = 8
|
||||||
|
private const val DECIMALS_MIN_LONG = 3
|
||||||
|
|
||||||
|
private const val DECIMALS_SHORT = 3
|
||||||
|
|
||||||
|
private const val MIN_ZATOSHI_FOR_DOTS_SHORT = Zatoshi.ZATOSHI_PER_ZEC / 1000
|
||||||
|
|
||||||
|
fun Zatoshi.toZecStringFull() =
|
||||||
|
convertZatoshiToZecString(
|
||||||
|
maxDecimals = DECIMALS_MAX_LONG,
|
||||||
|
minDecimals = DECIMALS_MIN_LONG
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Zatoshi.toZecStringAbbreviated(suffix: String): ZecAmountPair {
|
||||||
|
val checkedSuffix =
|
||||||
|
if (value in 1..<MIN_ZATOSHI_FOR_DOTS_SHORT) {
|
||||||
|
suffix
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
return convertZatoshiToZecString(
|
||||||
|
minDecimals = DECIMALS_SHORT,
|
||||||
|
maxDecimals = DECIMALS_SHORT
|
||||||
|
).let { mainPart ->
|
||||||
|
ZecAmountPair(
|
||||||
|
main = mainPart,
|
||||||
|
suffix = checkedSuffix
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val DEFAULT_LESS_THAN_FEE = 100_000L
|
||||||
|
|
||||||
|
val DEFAULT_FEE: String
|
||||||
|
get() = Zatoshi(DEFAULT_LESS_THAN_FEE).toZecStringFull()
|
||||||
|
|
||||||
|
data class ZecAmountPair(
|
||||||
|
val main: String,
|
||||||
|
val suffix: String
|
||||||
|
)
|
|
@ -0,0 +1,138 @@
|
||||||
|
package co.electriccoin.zcash.ui.design.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.basicMarquee
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.withStyle
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
||||||
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun StyledBalanceComposablePreview() {
|
||||||
|
ZcashTheme(forceDarkMode = false) {
|
||||||
|
BlankSurface {
|
||||||
|
Column {
|
||||||
|
StyledBalance(
|
||||||
|
balanceParts = ZecAmountTriple(main = "1,234.56789012"),
|
||||||
|
textStyles =
|
||||||
|
Pair(
|
||||||
|
ZcashTheme.extendedTypography.balanceWidgetStyles.first,
|
||||||
|
ZcashTheme.extendedTypography.balanceWidgetStyles.second
|
||||||
|
),
|
||||||
|
modifier = Modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This accepts string with balance and displays it in the UI component styled according to the design
|
||||||
|
* requirements. The function displays the balance within two parts.
|
||||||
|
*
|
||||||
|
* @param balanceParts [ZecAmountTriple] class that holds balance parts
|
||||||
|
* @param textStyles Styles for the first and second part of the balance
|
||||||
|
* @param textColor Optional color to modify the default font color from [textStyles]
|
||||||
|
* @param modifier Modifier to modify the Text UI element as needed
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun StyledBalance(
|
||||||
|
balanceParts: ZecAmountTriple,
|
||||||
|
textStyles: Pair<TextStyle, TextStyle>,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
textColor: Color? = null,
|
||||||
|
) {
|
||||||
|
val balanceSplit = splitBalance(balanceParts)
|
||||||
|
|
||||||
|
val content =
|
||||||
|
buildAnnotatedString {
|
||||||
|
withStyle(
|
||||||
|
style = textStyles.first.toSpanStyle()
|
||||||
|
) {
|
||||||
|
append(balanceSplit.first)
|
||||||
|
}
|
||||||
|
withStyle(
|
||||||
|
style = textStyles.second.toSpanStyle()
|
||||||
|
) {
|
||||||
|
append(balanceSplit.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textColor != null) {
|
||||||
|
Text(
|
||||||
|
text = content,
|
||||||
|
color = textColor,
|
||||||
|
maxLines = 1,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.basicMarquee()
|
||||||
|
.then(modifier)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
text = content,
|
||||||
|
maxLines = 1,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.basicMarquee()
|
||||||
|
.then(modifier)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val CUT_POSITION_OFFSET = 4
|
||||||
|
|
||||||
|
private fun splitBalance(balanceStringParts: ZecAmountTriple): Pair<String, String> {
|
||||||
|
Twig.debug { "Balance parts before calculation: $balanceStringParts" }
|
||||||
|
|
||||||
|
val cutPosition =
|
||||||
|
balanceStringParts.main.indexOf(
|
||||||
|
startIndex = 0,
|
||||||
|
char = MonetarySeparators.current(Locale.getDefault()).decimal,
|
||||||
|
ignoreCase = true
|
||||||
|
).let { separatorPosition ->
|
||||||
|
if (separatorPosition + CUT_POSITION_OFFSET < balanceStringParts.main.length) {
|
||||||
|
separatorPosition + CUT_POSITION_OFFSET
|
||||||
|
} else {
|
||||||
|
balanceStringParts.main.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val firstPart =
|
||||||
|
buildString {
|
||||||
|
append(balanceStringParts.prefix ?: "")
|
||||||
|
append(
|
||||||
|
balanceStringParts.main.substring(
|
||||||
|
startIndex = 0,
|
||||||
|
endIndex = cutPosition
|
||||||
|
)
|
||||||
|
)
|
||||||
|
append(balanceStringParts.suffix ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
val secondPart =
|
||||||
|
balanceStringParts.main.substring(
|
||||||
|
startIndex = cutPosition
|
||||||
|
)
|
||||||
|
|
||||||
|
Twig.debug { "Balance after split: $firstPart|$secondPart" }
|
||||||
|
|
||||||
|
return Pair(firstPart, secondPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ZecAmountTriple(
|
||||||
|
val main: String,
|
||||||
|
val prefix: String? = null,
|
||||||
|
val suffix: String? = null
|
||||||
|
)
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
package co.electriccoin.zcash.ui.design.component
|
package co.electriccoin.zcash.ui.design.component
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.basicMarquee
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
@ -26,18 +24,13 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextDecoration
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.text.withStyle
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -67,26 +60,6 @@ private fun ReferenceComposablePreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun StyledBalanceComposablePreview() {
|
|
||||||
ZcashTheme(forceDarkMode = false) {
|
|
||||||
BlankSurface {
|
|
||||||
Column {
|
|
||||||
StyledBalance(
|
|
||||||
balanceString = "1,234.56789012",
|
|
||||||
textStyles =
|
|
||||||
Pair(
|
|
||||||
ZcashTheme.extendedTypography.balanceWidgetStyles.first,
|
|
||||||
ZcashTheme.extendedTypography.balanceWidgetStyles.second
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add previews for the rest of the composables
|
// Add previews for the rest of the composables
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -324,86 +297,6 @@ fun Reference(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This accepts string with balance and displays it in the UI component styled according to the design
|
|
||||||
* requirements. The function displays the balance within two parts.
|
|
||||||
*
|
|
||||||
* @param balanceString String of Zcash formatted balance
|
|
||||||
* @param textStyles Styles for the first and second part of the balance
|
|
||||||
* @param textColor Optional color to modify the default font color from [textStyles]
|
|
||||||
* @param modifier Modifier to modify the Text UI element as needed
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
@Composable
|
|
||||||
fun StyledBalance(
|
|
||||||
balanceString: String,
|
|
||||||
textStyles: Pair<TextStyle, TextStyle>,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
textColor: Color? = null,
|
|
||||||
prefix: String? = null
|
|
||||||
) {
|
|
||||||
val balanceSplit = splitBalance(balanceString, prefix)
|
|
||||||
|
|
||||||
val content =
|
|
||||||
buildAnnotatedString {
|
|
||||||
withStyle(
|
|
||||||
style = textStyles.first.toSpanStyle()
|
|
||||||
) {
|
|
||||||
append(balanceSplit.first)
|
|
||||||
}
|
|
||||||
withStyle(
|
|
||||||
style = textStyles.second.toSpanStyle()
|
|
||||||
) {
|
|
||||||
append(balanceSplit.second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textColor != null) {
|
|
||||||
Text(
|
|
||||||
text = content,
|
|
||||||
color = textColor,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.basicMarquee()
|
|
||||||
.then(modifier)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Text(
|
|
||||||
text = content,
|
|
||||||
maxLines = 1,
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.basicMarquee()
|
|
||||||
.then(modifier)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun splitBalance(
|
|
||||||
balance: String,
|
|
||||||
prefix: String?
|
|
||||||
): Pair<String, String> {
|
|
||||||
Twig.debug { "Balance before split: $balance, prefix: $prefix" }
|
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
|
||||||
val cutPosition = balance.indexOf(MonetarySeparators.current(Locale.getDefault()).decimal) + 4
|
|
||||||
val firstPart =
|
|
||||||
(prefix ?: "") +
|
|
||||||
balance.substring(
|
|
||||||
startIndex = 0,
|
|
||||||
endIndex = cutPosition
|
|
||||||
)
|
|
||||||
val secondPart =
|
|
||||||
balance.substring(
|
|
||||||
startIndex = cutPosition
|
|
||||||
)
|
|
||||||
|
|
||||||
Twig.debug { "Balance after split: $firstPart|$secondPart" }
|
|
||||||
|
|
||||||
return Pair(firstPart, secondPart)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BodyWithFiatCurrencySymbol(
|
fun BodyWithFiatCurrencySymbol(
|
||||||
amount: String,
|
amount: String,
|
||||||
|
|
|
@ -19,14 +19,16 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.tooling.preview.Devices
|
import androidx.compose.ui.tooling.preview.Devices
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.toZecString
|
import cash.z.ecc.sdk.extension.toZecStringFull
|
||||||
import cash.z.ecc.sdk.type.ZcashCurrency
|
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||||
|
import co.electriccoin.zcash.ui.common.extension.asZecAmountTriple
|
||||||
import co.electriccoin.zcash.ui.design.R
|
import co.electriccoin.zcash.ui.design.R
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
import co.electriccoin.zcash.ui.design.component.Body
|
import co.electriccoin.zcash.ui.design.component.Body
|
||||||
import co.electriccoin.zcash.ui.design.component.CircularSmallProgressIndicator
|
import co.electriccoin.zcash.ui.design.component.CircularSmallProgressIndicator
|
||||||
import co.electriccoin.zcash.ui.design.component.Reference
|
import co.electriccoin.zcash.ui.design.component.Reference
|
||||||
import co.electriccoin.zcash.ui.design.component.StyledBalance
|
import co.electriccoin.zcash.ui.design.component.StyledBalance
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ZecAmountTriple
|
||||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||||
|
|
||||||
@Preview(device = Devices.PIXEL_2)
|
@Preview(device = Devices.PIXEL_2)
|
||||||
|
@ -94,7 +96,7 @@ fun BalanceWidget(
|
||||||
.then(modifier),
|
.then(modifier),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
BalanceWidgetBigLineOnly(text = balanceState.totalBalance.toZecString())
|
BalanceWidgetBigLineOnly(parts = balanceState.totalBalance.toZecStringFull().asZecAmountTriple())
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
@ -132,7 +134,7 @@ fun BalanceWidget(
|
||||||
}
|
}
|
||||||
is BalanceState.Available -> {
|
is BalanceState.Available -> {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = balanceState.spendableBalance.toZecString(),
|
balanceParts = balanceState.spendableBalance.toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceWidgetStyles.third,
|
ZcashTheme.extendedTypography.balanceWidgetStyles.third,
|
||||||
|
@ -154,7 +156,7 @@ fun BalanceWidget(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BalanceWidgetBigLineOnly(
|
fun BalanceWidgetBigLineOnly(
|
||||||
text: String,
|
parts: ZecAmountTriple,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
@ -162,7 +164,7 @@ fun BalanceWidgetBigLineOnly(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = text,
|
balanceParts = parts,
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceWidgetStyles.first,
|
ZcashTheme.extendedTypography.balanceWidgetStyles.first,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package co.electriccoin.zcash.ui.common.extension
|
||||||
|
|
||||||
|
import cash.z.ecc.sdk.extension.ZecAmountPair
|
||||||
|
import co.electriccoin.zcash.ui.design.component.ZecAmountTriple
|
||||||
|
|
||||||
|
fun ZecAmountPair.asZecAmountTriple(prefix: String? = null) =
|
||||||
|
ZecAmountTriple(
|
||||||
|
main = main,
|
||||||
|
suffix = suffix,
|
||||||
|
prefix = prefix
|
||||||
|
)
|
||||||
|
|
||||||
|
fun String.asZecAmountTriple(prefix: String? = null) =
|
||||||
|
ZecAmountTriple(
|
||||||
|
main = this,
|
||||||
|
prefix = prefix
|
||||||
|
)
|
|
@ -5,5 +5,7 @@ enum class TrxItemState {
|
||||||
EXPANDED,
|
EXPANDED,
|
||||||
EXPANDED_ADDRESS,
|
EXPANDED_ADDRESS,
|
||||||
EXPANDED_ID,
|
EXPANDED_ID,
|
||||||
EXPANDED_ALL,
|
EXPANDED_ALL;
|
||||||
|
|
||||||
|
fun isInAnyExtendedState() = this >= EXPANDED
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,13 @@ import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||||
import cash.z.ecc.android.sdk.model.TransactionState
|
import cash.z.ecc.android.sdk.model.TransactionState
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.model.toZecString
|
|
||||||
import cash.z.ecc.android.sdk.type.AddressType
|
import cash.z.ecc.android.sdk.type.AddressType
|
||||||
|
import cash.z.ecc.sdk.extension.DEFAULT_FEE
|
||||||
|
import cash.z.ecc.sdk.extension.toZecStringAbbreviated
|
||||||
|
import cash.z.ecc.sdk.extension.toZecStringFull
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.SynchronizationStatus
|
import co.electriccoin.zcash.ui.common.compose.SynchronizationStatus
|
||||||
|
import co.electriccoin.zcash.ui.common.extension.asZecAmountTriple
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
import co.electriccoin.zcash.ui.design.component.BlankSurface
|
||||||
|
@ -67,7 +70,6 @@ import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
|
||||||
import co.electriccoin.zcash.ui.screen.account.model.TrxItemState
|
import co.electriccoin.zcash.ui.screen.account.model.TrxItemState
|
||||||
import co.electriccoin.zcash.ui.screen.balances.BalancesTag
|
import co.electriccoin.zcash.ui.screen.balances.BalancesTag
|
||||||
import co.electriccoin.zcash.ui.screen.balances.model.StatusAction
|
import co.electriccoin.zcash.ui.screen.balances.model.StatusAction
|
||||||
import co.electriccoin.zcash.ui.screen.send.view.DEFAULT_LESS_THAN_FEE
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
|
@ -398,7 +400,7 @@ private fun HistoryItem(
|
||||||
|
|
||||||
HistoryItemDatePart(transaction)
|
HistoryItemDatePart(transaction)
|
||||||
|
|
||||||
if (transaction.expandableState >= TrxItemState.EXPANDED) {
|
if (transaction.expandableState.isInAnyExtendedState()) {
|
||||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
||||||
|
|
||||||
HistoryItemExpandedPart(onAction, transaction)
|
HistoryItemExpandedPart(onAction, transaction)
|
||||||
|
@ -457,22 +459,28 @@ private fun HistoryItemCollapsedMainPart(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO [#1047]: Representing Zatoshi amount
|
val prefix =
|
||||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
if (transaction.overview.isSentTransaction) {
|
||||||
|
stringResource(id = R.string.account_history_item_sent_prefix)
|
||||||
|
} else {
|
||||||
|
stringResource(id = R.string.account_history_item_received_prefix)
|
||||||
|
}
|
||||||
|
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = transaction.overview.netValue.toZecString(),
|
balanceParts =
|
||||||
|
if (transaction.expandableState.isInAnyExtendedState()) {
|
||||||
|
transaction.overview.netValue.toZecStringFull().asZecAmountTriple(prefix)
|
||||||
|
} else {
|
||||||
|
transaction.overview.netValue.toZecStringAbbreviated(
|
||||||
|
suffix = stringResource(id = R.string.general_etc)
|
||||||
|
).asZecAmountTriple(prefix)
|
||||||
|
},
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
first = valueTextStyle,
|
first = valueTextStyle,
|
||||||
second = ZcashTheme.extendedTypography.transactionItemStyles.valueSecondPart
|
second = ZcashTheme.extendedTypography.transactionItemStyles.valueSecondPart
|
||||||
),
|
),
|
||||||
textColor = valueTextColor,
|
textColor = valueTextColor,
|
||||||
prefix =
|
|
||||||
if (transaction.overview.isSentTransaction) {
|
|
||||||
stringResource(id = R.string.account_history_item_sent_prefix)
|
|
||||||
} else {
|
|
||||||
stringResource(id = R.string.account_history_item_received_prefix)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,7 +716,7 @@ private fun HistoryItemTransactionIdPart(
|
||||||
color = ZcashTheme.colors.textDescription,
|
color = ZcashTheme.colors.textDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingXtiny))
|
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingTiny))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = txIdString,
|
text = txIdString,
|
||||||
|
@ -789,23 +797,21 @@ private fun HistoryItemTransactionFeePart(
|
||||||
color = ZcashTheme.colors.textDescription,
|
color = ZcashTheme.colors.textDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingSmall))
|
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingTiny))
|
||||||
|
|
||||||
if (fee == null) {
|
if (fee == null) {
|
||||||
Text(
|
Text(
|
||||||
text =
|
text =
|
||||||
stringResource(
|
stringResource(
|
||||||
id = R.string.account_history_item_transaction_fee_typical,
|
id = R.string.account_history_item_transaction_fee_typical,
|
||||||
Zatoshi(DEFAULT_LESS_THAN_FEE).toZecString()
|
DEFAULT_FEE
|
||||||
),
|
),
|
||||||
style = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
style = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
||||||
color = ZcashTheme.colors.textDescription,
|
color = ZcashTheme.colors.textDescription,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// TODO [#1047]: Representing Zatoshi amount
|
|
||||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = fee.toZecString(),
|
balanceParts = fee.toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
first = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
first = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
||||||
|
|
|
@ -47,16 +47,16 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
|
||||||
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
|
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.sdk.extension.DEFAULT_FEE
|
||||||
import cash.z.ecc.android.sdk.model.toZecString
|
import cash.z.ecc.sdk.extension.toZecStringFull
|
||||||
import cash.z.ecc.sdk.type.ZcashCurrency
|
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
import co.electriccoin.zcash.ui.common.compose.BalanceState
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceWidget
|
import co.electriccoin.zcash.ui.common.compose.BalanceWidget
|
||||||
import co.electriccoin.zcash.ui.common.compose.StatusDialog
|
import co.electriccoin.zcash.ui.common.compose.StatusDialog
|
||||||
import co.electriccoin.zcash.ui.common.compose.SynchronizationStatus
|
import co.electriccoin.zcash.ui.common.compose.SynchronizationStatus
|
||||||
|
import co.electriccoin.zcash.ui.common.extension.asZecAmountTriple
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
|
||||||
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
|
||||||
|
@ -410,9 +410,7 @@ fun TransparentBalancePanel(
|
||||||
text =
|
text =
|
||||||
stringResource(
|
stringResource(
|
||||||
id = R.string.balances_transparent_balance_fee,
|
id = R.string.balances_transparent_balance_fee,
|
||||||
// TODO [#1047]: Representing Zatoshi amount
|
DEFAULT_FEE
|
||||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
|
||||||
Zatoshi(DEFAULT_LESS_THAN_FEE).convertZatoshiToZecString(maxDecimals = 3)
|
|
||||||
),
|
),
|
||||||
textFontWeight = FontWeight.SemiBold
|
textFontWeight = FontWeight.SemiBold
|
||||||
)
|
)
|
||||||
|
@ -467,7 +465,7 @@ fun TransparentBalanceRow(
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = walletSnapshot.transparentBalance.toZecString(),
|
balanceParts = walletSnapshot.transparentBalance.toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
||||||
|
@ -589,7 +587,7 @@ fun SpendableBalanceRow(walletSnapshot: WalletSnapshot) {
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = walletSnapshot.spendableBalance().toZecString(),
|
balanceParts = walletSnapshot.spendableBalance().toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
||||||
|
@ -624,7 +622,7 @@ fun ChangePendingRow(walletSnapshot: WalletSnapshot) {
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = walletSnapshot.changePendingBalance().toZecString(),
|
balanceParts = walletSnapshot.changePendingBalance().toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
||||||
|
@ -658,7 +656,7 @@ fun PendingTransactionsRow(walletSnapshot: WalletSnapshot) {
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
StyledBalance(
|
StyledBalance(
|
||||||
balanceString = walletSnapshot.valuePendingBalance().toZecString(),
|
balanceParts = walletSnapshot.valuePendingBalance().toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
||||||
|
|
|
@ -46,13 +46,12 @@ import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
|
||||||
import cash.z.ecc.android.sdk.model.Memo
|
import cash.z.ecc.android.sdk.model.Memo
|
||||||
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
import cash.z.ecc.android.sdk.model.MonetarySeparators
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
|
||||||
import cash.z.ecc.android.sdk.model.ZecSend
|
import cash.z.ecc.android.sdk.model.ZecSend
|
||||||
import cash.z.ecc.android.sdk.model.ZecSendExt
|
import cash.z.ecc.android.sdk.model.ZecSendExt
|
||||||
import cash.z.ecc.android.sdk.type.AddressType
|
import cash.z.ecc.android.sdk.type.AddressType
|
||||||
|
import cash.z.ecc.sdk.extension.DEFAULT_FEE
|
||||||
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||||
import cash.z.ecc.sdk.type.ZcashCurrency
|
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||||
import co.electriccoin.zcash.spackle.Twig
|
import co.electriccoin.zcash.spackle.Twig
|
||||||
|
@ -276,8 +275,6 @@ private fun SendMainContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const val DEFAULT_LESS_THAN_FEE = 100_000L
|
|
||||||
|
|
||||||
// TODO [#217]: Need to handle changing of Locale after user input, but before submitting the button.
|
// TODO [#217]: Need to handle changing of Locale after user input, but before submitting the button.
|
||||||
// TODO [#217]: https://github.com/Electric-Coin-Company/zashi-android/issues/217
|
// TODO [#217]: https://github.com/Electric-Coin-Company/zashi-android/issues/217
|
||||||
|
|
||||||
|
@ -463,9 +460,7 @@ fun SendButton(
|
||||||
text =
|
text =
|
||||||
stringResource(
|
stringResource(
|
||||||
id = R.string.send_fee,
|
id = R.string.send_fee,
|
||||||
// TODO [#1047]: Representing Zatoshi amount
|
DEFAULT_FEE
|
||||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
|
||||||
Zatoshi(DEFAULT_LESS_THAN_FEE).convertZatoshiToZecString(maxDecimals = 3)
|
|
||||||
),
|
),
|
||||||
textFontWeight = FontWeight.SemiBold,
|
textFontWeight = FontWeight.SemiBold,
|
||||||
modifier =
|
modifier =
|
||||||
|
|
|
@ -35,11 +35,12 @@ import cash.z.ecc.android.sdk.fixture.WalletAddressFixture
|
||||||
import cash.z.ecc.android.sdk.model.FirstClassByteArray
|
import cash.z.ecc.android.sdk.model.FirstClassByteArray
|
||||||
import cash.z.ecc.android.sdk.model.TransactionSubmitResult
|
import cash.z.ecc.android.sdk.model.TransactionSubmitResult
|
||||||
import cash.z.ecc.android.sdk.model.ZecSend
|
import cash.z.ecc.android.sdk.model.ZecSend
|
||||||
import cash.z.ecc.android.sdk.model.toZecString
|
import cash.z.ecc.sdk.extension.toZecStringFull
|
||||||
import cash.z.ecc.sdk.fixture.MemoFixture
|
import cash.z.ecc.sdk.fixture.MemoFixture
|
||||||
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
import cash.z.ecc.sdk.fixture.ZatoshiFixture
|
||||||
import co.electriccoin.zcash.ui.R
|
import co.electriccoin.zcash.ui.R
|
||||||
import co.electriccoin.zcash.ui.common.compose.BalanceWidgetBigLineOnly
|
import co.electriccoin.zcash.ui.common.compose.BalanceWidgetBigLineOnly
|
||||||
|
import co.electriccoin.zcash.ui.common.extension.asZecAmountTriple
|
||||||
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
|
||||||
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
|
||||||
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
import co.electriccoin.zcash.ui.design.component.AppAlertDialog
|
||||||
|
@ -370,7 +371,7 @@ private fun SendConfirmationContent(
|
||||||
|
|
||||||
Small(stringResource(R.string.send_confirmation_amount))
|
Small(stringResource(R.string.send_confirmation_amount))
|
||||||
|
|
||||||
BalanceWidgetBigLineOnly(text = zecSend.amount.toZecString())
|
BalanceWidgetBigLineOnly(parts = zecSend.amount.toZecStringFull().asZecAmountTriple())
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
||||||
|
|
||||||
|
@ -390,7 +391,7 @@ private fun SendConfirmationContent(
|
||||||
// The not-null assertion operator is necessary here even if we check its nullability before
|
// The not-null assertion operator is necessary here even if we check its nullability before
|
||||||
// due to: "Smart cast to 'Proposal' is impossible, because 'zecSend.proposal' is a public API
|
// due to: "Smart cast to 'Proposal' is impossible, because 'zecSend.proposal' is a public API
|
||||||
// property declared in different module. See more details on the Kotlin forum.
|
// property declared in different module. See more details on the Kotlin forum.
|
||||||
balanceString = zecSend.proposal!!.totalFeeRequired().toZecString(),
|
balanceParts = zecSend.proposal!!.totalFeeRequired().toZecStringFull().asZecAmountTriple(),
|
||||||
textStyles =
|
textStyles =
|
||||||
Pair(
|
Pair(
|
||||||
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
ZcashTheme.extendedTypography.balanceSingleStyles.first,
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<!-- This is replaced by a resource overlay via app/build.gradle.kts -->
|
||||||
|
<string name="app_name">zashi-ui</string>
|
||||||
|
|
||||||
<string name="fiat_currency_conversion_rate_unavailable">Unavailable</string>
|
<string name="fiat_currency_conversion_rate_unavailable">Unavailable</string>
|
||||||
<string name="empty_char">-</string>
|
<string name="empty_char">-</string>
|
||||||
<string name="zcash_logo_content_description">Zcash logo</string>
|
<string name="zcash_logo_content_description">Zcash logo</string>
|
||||||
|
@ -17,4 +20,6 @@
|
||||||
device connection, and/or navigate to Advanced Settings to choose a different server.</string>
|
device connection, and/or navigate to Advanced Settings to choose a different server.</string>
|
||||||
<string name="server_disconnected_dialog_switch_btn">Switch Server</string>
|
<string name="server_disconnected_dialog_switch_btn">Switch Server</string>
|
||||||
<string name="server_disconnected_dialog_ignore_btn">Ignore</string>
|
<string name="server_disconnected_dialog_ignore_btn">Ignore</string>
|
||||||
|
|
||||||
|
<string name="general_etc">…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">zashi-ui</string>
|
|
||||||
|
|
||||||
<string name="onboarding_header">A no-frills wallet for sending and receiving Zcash (ZEC)</string>
|
<string name="onboarding_header">A no-frills wallet for sending and receiving Zcash (ZEC)</string>
|
||||||
|
|
||||||
<string name="onboarding_create_new_wallet">Create New Wallet</string>
|
<string name="onboarding_create_new_wallet">Create New Wallet</string>
|
||||||
|
|
Loading…
Reference in New Issue