[#1162] Partial transaction history item rework
- Zcash Android SDK v2.0.7 partially adopted. Proper implementaiton will be part of the Send screens rework. - Partially addresses #1162. More related UI changes on the transaciton history item come in a follow-up PR - `HistoryItem` composable will be reworked to several more composables as well - Also note that the history item amount still lacks proper formatting as filed in #1047 - Closes #1236 - Closes #1288 - Closes #1253
This commit is contained in:
parent
9a929c1109
commit
d076605444
|
@ -189,7 +189,7 @@ ZCASH_BIP39_VERSION=1.0.7
|
|||
ZXING_VERSION=3.5.2
|
||||
|
||||
# WARNING: Ensure a non-snapshot version is used before releasing to production.
|
||||
ZCASH_SDK_VERSION=2.0.6-SNAPSHOT
|
||||
ZCASH_SDK_VERSION=2.0.7
|
||||
|
||||
# Toolchain is the Java version used to build the application, which is separate from the
|
||||
# Java version used to run the application.
|
||||
|
|
|
@ -6,6 +6,9 @@ import cash.z.ecc.android.sdk.Synchronizer
|
|||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||
import cash.z.ecc.android.sdk.model.ZecSend
|
||||
|
||||
// TODO [#1285]: Adopt proposal API
|
||||
// TODO [#1285]: https://github.com/Electric-Coin-Company/zashi-android/issues/1285
|
||||
@Suppress("deprecation")
|
||||
suspend fun Synchronizer.send(
|
||||
spendingKey: UnifiedSpendingKey,
|
||||
send: ZecSend
|
||||
|
|
|
@ -298,9 +298,10 @@ fun StyledBalance(
|
|||
balanceString: String,
|
||||
textStyles: Pair<TextStyle, TextStyle>,
|
||||
modifier: Modifier = Modifier,
|
||||
textColor: Color? = null
|
||||
textColor: Color? = null,
|
||||
prefix: String? = null
|
||||
) {
|
||||
val balanceSplit = splitBalance(balanceString)
|
||||
val balanceSplit = splitBalance(balanceString, prefix)
|
||||
|
||||
val content =
|
||||
buildAnnotatedString {
|
||||
|
@ -338,16 +339,20 @@ fun StyledBalance(
|
|||
}
|
||||
}
|
||||
|
||||
private fun splitBalance(balance: String): Pair<String, String> {
|
||||
Twig.debug { "Balance before split: $balance" }
|
||||
private fun splitBalance(
|
||||
balance: String,
|
||||
prefix: String?
|
||||
): Pair<String, String> {
|
||||
Twig.debug { "Balance before split: $balance, prefix: $prefix" }
|
||||
|
||||
@Suppress("MAGIC_CONSTANT", "MagicNumber")
|
||||
val cutPosition = balance.indexOf(MonetarySeparators.current(Locale.US).decimal) + 4
|
||||
val firstPart =
|
||||
balance.substring(
|
||||
startIndex = 0,
|
||||
endIndex = cutPosition
|
||||
)
|
||||
(prefix ?: "") +
|
||||
balance.substring(
|
||||
startIndex = 0,
|
||||
endIndex = cutPosition
|
||||
)
|
||||
val secondPart =
|
||||
balance.substring(
|
||||
startIndex = cutPosition
|
||||
|
|
|
@ -46,6 +46,7 @@ data class ExtendedColors(
|
|||
val radioButtonColor: Color,
|
||||
val radioButtonTextColor: Color,
|
||||
val historyBackgroundColor: Color,
|
||||
val historySendColor: Color,
|
||||
) {
|
||||
@Composable
|
||||
fun surfaceGradient() =
|
||||
|
|
|
@ -32,7 +32,7 @@ internal object Dark {
|
|||
val textDescription = Color(0xFF777777)
|
||||
val textProgress = Color(0xFF8B8A8A)
|
||||
|
||||
val aboutTextColor = Color.Unspecified
|
||||
val aboutTextColor = Color(0xFF4E4E4E)
|
||||
val screenTitleColor = Color(0xFF040404)
|
||||
val welcomeAnimationColor = Color(0xFF231F20)
|
||||
val complementaryColor = Color(0xFFF4B728)
|
||||
|
@ -70,7 +70,7 @@ internal object Dark {
|
|||
val overlay = Color(0x22000000)
|
||||
val highlight = Color(0xFFFFD800)
|
||||
|
||||
val dangerous = Color(0xFFEC0008)
|
||||
val dangerous = Color(0xFFFF0B0B)
|
||||
val onDangerous = Color(0xFFFFFFFF)
|
||||
|
||||
val reference = Color(0xFFFFFFFF)
|
||||
|
@ -81,6 +81,7 @@ internal object Dark {
|
|||
val buttonShadowColor = Color(0xFFFFFFFF)
|
||||
|
||||
val historyBackgroundColor = Color(0xFFF6F6F6)
|
||||
val historySendColor = Color(0xFFF40202)
|
||||
}
|
||||
|
||||
internal object Light {
|
||||
|
@ -139,7 +140,7 @@ internal object Light {
|
|||
val overlay = Color(0x22000000)
|
||||
val highlight = Color(0xFFFFD800)
|
||||
|
||||
val dangerous = Color(0xFFEC0008)
|
||||
val dangerous = Color(0xFFFF0B0B)
|
||||
val onDangerous = Color(0xFFFFFFFF)
|
||||
|
||||
val reference = Color(0xFF000000)
|
||||
|
@ -149,6 +150,7 @@ internal object Light {
|
|||
val buttonShadowColor = Color(0xFF000000)
|
||||
|
||||
val historyBackgroundColor = Color(0xFFF6F6F6)
|
||||
val historySendColor = Color(0xFFF40202)
|
||||
}
|
||||
|
||||
internal val DarkColorPalette =
|
||||
|
@ -215,6 +217,7 @@ internal val DarkExtendedColorPalette =
|
|||
radioButtonColor = Dark.radioButtonColor,
|
||||
radioButtonTextColor = Dark.radioButtonTextColor,
|
||||
historyBackgroundColor = Dark.historyBackgroundColor,
|
||||
historySendColor = Dark.historySendColor,
|
||||
)
|
||||
|
||||
internal val LightExtendedColorPalette =
|
||||
|
@ -254,9 +257,10 @@ internal val LightExtendedColorPalette =
|
|||
darkDividerColor = Light.darkDividerColor,
|
||||
tabTextColor = Light.tabTextColor,
|
||||
panelBackgroundColor = Light.panelBackgroundColor,
|
||||
radioButtonColor = Dark.radioButtonColor,
|
||||
radioButtonTextColor = Dark.radioButtonTextColor,
|
||||
historyBackgroundColor = Dark.historyBackgroundColor,
|
||||
radioButtonColor = Light.radioButtonColor,
|
||||
radioButtonTextColor = Light.radioButtonTextColor,
|
||||
historyBackgroundColor = Light.historyBackgroundColor,
|
||||
historySendColor = Light.historySendColor,
|
||||
)
|
||||
|
||||
@Suppress("CompositionLocalAllowlist")
|
||||
|
@ -301,5 +305,6 @@ internal val LocalExtendedColors =
|
|||
radioButtonColor = Color.Unspecified,
|
||||
radioButtonTextColor = Color.Unspecified,
|
||||
historyBackgroundColor = Color.Unspecified,
|
||||
historySendColor = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,10 +6,12 @@ import androidx.compose.runtime.staticCompositionLocalOf
|
|||
import androidx.compose.ui.text.PlatformTextStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.googlefonts.Font
|
||||
import androidx.compose.ui.text.googlefonts.GoogleFont
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.sp
|
||||
import co.electriccoin.zcash.ui.design.R
|
||||
|
||||
|
@ -152,6 +154,17 @@ data class BalanceSingleTextStyles(
|
|||
val second: TextStyle,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
data class TransactionItemTextStyles(
|
||||
val titleRegular: TextStyle,
|
||||
val titleRunning: TextStyle,
|
||||
val titleFailed: TextStyle,
|
||||
val addressCollapsed: TextStyle,
|
||||
val valueFirstPart: TextStyle,
|
||||
val valueSecondPart: TextStyle,
|
||||
val date: TextStyle,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
data class ExtendedTypography(
|
||||
val listItem: TextStyle,
|
||||
|
@ -172,6 +185,8 @@ data class ExtendedTypography(
|
|||
val textNavTab: TextStyle,
|
||||
val referenceSmall: TextStyle,
|
||||
val radioButton: TextStyle,
|
||||
// Grouping transaction item text styles to a wrapper class
|
||||
val transactionItemStyles: TransactionItemTextStyles,
|
||||
)
|
||||
|
||||
@Suppress("CompositionLocalAllowlist")
|
||||
|
@ -231,10 +246,7 @@ val LocalExtendedTypography =
|
|||
)
|
||||
),
|
||||
addressStyle =
|
||||
SecondaryTypography.bodyLarge.copy(
|
||||
// TODO [#1032]: Addresses can be shown with "×" symbols
|
||||
// TODO [#1032]: https://github.com/Electric-Coin-Company/zashi-android/issues/1032
|
||||
),
|
||||
SecondaryTypography.bodyLarge.copy(),
|
||||
aboutText =
|
||||
PrimaryTypography.bodyLarge.copy(
|
||||
fontSize = 14.sp,
|
||||
|
@ -286,6 +298,42 @@ val LocalExtendedTypography =
|
|||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
),
|
||||
transactionItemStyles =
|
||||
TransactionItemTextStyles(
|
||||
titleRegular =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
titleRunning =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.ExtraBold,
|
||||
fontStyle = FontStyle.Italic
|
||||
),
|
||||
titleFailed =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.ExtraBold,
|
||||
textDecoration = TextDecoration.LineThrough
|
||||
),
|
||||
addressCollapsed =
|
||||
SecondaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp
|
||||
),
|
||||
valueFirstPart =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp
|
||||
),
|
||||
valueSecondPart =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 8.sp
|
||||
),
|
||||
date =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -7,8 +7,10 @@ import cash.z.ecc.android.sdk.block.processor.CompactBlockProcessor
|
|||
import cash.z.ecc.android.sdk.model.Account
|
||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import cash.z.ecc.android.sdk.model.Proposal
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
import cash.z.ecc.android.sdk.model.TransactionSubmitResult
|
||||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
|
@ -80,6 +82,13 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
||||
override suspend fun createProposedTransactions(
|
||||
proposal: Proposal,
|
||||
usk: UnifiedSpendingKey
|
||||
): Flow<TransactionSubmitResult> {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} yet.")
|
||||
}
|
||||
|
||||
override fun getMemos(transactionOverview: TransactionOverview): Flow<String> {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
@ -120,6 +129,24 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
||||
override suspend fun proposeShielding(
|
||||
account: Account,
|
||||
shieldingThreshold: Zatoshi,
|
||||
memo: String,
|
||||
transparentReceiver: String?
|
||||
): Proposal? {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} yet.")
|
||||
}
|
||||
|
||||
override suspend fun proposeTransfer(
|
||||
account: Account,
|
||||
recipient: String,
|
||||
amount: Zatoshi,
|
||||
memo: String
|
||||
): Proposal {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} yet.")
|
||||
}
|
||||
|
||||
override suspend fun quickRewind() {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
@ -135,6 +162,13 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
||||
replaceWith =
|
||||
ReplaceWith(
|
||||
"createProposedTransactions(proposeTransfer(usk.account, toAddress, amount, memo), usk)"
|
||||
)
|
||||
)
|
||||
override suspend fun sendToAddress(
|
||||
usk: UnifiedSpendingKey,
|
||||
amount: Zatoshi,
|
||||
|
@ -144,6 +178,13 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
return 1
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Upcoming SDK 2.1 will create multiple transactions at once for some recipients.",
|
||||
replaceWith =
|
||||
ReplaceWith(
|
||||
"proposeShielding(usk.account, shieldingThreshold, memo)?.let { createProposedTransactions(it, usk) }"
|
||||
)
|
||||
)
|
||||
override suspend fun shieldFunds(
|
||||
usk: UnifiedSpendingKey,
|
||||
memo: String
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
package co.electriccoin.zcash.ui.screen.account.history.fixture
|
||||
|
||||
import cash.z.ecc.android.sdk.fixture.TransactionOverviewFixture
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.Account
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionOverviewExt
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal object TransactionHistorySyncStateFixture {
|
||||
val TRANSACTIONS =
|
||||
persistentListOf(
|
||||
TransactionOverviewFixture.new(),
|
||||
TransactionOverviewFixture.new(),
|
||||
TransactionOverviewFixture.new()
|
||||
TransactionOverviewExt(TransactionOverviewFixture.new(), TransactionRecipient.Account(Account.DEFAULT)),
|
||||
TransactionOverviewExt(TransactionOverviewFixture.new(), TransactionRecipient.Account(Account(1))),
|
||||
TransactionOverviewExt(TransactionOverviewFixture.new(), null),
|
||||
)
|
||||
val STATE = TransactionHistorySyncState.Syncing(TRANSACTIONS)
|
||||
|
||||
fun new(
|
||||
transactions: ImmutableList<TransactionOverview> = TRANSACTIONS,
|
||||
transactions: ImmutableList<TransactionOverviewExt> = TRANSACTIONS,
|
||||
state: TransactionHistorySyncState = STATE
|
||||
) = when (state) {
|
||||
is TransactionHistorySyncState.Syncing -> {
|
||||
|
|
|
@ -110,7 +110,7 @@ class HistoryViewTest {
|
|||
|
||||
assertEquals(0, testSetup.getOnItemClickCount())
|
||||
|
||||
composeTestRule.onAllNodesWithTag(HistoryTag.TRANSACTION_ITEM, useUnmergedTree = true).also {
|
||||
composeTestRule.onAllNodesWithTag(HistoryTag.TRANSACTION_ITEM_TITLE, useUnmergedTree = true).also {
|
||||
it.assertCountEquals(TransactionHistorySyncStateFixture.TRANSACTIONS.size)
|
||||
|
||||
TransactionHistorySyncStateFixture.TRANSACTIONS.forEachIndexed { index, _ ->
|
||||
|
|
|
@ -35,6 +35,7 @@ import co.electriccoin.zcash.ui.preference.EncryptedPreferenceSingleton
|
|||
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionOverviewExt
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
@ -48,6 +49,7 @@ import kotlinx.coroutines.flow.combine
|
|||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
@ -183,13 +185,22 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
|||
val transactionHistoryState =
|
||||
synchronizer
|
||||
.filterNotNull()
|
||||
.flatMapLatest {
|
||||
it.transactions
|
||||
.combine(it.status) { transactions: List<TransactionOverview>, status: Synchronizer.Status ->
|
||||
.flatMapLatest { synchronizer ->
|
||||
synchronizer.transactions
|
||||
.combine(synchronizer.status) {
|
||||
transactions: List<TransactionOverview>, status: Synchronizer.Status ->
|
||||
val enhancedTransactions =
|
||||
transactions.map {
|
||||
if (it.isSentTransaction) {
|
||||
TransactionOverviewExt(it, synchronizer.getRecipients(it).firstOrNull())
|
||||
} else {
|
||||
TransactionOverviewExt(it, null)
|
||||
}
|
||||
}
|
||||
if (status.isSyncing()) {
|
||||
TransactionHistorySyncState.Syncing(transactions.toPersistentList())
|
||||
TransactionHistorySyncState.Syncing(enhancedTransactions.toPersistentList())
|
||||
} else {
|
||||
TransactionHistorySyncState.Done(transactions.toPersistentList())
|
||||
TransactionHistorySyncState.Done(enhancedTransactions.toPersistentList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,14 +50,14 @@ internal fun WrapAccount(
|
|||
transactionState = transactionHistoryState,
|
||||
onItemClick = { tx ->
|
||||
Twig.debug { "Transaction item clicked - querying memos..." }
|
||||
val memos = synchronizer?.getMemos(tx)
|
||||
val memos = synchronizer?.getMemos(tx.overview)
|
||||
scope.launch {
|
||||
memos?.toList()?.let {
|
||||
val merged = it.joinToString().ifEmpty { "-" }
|
||||
Twig.info { "Transaction memos: count: ${it.size}, contains: $merged" }
|
||||
ClipboardManagerUtil.copyToClipboard(
|
||||
activity.applicationContext,
|
||||
activity.getString(R.string.history_item_clipboard_tag),
|
||||
activity.getString(R.string.account_history_item_clipboard_tag),
|
||||
merged
|
||||
)
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ internal fun WrapAccount(
|
|||
Twig.debug { "Transaction ID clicked: $txId" }
|
||||
ClipboardManagerUtil.copyToClipboard(
|
||||
activity.applicationContext,
|
||||
activity.getString(R.string.history_id_clipboard_tag),
|
||||
activity.getString(R.string.account_history_id_clipboard_tag),
|
||||
txId
|
||||
)
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@ package co.electriccoin.zcash.ui.screen.account
|
|||
*/
|
||||
object HistoryTag {
|
||||
const val TRANSACTION_LIST = "transaction_list"
|
||||
const val TRANSACTION_ITEM = "transaction_item"
|
||||
const val TRANSACTION_ITEM_TITLE = "transaction_item_title"
|
||||
const val TRANSACTION_ID = "transaction_id"
|
||||
const val PROGRESS = "progress_bar"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package co.electriccoin.zcash.ui.screen.account.state
|
||||
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
sealed class TransactionHistorySyncState {
|
||||
|
@ -8,13 +7,13 @@ sealed class TransactionHistorySyncState {
|
|||
override fun toString() = "Loading" // NON-NLS
|
||||
}
|
||||
|
||||
data class Syncing(val transactions: ImmutableList<TransactionOverview>) : TransactionHistorySyncState() {
|
||||
data class Syncing(val transactions: ImmutableList<TransactionOverviewExt>) : TransactionHistorySyncState() {
|
||||
fun hasNoTransactions(): Boolean {
|
||||
return transactions.isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
data class Done(val transactions: ImmutableList<TransactionOverview>) : TransactionHistorySyncState() {
|
||||
data class Done(val transactions: ImmutableList<TransactionOverviewExt>) : TransactionHistorySyncState() {
|
||||
fun hasNoTransactions(): Boolean {
|
||||
return transactions.isEmpty()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package co.electriccoin.zcash.ui.screen.account.state
|
||||
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
|
||||
data class TransactionOverviewExt(
|
||||
val overview: TransactionOverview,
|
||||
val recipient: TransactionRecipient?
|
||||
)
|
|
@ -17,7 +17,6 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.fixture.TransactionOverviewFixture
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.compose.BalanceWidget
|
||||
|
@ -30,6 +29,7 @@ import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
|||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||
import co.electriccoin.zcash.ui.screen.account.AccountTag
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionOverviewExt
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Preview("Account No History")
|
||||
|
@ -64,9 +64,18 @@ private fun HistoryListComposablePreview() {
|
|||
TransactionHistorySyncState.Syncing(
|
||||
@Suppress("MagicNumber")
|
||||
persistentListOf(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(100000000)),
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(200000000)),
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(300000000)),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(100000000)),
|
||||
null
|
||||
),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(200000000)),
|
||||
null
|
||||
),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(300000000)),
|
||||
null
|
||||
),
|
||||
)
|
||||
),
|
||||
onItemClick = {},
|
||||
|
@ -82,7 +91,7 @@ fun Account(
|
|||
goBalances: () -> Unit,
|
||||
goSettings: () -> Unit,
|
||||
isKeepScreenOnWhileSyncing: Boolean?,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onItemClick: (TransactionOverviewExt) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit,
|
||||
transactionState: TransactionHistorySyncState,
|
||||
walletSnapshot: WalletSnapshot,
|
||||
|
@ -131,7 +140,7 @@ private fun AccountMainContent(
|
|||
walletSnapshot: WalletSnapshot,
|
||||
isKeepScreenOnWhileSyncing: Boolean?,
|
||||
goBalances: () -> Unit,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onItemClick: (TransactionOverviewExt) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit,
|
||||
transactionState: TransactionHistorySyncState,
|
||||
modifier: Modifier = Modifier
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package co.electriccoin.zcash.ui.screen.account.view
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
|
@ -14,39 +15,43 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Cancel
|
||||
import androidx.compose.material.icons.outlined.ArrowCircleDown
|
||||
import androidx.compose.material.icons.outlined.ArrowCircleUp
|
||||
import androidx.compose.material.icons.twotone.ArrowCircleDown
|
||||
import androidx.compose.material.icons.twotone.ArrowCircleUp
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.DividerDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.Center
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import cash.z.ecc.android.sdk.fixture.TransactionOverviewFixture
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
import cash.z.ecc.android.sdk.model.TransactionState
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.toZecString
|
||||
import cash.z.ecc.sdk.type.ZcashCurrency
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.component.Body
|
||||
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
|
||||
import co.electriccoin.zcash.ui.design.component.GradientSurface
|
||||
import co.electriccoin.zcash.ui.design.component.StyledBalance
|
||||
import co.electriccoin.zcash.ui.design.component.Tiny
|
||||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.screen.account.HistoryTag
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionHistorySyncState
|
||||
import co.electriccoin.zcash.ui.screen.account.state.TransactionOverviewExt
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import java.text.DateFormat
|
||||
|
@ -77,9 +82,18 @@ private fun ComposableHistoryListPreview() {
|
|||
TransactionHistorySyncState.Syncing(
|
||||
@Suppress("MagicNumber")
|
||||
persistentListOf(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(100000000)),
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(200000000)),
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(300000000)),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(100000000)),
|
||||
null
|
||||
),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(200000000)),
|
||||
null
|
||||
),
|
||||
TransactionOverviewExt(
|
||||
TransactionOverviewFixture.new(netValue = Zatoshi(300000000)),
|
||||
null
|
||||
),
|
||||
)
|
||||
),
|
||||
onItemClick = {},
|
||||
|
@ -93,7 +107,9 @@ val dateFormat: DateFormat by lazy {
|
|||
SimpleDateFormat.getDateTimeInstance(
|
||||
SimpleDateFormat.MEDIUM,
|
||||
SimpleDateFormat.SHORT,
|
||||
Locale.getDefault()
|
||||
// TODO [#1171]: Remove default MonetarySeparators locale
|
||||
// TODO [#1171]: https://github.com/Electric-Coin-Company/zashi-android/issues/1171
|
||||
Locale.US
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -101,7 +117,7 @@ val dateFormat: DateFormat by lazy {
|
|||
@Suppress("LongMethod")
|
||||
fun HistoryContainer(
|
||||
transactionState: TransactionHistorySyncState,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
onItemClick: (TransactionOverviewExt) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
|
@ -143,141 +159,223 @@ fun HistoryContainer(
|
|||
|
||||
@Composable
|
||||
private fun HistoryList(
|
||||
transactions: ImmutableList<TransactionOverview>,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
transactions: ImmutableList<TransactionOverviewExt>,
|
||||
onItemClick: (TransactionOverviewExt) -> Unit,
|
||||
onTransactionIdClick: (String) -> Unit
|
||||
) {
|
||||
val currency = ZcashCurrency.getLocalizedName(LocalContext.current)
|
||||
if (transactions.isEmpty()) {
|
||||
Column {
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingXlarge))
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_LIST)
|
||||
) {
|
||||
itemsIndexed(transactions) { _, item ->
|
||||
HistoryItem(
|
||||
transaction = item,
|
||||
currency = currency,
|
||||
onItemClick = onItemClick,
|
||||
onIdClick = onTransactionIdClick,
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center,
|
||||
text = stringResource(id = R.string.account_history_empty),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.titleRegular,
|
||||
color = ZcashTheme.colors.textCommon,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_LIST)
|
||||
) {
|
||||
itemsIndexed(transactions) { _, item ->
|
||||
HistoryItem(
|
||||
transaction = item,
|
||||
onItemClick = onItemClick,
|
||||
onIdClick = onTransactionIdClick,
|
||||
)
|
||||
|
||||
Divider(
|
||||
color = ZcashTheme.colors.dividerColor,
|
||||
thickness = DividerDefaults.Thickness,
|
||||
modifier = Modifier.padding(horizontal = ZcashTheme.dimens.spacingDefault)
|
||||
)
|
||||
Divider(
|
||||
color = ZcashTheme.colors.dividerColor,
|
||||
thickness = DividerDefaults.Thickness,
|
||||
modifier = Modifier.padding(horizontal = ZcashTheme.dimens.spacingDefault)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class ItemExpandedState {
|
||||
COLLAPSED,
|
||||
EXPANDED,
|
||||
EXPANDED_ADDRESS,
|
||||
EXPANDED_ID
|
||||
}
|
||||
|
||||
const val ADDRESS_IN_TITLE_WIDTH_RATIO = 0.5f
|
||||
|
||||
@Composable
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
fun HistoryItem(
|
||||
transaction: TransactionOverview,
|
||||
currency: String,
|
||||
onItemClick: (TransactionOverview) -> Unit,
|
||||
transaction: TransactionOverviewExt,
|
||||
onItemClick: (TransactionOverviewExt) -> Unit,
|
||||
onIdClick: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val transactionTypeText: String
|
||||
val transactionTypeIcon: ImageVector
|
||||
when (transaction.getExtendedState()) {
|
||||
val typeText: String
|
||||
val textColor: Color
|
||||
val typeIcon: ImageVector
|
||||
val textStyle: TextStyle
|
||||
when (transaction.overview.getExtendedState()) {
|
||||
TransactionExtendedState.SENT -> {
|
||||
transactionTypeText = stringResource(id = R.string.history_item_sent)
|
||||
transactionTypeIcon = Icons.TwoTone.ArrowCircleUp
|
||||
typeText = stringResource(id = R.string.account_history_item_sent)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_send_icon)
|
||||
textColor = MaterialTheme.colorScheme.onBackground
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleRegular
|
||||
}
|
||||
TransactionExtendedState.SENDING -> {
|
||||
transactionTypeText = stringResource(id = R.string.history_item_sending)
|
||||
transactionTypeIcon = Icons.Outlined.ArrowCircleUp
|
||||
typeText = stringResource(id = R.string.account_history_item_sending)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_send_icon)
|
||||
textColor = ZcashTheme.colors.textDescription
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleRunning
|
||||
}
|
||||
TransactionExtendedState.SEND_FAILED -> {
|
||||
typeText = stringResource(id = R.string.account_history_item_send_failed)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_send_icon)
|
||||
textColor = ZcashTheme.colors.dangerous
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleFailed
|
||||
}
|
||||
|
||||
TransactionExtendedState.RECEIVED -> {
|
||||
transactionTypeText = stringResource(id = R.string.history_item_received)
|
||||
transactionTypeIcon = Icons.TwoTone.ArrowCircleDown
|
||||
typeText = stringResource(id = R.string.account_history_item_received)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_receive_icon)
|
||||
textColor = MaterialTheme.colorScheme.onBackground
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleRegular
|
||||
}
|
||||
TransactionExtendedState.RECEIVING -> {
|
||||
transactionTypeText = stringResource(id = R.string.history_item_receiving)
|
||||
transactionTypeIcon = Icons.Outlined.ArrowCircleDown
|
||||
typeText = stringResource(id = R.string.account_history_item_receiving)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_receive_icon)
|
||||
textColor = ZcashTheme.colors.textDescription
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleRunning
|
||||
}
|
||||
TransactionExtendedState.EXPIRED -> {
|
||||
transactionTypeText = stringResource(id = R.string.history_item_expired)
|
||||
transactionTypeIcon = Icons.Filled.Cancel
|
||||
TransactionExtendedState.RECEIVE_FAILED -> {
|
||||
typeText = stringResource(id = R.string.account_history_item_receive_failed)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.trx_receive_icon)
|
||||
textColor = ZcashTheme.colors.dangerous
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleFailed
|
||||
}
|
||||
}
|
||||
|
||||
var expandedState: ItemExpandedState by rememberSaveable {
|
||||
mutableStateOf(ItemExpandedState.COLLAPSED)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier =
|
||||
modifier
|
||||
.then(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onItemClick(transaction) }
|
||||
.background(color = ZcashTheme.colors.historyBackgroundColor)
|
||||
.padding(all = ZcashTheme.dimens.spacingDefault)
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
.clickable {
|
||||
if (expandedState == ItemExpandedState.COLLAPSED) {
|
||||
expandedState = ItemExpandedState.EXPANDED
|
||||
}
|
||||
onItemClick(transaction)
|
||||
}
|
||||
.padding(all = ZcashTheme.dimens.spacingLarge)
|
||||
.animateContentSize()
|
||||
)
|
||||
) {
|
||||
Image(
|
||||
imageVector = transactionTypeIcon,
|
||||
contentDescription = transactionTypeText,
|
||||
modifier = Modifier.padding(all = ZcashTheme.dimens.spacingTiny)
|
||||
imageVector = typeIcon,
|
||||
contentDescription = typeText,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny))
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingDefault))
|
||||
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Body(
|
||||
text = transactionTypeText,
|
||||
color = Color.Black,
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_ITEM)
|
||||
)
|
||||
Text(
|
||||
text = typeText,
|
||||
style = textStyle,
|
||||
color = textColor,
|
||||
modifier = Modifier.testTag(HistoryTag.TRANSACTION_ITEM_TITLE)
|
||||
)
|
||||
|
||||
val dateString =
|
||||
transaction.minedHeight?.let {
|
||||
transaction.blockTimeEpochSeconds?.let { blockTimeEpochSeconds ->
|
||||
// * 1000 to covert to millis
|
||||
@Suppress("MagicNumber")
|
||||
dateFormat.format(blockTimeEpochSeconds.times(1000L))
|
||||
} ?: stringResource(id = R.string.history_item_date_not_available)
|
||||
} ?: stringResource(id = R.string.history_item_date_not_available)
|
||||
// For now, use the same label for the above missing transaction date
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingSmall))
|
||||
|
||||
Body(
|
||||
text = dateString,
|
||||
if (transaction.recipient != null && transaction.recipient is TransactionRecipient.Address) {
|
||||
Text(
|
||||
text = transaction.recipient.addressValue,
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.addressCollapsed,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth(ADDRESS_IN_TITLE_WIDTH_RATIO)
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.trx_shielded),
|
||||
contentDescription = stringResource(id = R.string.account_history_item_shielded)
|
||||
)
|
||||
}
|
||||
|
||||
Column {
|
||||
Row(modifier = Modifier.align(alignment = Alignment.End)) {
|
||||
val zecString =
|
||||
if (transaction.isSentTransaction) {
|
||||
"-${transaction.netValue.toZecString()}"
|
||||
} else {
|
||||
transaction.netValue.toZecString()
|
||||
}
|
||||
Body(text = zecString)
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingSmall))
|
||||
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny))
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
Body(text = currency)
|
||||
}
|
||||
}
|
||||
StyledBalance(
|
||||
balanceString = transaction.overview.netValue.toZecString(),
|
||||
textStyles =
|
||||
Pair(
|
||||
first = ZcashTheme.extendedTypography.transactionItemStyles.valueFirstPart,
|
||||
second = ZcashTheme.extendedTypography.transactionItemStyles.valueSecondPart
|
||||
),
|
||||
textColor =
|
||||
if (transaction.overview.isSentTransaction) {
|
||||
ZcashTheme.colors.historySendColor
|
||||
} else {
|
||||
ZcashTheme.colors.textCommon
|
||||
},
|
||||
prefix =
|
||||
if (transaction.overview.isSentTransaction) {
|
||||
stringResource(id = R.string.account_history_item_sent_prefix)
|
||||
} else {
|
||||
stringResource(id = R.string.account_history_item_received_prefix)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingTiny))
|
||||
|
||||
val txId = transaction.txIdString()
|
||||
Tiny(
|
||||
text = txId,
|
||||
modifier =
|
||||
Modifier
|
||||
.clickable { onIdClick(txId) }
|
||||
.testTag(HistoryTag.TRANSACTION_ID)
|
||||
val dateString =
|
||||
transaction.overview.minedHeight?.let {
|
||||
transaction.overview.blockTimeEpochSeconds?.let { blockTimeEpochSeconds ->
|
||||
// * 1000 to covert to millis
|
||||
@Suppress("MagicNumber")
|
||||
dateFormat.format(blockTimeEpochSeconds.times(1000))
|
||||
} ?: "-"
|
||||
} ?: "-"
|
||||
// For now, use the same label for the above missing transaction date
|
||||
|
||||
Text(
|
||||
text = dateString,
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.date,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
if (expandedState >= ItemExpandedState.EXPANDED) {
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
||||
|
||||
val txId = transaction.overview.txIdString()
|
||||
Tiny(
|
||||
text = txId,
|
||||
modifier =
|
||||
Modifier
|
||||
.clickable { onIdClick(txId) }
|
||||
.testTag(HistoryTag.TRANSACTION_ID)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,15 +383,20 @@ fun HistoryItem(
|
|||
enum class TransactionExtendedState {
|
||||
SENT,
|
||||
SENDING,
|
||||
SEND_FAILED,
|
||||
RECEIVED,
|
||||
RECEIVING,
|
||||
EXPIRED
|
||||
RECEIVE_FAILED,
|
||||
}
|
||||
|
||||
private fun TransactionOverview.getExtendedState(): TransactionExtendedState {
|
||||
return when (transactionState) {
|
||||
TransactionState.Expired -> {
|
||||
TransactionExtendedState.EXPIRED
|
||||
if (isSentTransaction) {
|
||||
TransactionExtendedState.SEND_FAILED
|
||||
} else {
|
||||
TransactionExtendedState.RECEIVE_FAILED
|
||||
}
|
||||
}
|
||||
TransactionState.Confirmed -> {
|
||||
if (isSentTransaction) {
|
||||
|
|
|
@ -114,7 +114,12 @@ internal fun WrapBalances(
|
|||
|
||||
Twig.debug { "Shielding transparent funds" }
|
||||
// Using empty string for memo to clear the default memo prefix value defined in the SDK
|
||||
runCatching { synchronizer.shieldFunds(spendingKey, "") }
|
||||
runCatching {
|
||||
// TODO [#1285]: Adopt proposal API
|
||||
// TODO [#1285]: https://github.com/Electric-Coin-Company/zashi-android/issues/1285
|
||||
@Suppress("deprecation")
|
||||
synchronizer.shieldFunds(spendingKey, "")
|
||||
}
|
||||
.onSuccess {
|
||||
Twig.info { "Shielding transaction id:$it submitted successfully" }
|
||||
setShieldState(ShieldState.None)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="12dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="12">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h17.55v11.1h-17.55z"/>
|
||||
<path
|
||||
android:pathData="M17.39,0.09C17.32,0.03 17.22,0 17.13,0H17.04L0.32,4.29C0.13,4.34 0,4.51 0,4.71C0,4.91 0.14,5.07 0.33,5.12L8.59,7.07L16.95,11.06C17.01,11.09 17.07,11.1 17.13,11.1C17.21,11.1 17.29,11.08 17.36,11.03C17.48,10.95 17.56,10.82 17.56,10.67V0.43C17.56,0.3 17.5,0.18 17.4,0.09H17.39ZM16.7,4.73V10L5.68,4.73H16.71H16.7ZM5.33,3.88L16.7,0.97V3.88H5.33ZM2.39,4.73H4.17L5.97,5.58L2.39,4.73Z"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="16">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h20v16h-20z"/>
|
||||
<path
|
||||
android:pathData="M19.92,0.07C19.81,-0.03 19.5,-0 19.31,0.06C13.04,2.2 6.77,4.34 0.5,6.5C0.31,6.56 0.17,6.75 0,6.88C0.13,7.04 0.24,7.25 0.41,7.35C1.57,8.05 2.76,8.72 3.92,9.43C4.15,9.57 4.37,9.85 4.44,10.11C4.93,11.9 5.38,13.7 5.86,15.49C5.91,15.68 6.05,15.96 6.2,15.99C6.35,16.02 6.6,15.85 6.74,15.7C7.68,14.75 8.62,13.79 9.53,12.82C9.79,12.54 9.99,12.48 10.35,12.66C11.64,13.32 12.95,13.93 14.25,14.56C14.39,14.63 14.53,14.69 14.77,14.79C14.89,14.6 15.04,14.43 15.12,14.23C16.74,9.71 18.35,5.18 19.96,0.65C20.02,0.47 20.04,0.16 19.93,0.06L19.92,0.07ZM4.26,8.81C3.28,8.21 2.28,7.64 1.2,7C6.3,5.25 11.28,3.55 16.26,1.84L16.3,1.92C16.16,2.01 16.03,2.1 15.89,2.18C12.27,4.38 8.66,6.57 5.04,8.78C4.76,8.95 4.55,8.99 4.26,8.8V8.81ZM6.71,10.97C6.53,11.87 6.39,12.77 6.12,13.68C6.02,13.3 5.92,12.93 5.82,12.55C5.6,11.69 5.38,10.84 5.15,9.98C5.09,9.76 5.06,9.58 5.32,9.43C8.56,7.48 11.79,5.51 15.03,3.55C15.07,3.53 15.12,3.53 15.3,3.49C14.16,4.44 13.13,5.3 12.09,6.16C11.63,6.54 8.6,8.99 8.14,9.38C8.07,9.44 8,9.5 7.95,9.57C7.62,9.81 7.3,10.08 7.01,10.37C6.85,10.52 6.75,10.77 6.71,10.98V10.97ZM6.81,14.61C7.01,13.42 7.19,12.38 7.38,11.25C8,11.55 8.58,11.83 9.2,12.13C8.41,12.95 7.65,13.73 6.8,14.61H6.81ZM14.48,13.9C12.24,12.81 10.04,11.75 7.77,10.65C8.09,10.38 8.39,10.18 8.62,9.92C11.01,7.93 15.96,3.88 18.35,1.89C18.49,1.77 18.63,1.66 18.86,1.6C17.41,5.68 15.95,9.77 14.48,13.9Z"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -1,11 +1,17 @@
|
|||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="history_item_clipboard_tag">Transaction memo</string>
|
||||
<string name="history_id_clipboard_tag">Transaction ID</string>
|
||||
|
||||
<string name="history_item_sent">Sent</string>
|
||||
<string name="history_item_received">Received</string>
|
||||
<string name="history_item_sending">Sending</string>
|
||||
<string name="history_item_receiving">Receiving</string>
|
||||
<string name="history_item_expired">Expired</string>
|
||||
<string name="history_item_date_not_available">Date not available</string>
|
||||
<string name="account_history_empty">No transaction history</string>
|
||||
|
||||
<string name="account_history_item_sent">Sent</string>
|
||||
<string name="account_history_item_received">Received</string>
|
||||
<string name="account_history_item_sending">Sending…</string>
|
||||
<string name="account_history_item_receiving">Receiving…</string>
|
||||
<string name="account_history_item_receive_failed">Receive failed</string>
|
||||
<string name="account_history_item_send_failed">Send failed</string>
|
||||
<string name="account_history_item_shielded">Shielded transaction</string>
|
||||
<string name="account_history_item_sent_prefix">-</string>
|
||||
<string name="account_history_item_received_prefix">+</string>
|
||||
|
||||
<string name="account_history_item_clipboard_tag">Transaction memo</string>
|
||||
<string name="account_history_id_clipboard_tag">Transaction ID</string>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="17dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="17"
|
||||
android:viewportHeight="14">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M17,0l-17,0l-0,13.909l17,0z"/>
|
||||
<path
|
||||
android:pathData="M4.481,3.052L8.415,1.794C8.472,1.772 8.528,1.772 8.585,1.794L12.519,3.052C12.697,3.108 12.728,3.151 12.728,3.352V7.967C12.728,8.568 12.5,9.182 12.051,9.794C11.707,10.261 11.232,10.73 10.639,11.188C9.643,11.957 8.661,12.429 8.619,12.449C8.54,12.488 8.459,12.488 8.379,12.449C8.338,12.429 7.357,11.957 6.359,11.188C5.766,10.73 5.291,10.26 4.948,9.794C4.498,9.182 4.27,8.568 4.27,7.967V3.352C4.28,3.143 4.337,3.114 4.479,3.052H4.481Z"
|
||||
android:fillColor="#231F20"/>
|
||||
<path
|
||||
android:pathData="M17,13.909V0H13.542V0.96H15.715V12.948H13.542V13.908H17V13.909Z"
|
||||
android:fillColor="#231F20"/>
|
||||
<path
|
||||
android:pathData="M0,0V13.909H3.458V12.95H1.285V0.96H3.458V0H0Z"
|
||||
android:fillColor="#231F20"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -10,7 +10,7 @@
|
|||
<string name="balances_transparent_balance_help_close">I got it!</string>
|
||||
<string name="balances_transparent_help_content_description">Show help</string>
|
||||
<string name="balances_transparent_balance_shield">Shield and consolidate funds</string>
|
||||
<string name="balances_transparent_balance_fee">(Typical fee < <xliff:g id="fee_amount" example="0.001">%1$s
|
||||
<string name="balances_transparent_balance_fee">(Typical Fee < <xliff:g id="fee_amount" example="0.001">%1$s
|
||||
</xliff:g>)</string>
|
||||
|
||||
<string name="balances_status_syncing" formatted="true">Syncing…</string>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<xliff:g id="max_bytes" example="500">%2$s</xliff:g>
|
||||
</string>
|
||||
<string name="send_create">Review</string>
|
||||
<string name="send_fee">(Typical fee < <xliff:g id="fee_amount" example="0.001">%1$s</xliff:g>)</string>
|
||||
<string name="send_fee">(Typical Fee < <xliff:g id="fee_amount" example="0.001">%1$s</xliff:g>)</string>
|
||||
|
||||
<string name="send_confirmation_amount_and_address_format" formatted="true">Send <xliff:g id="amount" example="12.345">%1$s</xliff:g> ZEC to <xliff:g id="address" example="zs1g7cqw … mvyzgm">%2$s</xliff:g>?</string>
|
||||
<string name="send_confirmation_memo_format" formatted="true">Memo: <xliff:g id="memo" example="for Veronika">%1$s</xliff:g></string>
|
||||
|
|
Loading…
Reference in New Issue