From 221a495c6e1cc50eb895b2d1290f463d9c6233eb Mon Sep 17 00:00:00 2001 From: Jakub Porzuczek Date: Mon, 15 Jan 2024 13:55:18 +0100 Subject: [PATCH] display guarantees for pool units --- .../android/domain/SampleDataProvider.kt | 4 +- .../android/domain/model/Transferable.kt | 42 ++++- .../transaction/TransactionReviewScreen.kt | 2 + .../transaction/TransactionReviewViewModel.kt | 18 +- .../analysis/PoolContributionAnalysis.kt | 13 +- .../transaction/analysis/StakeAnalysis.kt | 2 +- .../analysis/StakeClaimAnalysis.kt | 2 +- .../analysis/TransactionTypeExtensions.kt | 8 +- .../composables/PoolTypeContent.kt | 6 +- .../composables/StakeTypeContent.kt | 6 +- .../composables/TransactionAccountCard.kt | 178 ++++++++++-------- .../TransactionAccountWithGuaranteesCard.kt | 10 +- .../TransactionGuaranteesDelegate.kt | 77 ++++++-- 13 files changed, 234 insertions(+), 134 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/domain/SampleDataProvider.kt b/app/src/main/java/com/babylon/wallet/android/domain/SampleDataProvider.kt index 0b11424b80..6b0bc190f0 100644 --- a/app/src/main/java/com/babylon/wallet/android/domain/SampleDataProvider.kt +++ b/app/src/main/java/com/babylon/wallet/android/domain/SampleDataProvider.kt @@ -89,7 +89,7 @@ class SampleDataProvider { ) val transferableDepositing = Transferable.Depositing( - transferable = TransferableResource.Amount( + transferable = TransferableResource.FungibleAmount( amount = BigDecimal(69), resource = Resource.FungibleResource( resourceAddress = "resource_tdx_e_1tkawacgvcw7z9xztccgjrged25c7nqtnd4nllh750s2ny64m0cltmg", @@ -136,7 +136,7 @@ class SampleDataProvider { val transferableDepositingPool = Transferable.Depositing( transferable = TransferableResource.PoolUnitAmount( - pool = PoolUnit( + poolUnit = PoolUnit( Resource.FungibleResource( resourceAddress = "resource_tdx_e_1tkawacgvcw7z9xztccgjrged25c7nqtnd4nllh750s2ny64m0cltmg", ownedAmount = null, diff --git a/app/src/main/java/com/babylon/wallet/android/domain/model/Transferable.kt b/app/src/main/java/com/babylon/wallet/android/domain/model/Transferable.kt index f5115013fe..bdb5088cd7 100644 --- a/app/src/main/java/com/babylon/wallet/android/domain/model/Transferable.kt +++ b/app/src/main/java/com/babylon/wallet/android/domain/model/Transferable.kt @@ -23,7 +23,7 @@ sealed interface Transferable { val predicted = guaranteeType as? GuaranteeType.Predicted ?: return null when (val transferable = transferable) { - is TransferableResource.Amount -> GuaranteeAssertion.ForAmount( + is TransferableResource.FungibleAmount -> GuaranteeAssertion.ForAmount( amount = transferable.amount * predicted.guaranteeOffset.toBigDecimal(), instructionIndex = predicted.instructionIndex ) @@ -36,6 +36,7 @@ sealed interface Transferable { amount = transferable.amount * predicted.guaranteeOffset.toBigDecimal(), instructionIndex = predicted.instructionIndex ) + is TransferableResource.StakeClaimNft -> null is TransferableResource.PoolUnitAmount -> GuaranteeAssertion.ForAmount( amount = transferable.amount * predicted.guaranteeOffset.toBigDecimal(), @@ -48,6 +49,14 @@ sealed interface Transferable { } } + val hasEditableGuarantees: Boolean + get() { + return when (this) { + is Depositing -> guaranteeType is GuaranteeType.Predicted && !transferable.isNewlyCreated + is Withdrawing -> false + } + } + data class Depositing( override val transferable: TransferableResource, val guaranteeType: GuaranteeType = GuaranteeType.Guaranteed @@ -107,19 +116,25 @@ sealed interface TransferableResource { get() = resource.resourceAddress val isNewlyCreated: Boolean - data class Amount( - val amount: BigDecimal, + data class FungibleAmount( + override val amount: BigDecimal, override val resource: Resource.FungibleResource, override val isNewlyCreated: Boolean - ) : TransferableResource + ) : TransferableResource, TransferableWithGuarantees { + override val fungibleResource: Resource.FungibleResource + get() = resource + } data class LsuAmount( - val amount: BigDecimal, + override val amount: BigDecimal, override val resource: Resource.FungibleResource, val validatorDetail: ValidatorDetail, val xrdWorth: BigDecimal, override val isNewlyCreated: Boolean = false - ) : TransferableResource + ) : TransferableResource, TransferableWithGuarantees { + override val fungibleResource: Resource.FungibleResource + get() = resource + } data class NFTs( override val resource: Resource.NonFungibleResource, @@ -134,12 +149,19 @@ sealed interface TransferableResource { ) : TransferableResource data class PoolUnitAmount( - val amount: BigDecimal, - val pool: PoolUnit, + override val amount: BigDecimal, + val poolUnit: PoolUnit, val contributionPerResource: Map, override val isNewlyCreated: Boolean = false, - ) : TransferableResource { + ) : TransferableResource, TransferableWithGuarantees { override val resource: Resource - get() = pool.stake + get() = poolUnit.stake + override val fungibleResource: Resource.FungibleResource + get() = poolUnit.stake } } + +interface TransferableWithGuarantees { + val fungibleResource: Resource.FungibleResource + val amount: BigDecimal +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewScreen.kt index fd88ab630c..7ec15f6378 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewScreen.kt @@ -315,6 +315,7 @@ private fun TransactionPreviewContent( state = state, onFungibleResourceClick = onFungibleResourceClick, onNonFungibleResourceClick = onNonFungibleResourceClick, + onPromptForGuarantees = promptForGuarantees, previewType = preview ) ReceiptEdge(modifier = Modifier.fillMaxWidth(), color = RadixTheme.colors.gray5) @@ -325,6 +326,7 @@ private fun TransactionPreviewContent( modifier = Modifier.background(RadixTheme.colors.gray5), state = state, onFungibleResourceClick = onFungibleResourceClick, + onPromptForGuarantees = promptForGuarantees, previewType = preview ) ReceiptEdge(modifier = Modifier.fillMaxWidth(), color = RadixTheme.colors.gray5) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewViewModel.kt index 7270bd09c3..9ed36f0c8b 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/TransactionReviewViewModel.kt @@ -14,6 +14,7 @@ import com.babylon.wallet.android.domain.model.GuaranteeAssertion import com.babylon.wallet.android.domain.model.MessageFromDataChannel import com.babylon.wallet.android.domain.model.Transferable import com.babylon.wallet.android.domain.model.TransferableResource +import com.babylon.wallet.android.domain.model.TransferableWithGuarantees import com.babylon.wallet.android.domain.model.assets.ValidatorDetail import com.babylon.wallet.android.domain.model.resources.Badge import com.babylon.wallet.android.domain.model.resources.Resource @@ -365,7 +366,7 @@ class TransactionReviewViewModel @Inject constructor( if (candidateAddressWithdrawn != null) { val xrdResourceWithdrawn = candidateAddressWithdrawn.resources.map { it.transferable - }.filterIsInstance().find { it.resource.isXrd } + }.filterIsInstance().find { it.resource.isXrd } xrdResourceWithdrawn?.amount ?: BigDecimal.ZERO } else { @@ -503,9 +504,8 @@ data class AccountWithDepositSettingsChanges( @Suppress("MagicNumber") sealed interface AccountWithPredictedGuarantee { - val address: String - val transferableAmount: TransferableResource.Amount + val transferable: TransferableWithGuarantees val instructionIndex: Long val guaranteeAmountString: String @@ -514,7 +514,7 @@ sealed interface AccountWithPredictedGuarantee { get() = (guaranteeAmountString.toDoubleOrNull() ?: 0.0).div(100.0) val guaranteedAmount: BigDecimal - get() = transferableAmount.amount * guaranteeOffsetDecimal.toBigDecimal() + get() = transferable.amount * guaranteeOffsetDecimal.toBigDecimal() fun increase(): AccountWithPredictedGuarantee { val newOffset = (guaranteeOffsetDecimal.toBigDecimal().plus(BigDecimal(0.001))) @@ -549,11 +549,11 @@ sealed interface AccountWithPredictedGuarantee { } fun isTheSameGuaranteeItem(with: AccountWithPredictedGuarantee): Boolean = address == with.address && - transferableAmount.resourceAddress == with.transferableAmount.resourceAddress + transferable.fungibleResource.resourceAddress == with.transferable.fungibleResource.resourceAddress data class Owned( val account: Network.Account, - override val transferableAmount: TransferableResource.Amount, + override val transferable: TransferableWithGuarantees, override val instructionIndex: Long, override val guaranteeAmountString: String ) : AccountWithPredictedGuarantee { @@ -563,7 +563,7 @@ sealed interface AccountWithPredictedGuarantee { data class Other( override val address: String, - override val transferableAmount: TransferableResource.Amount, + override val transferable: TransferableWithGuarantees, override val instructionIndex: Long, override val guaranteeAmountString: String ) : AccountWithPredictedGuarantee @@ -597,12 +597,12 @@ sealed interface AccountWithTransferableResources { val resources = resources.mapWhen( predicate = { depositing -> resourcesWithGuaranteesForAccount.any { - it.address == address && it.transferableAmount.resourceAddress == depositing.transferable.resourceAddress + it.address == address && it.transferable.fungibleResource.resourceAddress == depositing.transferable.resourceAddress } }, mutation = { depositing -> val accountWithGuarantee = resourcesWithGuaranteesForAccount.find { - it.transferableAmount.resourceAddress == depositing.transferable.resourceAddress + it.transferable.fungibleResource.resourceAddress == depositing.transferable.resourceAddress } if (accountWithGuarantee != null) { diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/PoolContributionAnalysis.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/PoolContributionAnalysis.kt index cde0f35e3c..a528f09511 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/PoolContributionAnalysis.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/PoolContributionAnalysis.kt @@ -1,5 +1,6 @@ package com.babylon.wallet.android.presentation.transaction.analysis +import com.babylon.wallet.android.domain.model.GuaranteeType import com.babylon.wallet.android.domain.model.Transferable import com.babylon.wallet.android.domain.model.TransferableResource import com.babylon.wallet.android.domain.model.assets.PoolUnit @@ -10,11 +11,12 @@ import com.babylon.wallet.android.presentation.transaction.AccountWithTransferab import com.babylon.wallet.android.presentation.transaction.PreviewType import com.radixdlt.ret.DetailedManifestClass import com.radixdlt.ret.ExecutionSummary +import com.radixdlt.ret.ResourceIndicator +import kotlinx.coroutines.flow.first import rdx.works.profile.data.model.pernetwork.Network import rdx.works.profile.domain.GetProfileUseCase import rdx.works.profile.domain.accountOnCurrentNetwork import rdx.works.profile.domain.accountsOnCurrentNetwork -import timber.log.Timber suspend fun DetailedManifestClass.PoolContribution.resolve( executionSummary: ExecutionSummary, @@ -22,6 +24,7 @@ suspend fun DetailedManifestClass.PoolContribution.resolve( resources: List, involvedPools: List ): PreviewType { + val defaultDepositGuarantees = getProfileUseCase.invoke().first().appPreferences.transaction.defaultDepositGuarantee val accountsWithdrawnFrom = executionSummary.accountWithdraws.keys val ownedAccountsWithdrawnFrom = getProfileUseCase.accountsOnCurrentNetwork().filter { accountsWithdrawnFrom.contains(it.address) @@ -29,9 +32,6 @@ suspend fun DetailedManifestClass.PoolContribution.resolve( val from = executionSummary.extractWithdraws(ownedAccountsWithdrawnFrom, resources) val to = executionSummary.accountDeposits.map { depositsPerAddress -> val ownedAccount = getProfileUseCase.accountOnCurrentNetwork(depositsPerAddress.key) ?: error("No account found") - depositsPerAddress.value.forEach { - Timber.d("depositing: ${it.resourceAddress}") - } val deposits = depositsPerAddress.value.mapNotNull { deposit -> val resourceAddress = deposit.resourceAddress val contributions = poolContributions.filter { it.poolUnitsResourceAddress.addressString() == resourceAddress } @@ -43,6 +43,8 @@ suspend fun DetailedManifestClass.PoolContribution.resolve( val poolResource = resources.find { it.resourceAddress == pool.metadata.poolUnit() } as? Resource.FungibleResource ?: error("No pool resource found") val contributedResourceAddresses = contributions.first().contributedResources.keys + val guaranteeType = (deposit as? ResourceIndicator.Fungible)?.indicator?.toGuaranteeType(defaultDepositGuarantees) + ?: GuaranteeType.Guaranteed Transferable.Depositing( transferable = TransferableResource.PoolUnitAmount( amount = contributions.map { it.poolUnitsAmount.asStr().toBigDecimal() }.sumOf { it }, @@ -54,7 +56,8 @@ suspend fun DetailedManifestClass.PoolContribution.resolve( contributions.mapNotNull { it.contributedResources[contributedResourceAddress]?.asStr()?.toBigDecimal() } .sumOf { it } }, - ) + ), + guaranteeType = guaranteeType, ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeAnalysis.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeAnalysis.kt index f2259eb5d7..f4a90cecb1 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeAnalysis.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeAnalysis.kt @@ -77,7 +77,7 @@ private suspend fun extractWithdrawals( account = ownedAccount, resources = listOf( element = Transferable.Withdrawing( - transferable = TransferableResource.Amount( + transferable = TransferableResource.FungibleAmount( entry.value.sumOf { it.amount }, xrdResource, false diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeClaimAnalysis.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeClaimAnalysis.kt index 2d246d105e..7162af1dba 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeClaimAnalysis.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/StakeClaimAnalysis.kt @@ -98,7 +98,7 @@ private suspend fun extractDeposits( account = ownedAccount, resources = listOf( element = Transferable.Depositing( - transferable = TransferableResource.Amount( + transferable = TransferableResource.FungibleAmount( entry.value.sumOf { it.amount }, xrdResource, false diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/TransactionTypeExtensions.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/TransactionTypeExtensions.kt index b4a2878567..56f562b62c 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/TransactionTypeExtensions.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/analysis/TransactionTypeExtensions.kt @@ -121,7 +121,7 @@ fun ResourceIndicator.toTransferableResource(resources: List): Transfe resourceAddress = resourceAddress, ownedAmount = BigDecimal.ZERO ) - TransferableResource.Amount( + TransferableResource.FungibleAmount( amount = amount, resource = resource, isNewlyCreated = false @@ -238,7 +238,7 @@ fun DetailedManifestClass.isConformingManifestType(): Boolean { } } -private fun FungibleResourceIndicator.toGuaranteeType(defaultDepositGuarantees: Double): GuaranteeType { +fun FungibleResourceIndicator.toGuaranteeType(defaultDepositGuarantees: Double): GuaranteeType { return when (this) { is FungibleResourceIndicator.Guaranteed -> GuaranteeType.Guaranteed is FungibleResourceIndicator.Predicted -> GuaranteeType.Predicted( @@ -258,14 +258,14 @@ private fun ResourceIndicator.Fungible.toTransferableResource( resources: List, newlyCreatedMetadata: Map>, newlyCreatedEntities: List
-): TransferableResource.Amount { +): TransferableResource.FungibleAmount { val resource = resources.findFungible( resourceAddress.addressString() ) ?: Resource.FungibleResource.from( resourceAddress = resourceAddress, metadata = newlyCreatedMetadata[resourceAddress.addressString()].orEmpty() ) - return TransferableResource.Amount( + return TransferableResource.FungibleAmount( amount = amount, resource = resource, isNewlyCreated = resourceAddress.addressString() in newlyCreatedEntities.map { it.addressString() } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/PoolTypeContent.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/PoolTypeContent.kt index 4104a91a7c..e6d0996512 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/PoolTypeContent.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/PoolTypeContent.kt @@ -19,7 +19,8 @@ fun PoolTypeContent( modifier: Modifier = Modifier, state: TransactionReviewViewModel.State, onFungibleResourceClick: (fungibleResource: Resource.FungibleResource, Boolean) -> Unit, - previewType: PreviewType.Transfer.Pool + previewType: PreviewType.Transfer.Pool, + onPromptForGuarantees: () -> Unit ) { val poolSectionLabel = when (previewType.actionType) { PreviewType.Transfer.Pool.ActionType.Contribution -> "Contributing to pools" @@ -31,7 +32,7 @@ fun PoolTypeContent( onFungibleResourceClick = onFungibleResourceClick, onNonFungibleResourceClick = { _, _, _ -> }, previewType = previewType, - onPromptForGuarantees = {}, + onPromptForGuarantees = onPromptForGuarantees, middleSection = { PoolsContent( modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingDefault), @@ -60,6 +61,7 @@ fun PoolTypePreview() { pools = persistentListOf(), actionType = PreviewType.Transfer.Pool.ActionType.Contribution ), + onPromptForGuarantees = {}, ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/StakeTypeContent.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/StakeTypeContent.kt index b224f5353c..af13dcd11c 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/StakeTypeContent.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/StakeTypeContent.kt @@ -22,7 +22,8 @@ fun StakeTypeContent( state: TransactionReviewViewModel.State, onFungibleResourceClick: (fungibleResource: Resource.FungibleResource, Boolean) -> Unit, onNonFungibleResourceClick: (nonFungibleResource: Resource.NonFungibleResource, Resource.NonFungibleResource.Item, Boolean) -> Unit, - previewType: PreviewType.Transfer.Staking + previewType: PreviewType.Transfer.Staking, + onPromptForGuarantees: () -> Unit ) { val validatorSectionText = when (previewType.actionType) { PreviewType.Transfer.Staking.ActionType.Stake -> stringResource(id = R.string.transactionReview_validators_stake).uppercase() @@ -35,7 +36,7 @@ fun StakeTypeContent( onFungibleResourceClick = onFungibleResourceClick, onNonFungibleResourceClick = onNonFungibleResourceClick, previewType = previewType, - onPromptForGuarantees = {}, + onPromptForGuarantees = onPromptForGuarantees, middleSection = { ValidatorsContent( modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingDefault), @@ -65,6 +66,7 @@ fun StakeUnstakeTypePreview() { validators = persistentListOf(), actionType = PreviewType.Transfer.Staking.ActionType.Stake ), + onPromptForGuarantees = {}, ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountCard.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountCard.kt index 5c174f154b..e3718d7678 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountCard.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountCard.kt @@ -40,6 +40,7 @@ import com.babylon.wallet.android.domain.SampleDataProvider import com.babylon.wallet.android.domain.model.GuaranteeAssertion import com.babylon.wallet.android.domain.model.Transferable import com.babylon.wallet.android.domain.model.TransferableResource +import com.babylon.wallet.android.domain.model.TransferableWithGuarantees import com.babylon.wallet.android.domain.model.resources.Resource import com.babylon.wallet.android.domain.model.resources.XrdResource import com.babylon.wallet.android.domain.model.resources.asLsu @@ -69,8 +70,8 @@ fun TransactionAccountCard( shape = RadixTheme.shapes.roundedRectTopMedium ) - val amountTransferables = remember(account.resources) { - account.resources.filter { it.transferable is TransferableResource.Amount } + val fungibleAmountTransferables = remember(account.resources) { + account.resources.filter { it.transferable is TransferableResource.FungibleAmount } } val nftTransferables = remember(account.resources) { @@ -90,14 +91,14 @@ fun TransactionAccountCard( } // Fungibles - amountTransferables.forEachIndexed { index, amountTransferable -> - val lastItem = if (nftTransferables.isEmpty()) index == amountTransferables.lastIndex else false + fungibleAmountTransferables.forEachIndexed { index, amountTransferable -> + val lastItem = if (nftTransferables.isEmpty()) index == fungibleAmountTransferables.lastIndex else false val shape = if (lastItem) RadixTheme.shapes.roundedRectBottomMedium else RectangleShape - val transferableAmount = amountTransferable.transferable as TransferableResource.Amount + val transferableFungibleAmount = amountTransferable.transferable as TransferableResource.FungibleAmount TransferableItemContent( modifier = Modifier.clickable { - onFungibleResourceClick(transferableAmount.resource, transferableAmount.isNewlyCreated) + onFungibleResourceClick(transferableFungibleAmount.resource, transferableFungibleAmount.isNewlyCreated) }, transferable = amountTransferable, shape = shape, @@ -128,7 +129,7 @@ fun TransactionAccountCard( modifier = Modifier.clickable { onFungibleResourceClick(transferableLsu.resource, transferableLsu.isNewlyCreated) }, - transferable = transferableLsu, + transferable = transferable, shape = shape, ) if (lastItem.not()) { @@ -153,10 +154,9 @@ fun TransactionAccountCard( poolUnitTransferables.forEachIndexed { index, transferable -> val lastItem = index == poolUnitTransferables.lastIndex val shape = if (lastItem) RadixTheme.shapes.roundedRectBottomMedium else RectangleShape - val transferablePoolUnit = transferable.transferable as TransferableResource.PoolUnitAmount TransferablePoolUnitItemContent( - transferable = transferablePoolUnit, + transferable = transferable, shape = shape, onFungibleResourceClick = onFungibleResourceClick ) @@ -252,7 +252,7 @@ private fun TransferableItemContent( horizontalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingMedium) ) { when (val resource = transferable.transferable) { - is TransferableResource.Amount -> { + is TransferableResource.FungibleAmount -> { Thumbnail.Fungible( modifier = Modifier.size(44.dp), token = resource.resource, @@ -272,7 +272,7 @@ private fun TransferableItemContent( Text( modifier = Modifier.weight(1f), text = when (val resource = transferable.transferable) { - is TransferableResource.Amount -> resource.resource.displayTitle + is TransferableResource.FungibleAmount -> resource.resource.displayTitle is TransferableResource.NFTs -> resource.resource.name else -> "" }.ifEmpty { stringResource(id = R.string.transactionReview_unknown) }, @@ -281,59 +281,67 @@ private fun TransferableItemContent( maxLines = 1, overflow = TextOverflow.Ellipsis, ) - Column( - horizontalAlignment = Alignment.End + if (transferable.hasEditableGuarantees) { + GuaranteedQuantitySection(transferable) + } + } +} + +@Composable +private fun GuaranteedQuantitySection(transferable: Transferable, modifier: Modifier = Modifier) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.End + ) { + val guaranteedQuantity = transferable.guaranteeAssertion as? GuaranteeAssertion.ForAmount + Row( + modifier = Modifier, + verticalAlignment = CenterVertically ) { - val guaranteedQuantity = transferable.guaranteeAssertion as? GuaranteeAssertion.ForAmount - Row( - modifier = Modifier, - verticalAlignment = CenterVertically - ) { - if (guaranteedQuantity != null) { - Text( - modifier = Modifier.padding(end = RadixTheme.dimensions.paddingSmall), - text = stringResource(id = R.string.transactionReview_estimated), - style = RadixTheme.typography.body2Link, - color = RadixTheme.colors.gray1, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.End - ) - } + if (guaranteedQuantity != null) { + Text( + modifier = Modifier.padding(end = RadixTheme.dimensions.paddingSmall), + text = stringResource(id = R.string.transactionReview_estimated), + style = RadixTheme.typography.body2Link, + color = RadixTheme.colors.gray1, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.End + ) + } - (transferable.transferable as? TransferableResource.Amount)?.let { - Text( - modifier = Modifier, - text = it.amount.displayableQuantity(), - style = RadixTheme.typography.secondaryHeader, - color = RadixTheme.colors.gray1, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.End - ) - } + (transferable.transferable as? TransferableWithGuarantees)?.let { + Text( + modifier = Modifier, + text = it.amount.displayableQuantity(), + style = RadixTheme.typography.secondaryHeader, + color = RadixTheme.colors.gray1, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.End + ) } - guaranteedQuantity?.let { quantity -> - Row { - Text( - modifier = Modifier.padding(end = RadixTheme.dimensions.paddingSmall), - text = stringResource(id = R.string.transactionReview_guaranteed), - style = RadixTheme.typography.body2Regular, - color = RadixTheme.colors.gray2, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.End - ) - Text( - modifier = Modifier, - text = quantity.amount.displayableQuantity(), - style = RadixTheme.typography.body2HighImportance, - color = RadixTheme.colors.gray2, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.End - ) - } + } + guaranteedQuantity?.let { quantity -> + Row { + Text( + modifier = Modifier.padding(end = RadixTheme.dimensions.paddingSmall), + text = stringResource(id = R.string.transactionReview_guaranteed), + style = RadixTheme.typography.body2Regular, + color = RadixTheme.colors.gray2, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.End + ) + Text( + modifier = Modifier, + text = quantity.amount.displayableQuantity(), + style = RadixTheme.typography.body2HighImportance, + color = RadixTheme.colors.gray2, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.End + ) } } } @@ -342,11 +350,12 @@ private fun TransferableItemContent( @Composable private fun TransferableLsuItemContent( modifier: Modifier = Modifier, - transferable: TransferableResource.LsuAmount, + transferable: Transferable, shape: Shape ) { - val lsu = remember(transferable) { - transferable.resource.asLsu() + val transferableLsu = transferable.transferable as TransferableResource.LsuAmount + val lsu = remember(transferableLsu) { + transferableLsu.resource.asLsu() } Column( modifier = modifier @@ -379,7 +388,7 @@ private fun TransferableLsuItemContent( overflow = TextOverflow.Ellipsis, ) Text( - text = transferable.validatorDetail.name, + text = transferableLsu.validatorDetail.name, style = RadixTheme.typography.body2Regular, color = RadixTheme.colors.gray2, maxLines = 1, @@ -421,13 +430,21 @@ private fun TransferableLsuItemContent( ) Text( modifier = Modifier.weight(1f), - text = transferable.xrdWorth.displayableQuantity(), + text = transferableLsu.xrdWorth.displayableQuantity(), style = RadixTheme.typography.secondaryHeader, color = RadixTheme.colors.gray1, textAlign = TextAlign.End, maxLines = 2 ) } + if (transferable.hasEditableGuarantees) { + GuaranteedQuantitySection( + transferable, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = RadixTheme.dimensions.paddingMedium) + ) + } } } @@ -538,10 +555,11 @@ private fun TransferableStakeClaimNftItemContent( @Composable private fun TransferablePoolUnitItemContent( modifier: Modifier = Modifier, - transferable: TransferableResource.PoolUnitAmount, + transferable: Transferable, shape: Shape, onFungibleResourceClick: (fungibleResource: Resource.FungibleResource, Boolean) -> Unit ) { + val transferablePoolUnit = transferable.transferable as TransferableResource.PoolUnitAmount Column( modifier = modifier .height(IntrinsicSize.Min) @@ -561,19 +579,23 @@ private fun TransferablePoolUnitItemContent( ) { Thumbnail.PoolUnit( modifier = Modifier.size(44.dp), - poolUnit = transferable.pool + poolUnit = transferablePoolUnit.poolUnit ) Column(modifier = Modifier.weight(1f)) { Text( modifier = Modifier.fillMaxWidth(), - text = transferable.pool.stake.displayTitle.ifEmpty { stringResource(id = R.string.transactionReview_unknown) }, + text = transferablePoolUnit.poolUnit.stake.displayTitle.ifEmpty { + stringResource( + id = R.string.transactionReview_unknown + ) + }, style = RadixTheme.typography.body2HighImportance, color = RadixTheme.colors.gray1, maxLines = 1, overflow = TextOverflow.Ellipsis, ) Text( - text = transferable.pool.pool?.metadata?.name().orEmpty().ifEmpty { "Unknown pool" }, // TODO crowdin + text = transferablePoolUnit.poolUnit.pool?.metadata?.name().orEmpty().ifEmpty { "Unknown pool" }, // TODO crowdin style = RadixTheme.typography.body2Regular, color = RadixTheme.colors.gray2, maxLines = 1, @@ -591,7 +613,7 @@ private fun TransferablePoolUnitItemContent( color = RadixTheme.colors.gray2, maxLines = 1 ) - val poolResources = transferable.pool.pool?.resources.orEmpty() + val poolResources = transferablePoolUnit.poolUnit.pool?.resources.orEmpty() Column(modifier = Modifier.border(1.dp, RadixTheme.colors.gray3, shape = RadixTheme.shapes.roundedRectSmall)) { poolResources.forEachIndexed { index, item -> val addDivider = index != poolResources.lastIndex @@ -601,7 +623,7 @@ private fun TransferablePoolUnitItemContent( .clickable { onFungibleResourceClick( item, - transferable.isNewlyCreated + transferablePoolUnit.isNewlyCreated ) } .fillMaxWidth() @@ -621,7 +643,7 @@ private fun TransferablePoolUnitItemContent( ) Text( modifier = Modifier.weight(1f), - text = transferable.contributionPerResource[item.resourceAddress]?.displayableQuantity().orEmpty(), + text = transferablePoolUnit.contributionPerResource[item.resourceAddress]?.displayableQuantity().orEmpty(), style = RadixTheme.typography.secondaryHeader, color = RadixTheme.colors.gray1, textAlign = TextAlign.End, @@ -633,6 +655,14 @@ private fun TransferablePoolUnitItemContent( } } } + if (transferable.hasEditableGuarantees) { + GuaranteedQuantitySection( + transferable, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = RadixTheme.dimensions.paddingMedium) + ) + } } } @@ -694,7 +724,7 @@ fun TransactionAccountCardPreview() { account = SampleDataProvider().sampleAccount(), resources = SampleDataProvider().sampleFungibleResources().map { Transferable.Withdrawing( - transferable = TransferableResource.Amount( + transferable = TransferableResource.FungibleAmount( amount = "689.203".toBigDecimal(), resource = it, isNewlyCreated = false diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountWithGuaranteesCard.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountWithGuaranteesCard.kt index a0b174dcaf..3a30f4d5cb 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountWithGuaranteesCard.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/composables/TransactionAccountWithGuaranteesCard.kt @@ -109,14 +109,14 @@ fun TransactionAccountWithGuaranteesCard( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingMedium) ) { - val transferrable = accountWithGuarantee.transferableAmount + val transferable = accountWithGuarantee.transferable Thumbnail.Fungible( modifier = Modifier.size(44.dp), - token = transferrable.resource + token = transferable.fungibleResource ) Text( modifier = Modifier.weight(1f), - text = transferrable.resource.displayTitle, + text = transferable.fungibleResource.displayTitle, style = RadixTheme.typography.body2HighImportance, color = RadixTheme.colors.gray1, maxLines = 1, @@ -140,7 +140,7 @@ fun TransactionAccountWithGuaranteesCard( ) Text( modifier = Modifier, - text = accountWithGuarantee.transferableAmount.amount.displayableQuantity(), + text = accountWithGuarantee.transferable.amount.displayableQuantity(), style = RadixTheme.typography.secondaryHeader, color = RadixTheme.colors.gray1, maxLines = 1, @@ -245,7 +245,7 @@ fun TransactionAccountWithGuaranteesCardPreview() { mutableStateOf( Owned( account = SampleDataProvider().sampleAccount(), - transferableAmount = TransferableResource.Amount( + transferable = TransferableResource.FungibleAmount( amount = BigDecimal.TEN, resource = SampleDataProvider().sampleFungibleResources()[0], isNewlyCreated = false diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/guarantees/TransactionGuaranteesDelegate.kt b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/guarantees/TransactionGuaranteesDelegate.kt index 2bdff23aba..180d5e1d45 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/transaction/guarantees/TransactionGuaranteesDelegate.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/transaction/guarantees/TransactionGuaranteesDelegate.kt @@ -2,7 +2,7 @@ package com.babylon.wallet.android.presentation.transaction.guarantees import com.babylon.wallet.android.domain.model.GuaranteeType import com.babylon.wallet.android.domain.model.Transferable -import com.babylon.wallet.android.domain.model.TransferableResource +import com.babylon.wallet.android.domain.model.TransferableWithGuarantees import com.babylon.wallet.android.presentation.common.ViewModelDelegate import com.babylon.wallet.android.presentation.transaction.AccountWithPredictedGuarantee import com.babylon.wallet.android.presentation.transaction.AccountWithTransferableResources @@ -21,11 +21,11 @@ class TransactionGuaranteesDelegate @Inject constructor() : ViewModelDelegate() transaction.to.forEach { depositing -> val resourcesWithGuarantees = depositing.resources.filterIsInstance().filter { - it.guaranteeType is GuaranteeType.Predicted && it.transferable is TransferableResource.Amount + it.guaranteeType is GuaranteeType.Predicted && it.transferable is TransferableWithGuarantees } val predictedAmounts = resourcesWithGuarantees.associate { - it.transferable as TransferableResource.Amount to it.guaranteeType as GuaranteeType.Predicted + it.transferable as TransferableWithGuarantees to it.guaranteeType as GuaranteeType.Predicted } when (depositing) { is AccountWithTransferableResources.Other -> { @@ -33,7 +33,7 @@ class TransactionGuaranteesDelegate @Inject constructor() : ViewModelDelegate { + _state.update { + it.copy( + previewType = preview.copy( + to = preview.to.mapWhen( + predicate = { depositing -> + sheet.accountsWithPredictedGuarantees.any { it.address == depositing.address } + }, + mutation = { depositing -> + depositing.updateFromGuarantees(sheet.accountsWithPredictedGuarantees) + } + ) + ), + sheetState = Sheet.None + ) + } + } - _state.update { - it.copy( - previewType = preview.copy( - to = preview.to.mapWhen( - predicate = { depositing -> - sheet.accountsWithPredictedGuarantees.any { it.address == depositing.address } - }, - mutation = { depositing -> - depositing.updateFromGuarantees(sheet.accountsWithPredictedGuarantees) - } + is PreviewType.Transfer.Pool -> { + _state.update { + it.copy( + previewType = preview.copy( + to = preview.to.mapWhen( + predicate = { depositing -> + sheet.accountsWithPredictedGuarantees.any { it.address == depositing.address } + }, + mutation = { depositing -> + depositing.updateFromGuarantees(sheet.accountsWithPredictedGuarantees) + } + ) + ), + sheetState = Sheet.None ) - ), - sheetState = Sheet.None - ) + } + } + + is PreviewType.Transfer.Staking -> { + _state.update { + it.copy( + previewType = preview.copy( + to = preview.to.mapWhen( + predicate = { depositing -> + sheet.accountsWithPredictedGuarantees.any { it.address == depositing.address } + }, + mutation = { depositing -> + depositing.updateFromGuarantees(sheet.accountsWithPredictedGuarantees) + } + ) + ), + sheetState = Sheet.None + ) + } + } } } }