Updated on 2026-08-14
This commit is contained in:
commit
63133bb8fb
117 changed files with 1915 additions and 1265 deletions
|
|
@ -5,6 +5,7 @@ import androidx.compose.ui.Modifier
|
|||
import com.tangem.core.decompose.navigation.DummyRouter
|
||||
import com.tangem.core.navigation.url.DummyUrlOpener
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.details.component.DetailsComponent
|
||||
import com.tangem.features.details.entity.DetailsFooterUM
|
||||
import com.tangem.features.details.entity.DetailsUM
|
||||
|
|
@ -18,7 +19,12 @@ internal class PreviewDetailsComponent : DetailsComponent {
|
|||
private val previewBlocks = runBlocking {
|
||||
ItemsBuilder(
|
||||
router = DummyRouter(),
|
||||
).buildAll(isWalletConnectAvailable = true, onSupportClick = {}, onBuyClick = {})
|
||||
).buildAll(
|
||||
isWalletConnectAvailable = true,
|
||||
userWalletId = UserWalletId(""),
|
||||
onSupportClick = {},
|
||||
onBuyClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
private val previewFooter = DetailsFooterUM(
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ internal class DetailsModel @Inject constructor(
|
|||
items = MutableStateFlow(
|
||||
itemsBuilder.buildAll(
|
||||
isWalletConnectAvailable = isWalletConnectAvailable,
|
||||
userWalletId = params.userWalletId,
|
||||
onSupportClick = ::sendFeedback,
|
||||
onBuyClick = ::onBuyClick,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.ui.components.block.model.BlockUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.details.entity.DetailsItemUM
|
||||
import com.tangem.features.details.impl.BuildConfig
|
||||
import com.tangem.features.details.impl.R
|
||||
|
|
@ -19,20 +20,21 @@ internal class ItemsBuilder @Inject constructor(private val router: Router) {
|
|||
|
||||
fun buildAll(
|
||||
isWalletConnectAvailable: Boolean,
|
||||
userWalletId: UserWalletId,
|
||||
onSupportClick: () -> Unit,
|
||||
onBuyClick: () -> Unit,
|
||||
): ImmutableList<DetailsItemUM> = buildList {
|
||||
buildWalletConnectBlock(isWalletConnectAvailable)?.let(::add)
|
||||
buildWalletConnectBlock(isWalletConnectAvailable, userWalletId)?.let(::add)
|
||||
buildUserWalletListBlock().let(::add)
|
||||
buildShopBlock(onBuyClick).let(::add)
|
||||
buildSettingsBlock().let(::add)
|
||||
buildSupportBlock(onSupportClick).let(::add)
|
||||
}.toImmutableList()
|
||||
|
||||
private fun buildWalletConnectBlock(isWalletConnectAvailable: Boolean): DetailsItemUM? {
|
||||
private fun buildWalletConnectBlock(isWalletConnectAvailable: Boolean, userWalletId: UserWalletId): DetailsItemUM? {
|
||||
return if (isWalletConnectAvailable) {
|
||||
DetailsItemUM.WalletConnect(
|
||||
onClick = { router.push(AppRoute.WalletConnectSessions) },
|
||||
onClick = { router.push(AppRoute.WalletConnectSessions(userWalletId)) },
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ internal class UserWalletsFetcher @Inject constructor(
|
|||
wallets.forEach { wallet ->
|
||||
val artwork = getCardImageUseCase(
|
||||
cardId = wallet.cardId,
|
||||
manufacturerName = wallet.scanResponse.card.manufacturer.name,
|
||||
firmwareVersion = wallet.scanResponse.card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
cardPublicKey = wallet.scanResponse.card.cardPublicKey,
|
||||
size = ArtworkSize.SMALL,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ import com.tangem.features.nft.collections.NFTCollectionsComponent
|
|||
import com.tangem.features.nft.collections.entity.NFTCollectionsStateUM
|
||||
import com.tangem.features.nft.collections.entity.NFTCollectionsUM
|
||||
import com.tangem.features.nft.collections.entity.transformer.*
|
||||
import com.tangem.features.nft.collections.entity.transformer.ChangeCollectionExpandedStateTransformer
|
||||
import com.tangem.features.nft.collections.entity.transformer.ToggleSearchBarTransformer
|
||||
import com.tangem.features.nft.collections.entity.transformer.UpdateDataStateTransformer
|
||||
import com.tangem.features.nft.collections.entity.transformer.UpdateSearchQueryTransformer
|
||||
import com.tangem.features.nft.impl.R
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child
|
||||
|
||||
import com.tangem.common.card.Card.Manufacturer
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.MultiWalletInnerNavigationState
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState
|
||||
|
|
@ -18,6 +20,8 @@ class MultiWalletChildParams(
|
|||
data class BackupCardInfo(
|
||||
val cardId: String,
|
||||
val cardPublicKey: ByteArray,
|
||||
val manufacturer: Manufacturer,
|
||||
val firmwareVersion: FirmwareVersion,
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ class MultiWalletBackupModel @Inject constructor(
|
|||
val backupCardInfo = MultiWalletChildParams.Backup.BackupCardInfo(
|
||||
cardId = result.data.cardId,
|
||||
cardPublicKey = result.data.cardPublicKey,
|
||||
manufacturer = result.data.manufacturer,
|
||||
firmwareVersion = result.data.firmwareVersion,
|
||||
)
|
||||
params.backups.update {
|
||||
it.copy(
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
|||
cardId = backup.card2.cardId,
|
||||
cardPublicKey = backup.card2.cardPublicKey,
|
||||
size = ArtworkSize.LARGE,
|
||||
manufacturerName = backup.card2.manufacturer.name,
|
||||
firmwareVersion = backup.card2.firmwareVersion,
|
||||
)
|
||||
_uiState.update {
|
||||
it.copy(artwork2 = ArtworkUM(artwork.verifiedArtwork, artwork.defaultUrl))
|
||||
|
|
@ -97,6 +99,8 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
|||
cardId = backup.card3.cardId,
|
||||
cardPublicKey = backup.card3.cardPublicKey,
|
||||
size = ArtworkSize.LARGE,
|
||||
manufacturerName = backup.card3.manufacturer.name,
|
||||
firmwareVersion = backup.card3.firmwareVersion,
|
||||
)
|
||||
_uiState.update {
|
||||
it.copy(artwork3 = ArtworkUM(artwork.verifiedArtwork, artwork.defaultUrl))
|
||||
|
|
@ -170,6 +174,8 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
|||
cardId = params.scanResponse.card.cardId,
|
||||
cardPublicKey = params.scanResponse.card.cardPublicKey,
|
||||
size = ArtworkSize.LARGE,
|
||||
manufacturerName = params.scanResponse.card.manufacturer.name,
|
||||
firmwareVersion = params.scanResponse.card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
)
|
||||
|
||||
_uiState.update {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import com.tangem.domain.exchange.RampStateManager
|
|||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.onramp.GetLegacyTopUpUrlUseCase
|
||||
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.NetworkAddress
|
||||
|
|
@ -39,7 +39,7 @@ import javax.inject.Inject
|
|||
internal class OnboardingNoteTopUpModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val userWalletBuilderFactory: UserWalletBuilder.Factory,
|
||||
private val getLegacyTopUpUrlUseCase: GetLegacyTopUpUrlUseCase,
|
||||
|
|
@ -137,8 +137,11 @@ internal class OnboardingNoteTopUpModel @Inject constructor(
|
|||
|
||||
private fun observeCryptoCurrencyStatus() {
|
||||
val userWalletId = userWallet?.walletId ?: return
|
||||
getPrimaryCurrencyStatusUpdatesUseCase(userWalletId = userWalletId).map { it.getOrNull() }.filterNotNull()
|
||||
.onEach(::applyCryptoCurrencyStatusToState).launchIn(modelScope)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWalletId = userWalletId)
|
||||
.map { it.getOrNull() }
|
||||
.filterNotNull()
|
||||
.onEach(::applyCryptoCurrencyStatusToState)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun applyCryptoCurrencyStatusToState(status: CryptoCurrencyStatus) {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ internal class OnboardingNoteModel @Inject constructor(
|
|||
cardId = cardInfo.cardId,
|
||||
cardPublicKey = cardInfo.cardPublicKey,
|
||||
size = ArtworkSize.LARGE,
|
||||
manufacturerName = cardInfo.manufacturer.name,
|
||||
firmwareVersion = cardInfo.firmwareVersion.toSdkFirmwareVersion(),
|
||||
)
|
||||
_uiState.update {
|
||||
it.copy(cardArtwork = ArtworkUM(artwork.verifiedArtwork, artwork.defaultUrl))
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ import com.tangem.common.core.TangemError
|
|||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.extensions.hexToBytes
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.toWrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
|
|
@ -34,7 +34,7 @@ import com.tangem.domain.models.scan.ScanResponse
|
|||
import com.tangem.domain.onboarding.SaveTwinsOnboardingShownUseCase
|
||||
import com.tangem.domain.onramp.GetLegacyTopUpUrlUseCase
|
||||
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.model.analytics.TokenReceiveAnalyticsEvent
|
||||
|
|
@ -77,7 +77,7 @@ internal class OnboardingTwinModel @Inject constructor(
|
|||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val issuersConfigStorage: IssuersConfigStorage,
|
||||
private val cardRepository: CardRepository,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val getLegacyTopUpUrlUseCase: GetLegacyTopUpUrlUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
|
|
@ -337,16 +337,16 @@ internal class OnboardingTwinModel @Inject constructor(
|
|||
setLoading(false)
|
||||
}
|
||||
|
||||
val cryptoCurrencyStatus =
|
||||
getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId).firstOrNull()?.getOrNull()
|
||||
?: run {
|
||||
setLoading(false)
|
||||
Timber.e("Unable to get currency status")
|
||||
return@coroutineScope
|
||||
}
|
||||
val cryptoCurrencyStatus = getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWallet.walletId)
|
||||
.firstOrNull()?.getOrNull()
|
||||
?: run {
|
||||
setLoading(false)
|
||||
Timber.e("Unable to get currency status")
|
||||
return@coroutineScope
|
||||
}
|
||||
|
||||
launch {
|
||||
getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWallet.walletId)
|
||||
.collect {
|
||||
it.onRight { status ->
|
||||
applyCryptoCurrencyStatusToState(status)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.onramp.GetHotCryptoUseCase
|
||||
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||
import com.tangem.features.onramp.hottokens.converter.HotTokenItemStateConverter
|
||||
|
|
@ -45,7 +45,7 @@ internal class HotCryptoModel @Inject constructor(
|
|||
paramsContainer: ParamsContainer,
|
||||
getHotCryptoUseCase: GetHotCryptoUseCase,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
|
|
@ -103,7 +103,10 @@ internal class HotCryptoModel @Inject constructor(
|
|||
|
||||
private fun onSuccessAdding(id: CryptoCurrency.ID) {
|
||||
modelScope.launch {
|
||||
getCryptoCurrencyStatusSyncUseCase(userWalletId = params.userWalletId, cryptoCurrencyId = id)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrencyId = id,
|
||||
)
|
||||
.onRight {
|
||||
bottomSheetNavigation.dismiss()
|
||||
params.onTokenClick(it)
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ internal class SendBalanceUpdater @AssistedInject constructor(
|
|||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
delayMillis = delay,
|
||||
refresh = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@ import com.tangem.domain.feedback.models.FeedbackEmailType
|
|||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.domain.qrscanning.usecases.ParseQrCodeUseCase
|
||||
import com.tangem.domain.tokens.GetCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -72,8 +71,7 @@ internal class SendModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
|
||||
|
|
@ -244,13 +242,13 @@ internal class SendModel @Inject constructor(
|
|||
isMultiCurrency: Boolean,
|
||||
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
|
||||
return if (isMultiCurrency) {
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = isSingleWalletWithToken,
|
||||
)
|
||||
} else {
|
||||
getPrimaryCurrencyStatusUpdatesUseCase(userWalletId = userWalletId)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWalletId = userWalletId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase
|
||||
import com.tangem.domain.tokens.GetCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
|
|
@ -60,7 +60,7 @@ internal class NFTSendModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val createNFTTransferTransactionUseCase: CreateNFTTransferTransactionUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
|
|
@ -183,7 +183,7 @@ internal class NFTSendModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun getCurrenciesStatusUpdates(isSingleWalletWithToken: Boolean) {
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = isSingleWalletWithToken,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ import kotlin.properties.Delegates
|
|||
internal class SendModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
|
|
@ -325,13 +325,13 @@ internal class SendModel @Inject constructor(
|
|||
isMultiCurrency: Boolean,
|
||||
): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
||||
return if (isMultiCurrency) {
|
||||
getCryptoCurrencyStatusSyncUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = isSingleWalletWithToken,
|
||||
)
|
||||
} else {
|
||||
getCryptoCurrencyStatusSyncUseCase(userWalletId = userWalletId)
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeSingleWalletSync(userWalletId = userWalletId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1048,7 +1048,6 @@ internal class SendModel @Inject constructor(
|
|||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
delayMillis = BALANCE_UPDATE_DELAY,
|
||||
refresh = true,
|
||||
)
|
||||
},
|
||||
).awaitAll()
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ internal class StakingModel @Inject constructor(
|
|||
private val stateController: StakingStateController,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
|
|
@ -920,7 +920,7 @@ internal class StakingModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
)
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrencyId,
|
||||
isSingleWalletWithTokens = false,
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ internal class StakingBalanceUpdater @AssistedInject constructor(
|
|||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
delayMillis = delay,
|
||||
refresh = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
|||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.quotes.QuotesRepositoryV2
|
||||
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetCurrencyCheckUseCase
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.model.*
|
||||
|
|
@ -54,7 +54,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
private val userWalletManager: UserWalletManager,
|
||||
private val repository: SwapRepository,
|
||||
private val allowPermissionsHandler: AllowPermissionsHandler,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusesSyncUseCase,
|
||||
private val getMultiCryptoCurrencyStatusUseCase: GetMultiCryptoCurrencyStatusUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||
private val createTransactionUseCase: CreateTransactionUseCase,
|
||||
|
|
@ -92,7 +92,7 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override suspend fun getTokensDataState(currency: CryptoCurrency): TokensDataStateExpress {
|
||||
val walletCurrencyStatuses = getMultiCryptoCurrencyStatusUseCase(userWalletId)
|
||||
val walletCurrencyStatuses = getMultiCryptoCurrencyStatusUseCase.invokeMultiWalletSync(userWalletId)
|
||||
.getOrElse { emptyList() }
|
||||
|
||||
val walletCurrencyStatusesExceptInitial = walletCurrencyStatuses
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.swap.domain.di
|
||||
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusesSyncUseCase
|
||||
import com.tangem.domain.tokens.GetMultiCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.operations.BaseCurrencyStatusOperations
|
||||
import com.tangem.feature.swap.domain.*
|
||||
import dagger.Module
|
||||
|
|
@ -28,8 +28,8 @@ internal class SwapDomainModule {
|
|||
@Singleton
|
||||
fun providesGetCryptoCurrencyStatusUseCase(
|
||||
currencyStatusOperations: BaseCurrencyStatusOperations,
|
||||
): GetCryptoCurrencyStatusesSyncUseCase {
|
||||
return GetCryptoCurrencyStatusesSyncUseCase(currencyStatusOperations)
|
||||
): GetMultiCryptoCurrencyStatusUseCase {
|
||||
return GetMultiCryptoCurrencyStatusUseCase(currencyStatusOperations)
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ import com.tangem.domain.promo.models.StoryContentIds
|
|||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.UpdateDelayedNetworkStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
|
@ -86,9 +89,8 @@ internal class SwapModel @Inject constructor(
|
|||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val analyticsErrorEventHandler: AnalyticsErrorHandler,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||
|
|
@ -98,7 +100,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val shouldShowStoriesUseCase: ShouldShowStoriesUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val getUserCountryUseCase: GetUserCountryUseCase,
|
||||
getUserCountryUseCase: GetUserCountryUseCase,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
swapInteractorFactory: SwapInteractor.Factory,
|
||||
private val urlOpener: UrlOpener,
|
||||
|
|
@ -176,8 +178,12 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
|
||||
modelScope.launch(dispatchers.io) {
|
||||
val fromStatus = getCryptoCurrencyStatusUseCase(userWalletId, initialCurrencyFrom.id).getOrNull()
|
||||
val toStatus = initialCurrencyTo?.let { getCryptoCurrencyStatusUseCase(userWalletId, it.id).getOrNull() }
|
||||
val fromStatus =
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(userWalletId, initialCurrencyFrom.id)
|
||||
.getOrNull()
|
||||
val toStatus = initialCurrencyTo?.let {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(userWalletId, it.id).getOrNull()
|
||||
}
|
||||
val wallet = getUserWalletUseCase(userWalletId).getOrNull()
|
||||
|
||||
if (fromStatus == null || wallet == null) {
|
||||
|
|
@ -861,7 +867,7 @@ internal class SwapModel @Inject constructor(
|
|||
) {
|
||||
Timber.d("Subscribe to ${coin.id} balance updates")
|
||||
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = coin.id,
|
||||
isSingleWalletWithTokens = false,
|
||||
|
|
@ -1311,7 +1317,6 @@ internal class SwapModel @Inject constructor(
|
|||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
delayMillis = UPDATE_BALANCE_DELAY_MILLIS,
|
||||
refresh = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class TokenDetailsModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
|
|
@ -117,7 +117,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
private val vibratorHapticManager: VibratorHapticManager,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val getCryptoCurrencySyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val onrampFeatureToggles: OnrampFeatureToggles,
|
||||
private val shareManager: ShareManager,
|
||||
@GlobalUiMessageSender private val uiMessageSender: UiMessageSender,
|
||||
|
|
@ -219,7 +218,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private fun initButtons() {
|
||||
// we need also init buttons before start all loading to avoid buttons blocking
|
||||
modelScope.launch {
|
||||
val currentCryptoCurrencyStatus = getCryptoCurrencySyncUseCase.invoke(
|
||||
val currentCryptoCurrencyStatus = getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = false,
|
||||
|
|
@ -300,7 +299,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
|
|
@ -364,7 +363,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
updateDelayedCurrencyStatusUseCase(
|
||||
userWalletId = userWalletId,
|
||||
network = toCryptoCurrency.network,
|
||||
refresh = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.tokens.GetCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
||||
|
|
@ -39,7 +39,7 @@ internal class TxHistoryModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
private val getCurrencyStatusUpdatesUseCase: GetCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
|
|
@ -165,7 +165,7 @@ internal class TxHistoryModel @Inject constructor(
|
|||
val userWallet: UserWallet = requireNotNull(getUserWalletUseCase(params.userWalletId).getOrNull()) {
|
||||
"User wallet not found"
|
||||
}
|
||||
getCurrencyStatusUpdatesUseCase(
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = params.userWalletId,
|
||||
currencyId = params.currency.id,
|
||||
isSingleWalletWithTokens = userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
|
|||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.settings.ShouldShowMarketsTooltipUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.TokensAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
|
|
@ -67,7 +67,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
private val walletWarningsClickIntents: WalletWarningsClickIntentsImplementor,
|
||||
private val onrampStatusFactory: OnrampStatusFactory,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val shouldShowMarketsTooltipUseCase: ShouldShowMarketsTooltipUseCase,
|
||||
|
|
@ -162,7 +162,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
|
||||
override fun onTransactionClick(txHash: String) {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
val currency = getPrimaryCurrencyStatusUpdatesUseCase.unwrap(
|
||||
val currency = getSingleCryptoCurrencyStatusUseCase.unwrap(
|
||||
userWalletId = stateHolder.getSelectedWalletId(),
|
||||
)
|
||||
?.currency
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import com.tangem.domain.promo.GetStoryContentUseCase
|
|||
import com.tangem.domain.promo.models.StoryContentIds
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.IsCryptoCurrencyCoinCouldHideUseCase
|
||||
import com.tangem.domain.tokens.RemoveCurrencyUseCase
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
|
|
@ -110,7 +110,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val isCryptoCurrencyCoinCouldHide: IsCryptoCurrencyCoinCouldHideUseCase,
|
||||
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
|
||||
private val getExploreUrlUseCase: GetExploreUrlUseCase,
|
||||
|
|
@ -489,7 +489,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
val currencyStatus = getPrimaryCurrencyStatusUpdatesUseCase.unwrap(userWalletId) ?: return@launch
|
||||
val currencyStatus = getSingleCryptoCurrencyStatusUseCase.unwrap(userWalletId) ?: return@launch
|
||||
|
||||
when (val addresses = currencyStatus.value.networkAddress) {
|
||||
is NetworkAddress.Selectable -> {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
|||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.NeverToSuggestRateAppUseCase
|
||||
import com.tangem.domain.settings.RemindToRateAppLaterUseCase
|
||||
import com.tangem.domain.tokens.FetchTokenListUseCase
|
||||
import com.tangem.domain.tokens.FetchTokenListUseCase.RefreshMode
|
||||
import com.tangem.domain.tokens.TokensFeatureToggles
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
||||
|
|
@ -91,7 +88,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val stateHolder: WalletStateController,
|
||||
private val walletEventSender: WalletEventSender,
|
||||
private val derivePublicKeysUseCase: DerivePublicKeysUseCase,
|
||||
private val fetchTokenListUseCase: FetchTokenListUseCase,
|
||||
private val setCardWasScannedUseCase: SetCardWasScannedUseCase,
|
||||
private val neverToSuggestRateAppUseCase: NeverToSuggestRateAppUseCase,
|
||||
private val remindToRateAppLaterUseCase: RemindToRateAppLaterUseCase,
|
||||
|
|
@ -105,7 +101,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val seedPhraseNotificationUseCase: SeedPhraseNotificationUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val tokensFeatureToggles: TokensFeatureToggles,
|
||||
private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
private val appRouter: AppRouter,
|
||||
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
||||
|
|
@ -148,22 +143,13 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
).fold(
|
||||
ifLeft = { Timber.e(it, "Failed to derive public keys") },
|
||||
ifRight = {
|
||||
if (tokensFeatureToggles.isNetworksLoadingRefactoringEnabled) {
|
||||
multiNetworkStatusFetcher(
|
||||
params = MultiNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
networks = missedAddressCurrencies.map(CryptoCurrency::network).toSet(),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
fetchTokenListUseCase(
|
||||
multiNetworkStatusFetcher(
|
||||
params = MultiNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
mode = RefreshMode.SKIP_CURRENCIES,
|
||||
currencies = missedAddressCurrencies,
|
||||
).onLeft {
|
||||
Timber.e("Unable to refresh token list: $it")
|
||||
}
|
||||
}
|
||||
networks = missedAddressCurrencies.map(CryptoCurrency::network).toSet(),
|
||||
),
|
||||
)
|
||||
.onLeft { Timber.e("Unable to refresh token list: $it") }
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.domain.common.util.cardTypesResolver
|
|||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
|||
|
||||
@ModelScoped
|
||||
internal class GetSingleWalletWarningsFactory @Inject constructor(
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||
|
|
@ -36,7 +36,7 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
|
|||
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
||||
|
||||
return combine(
|
||||
flow = getPrimaryCurrencyStatusUpdatesUseCase(userWallet.walletId),
|
||||
flow = getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWallet.walletId),
|
||||
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
||||
flow3 = isNeedToBackupUseCase(userWallet.walletId).conflate(),
|
||||
flow4 = getWalletsUseCase().conflate(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.domain
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -20,8 +20,8 @@ internal fun GetSelectedWalletSyncUseCase.unwrap(): UserWallet? {
|
|||
)
|
||||
}
|
||||
|
||||
internal suspend fun GetPrimaryCurrencyStatusUpdatesUseCase.unwrap(userWalletId: UserWalletId): CryptoCurrencyStatus? {
|
||||
return this(userWalletId)
|
||||
internal suspend fun GetSingleCryptoCurrencyStatusUseCase.unwrap(userWalletId: UserWalletId): CryptoCurrencyStatus? {
|
||||
return invokeSingleWallet(userWalletId)
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.filter(Either<CurrencyStatusError, CryptoCurrencyStatus>::isRight)
|
||||
|
|
@ -35,11 +35,11 @@ internal suspend fun GetPrimaryCurrencyStatusUpdatesUseCase.unwrap(userWalletId:
|
|||
)
|
||||
}
|
||||
|
||||
internal suspend fun GetPrimaryCurrencyStatusUpdatesUseCase.collectLatest(
|
||||
internal suspend fun GetSingleCryptoCurrencyStatusUseCase.collectLatest(
|
||||
userWalletId: UserWalletId,
|
||||
onRight: suspend (CryptoCurrencyStatus) -> Unit,
|
||||
) {
|
||||
this(userWalletId = userWalletId)
|
||||
invokeSingleWallet(userWalletId = userWalletId)
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.collectLatest { maybeStatus ->
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.tangem.domain.onramp.GetOnrampTransactionsUseCase
|
|||
import com.tangem.domain.onramp.OnrampRemoveTransactionUseCase
|
||||
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -29,7 +29,7 @@ internal class SingleWalletContentLoader(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val isRefresh: Boolean,
|
||||
private val stateHolder: WalletStateController,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val getSingleWalletWarningsFactory: GetSingleWalletWarningsFactory,
|
||||
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
|
||||
|
|
@ -48,7 +48,7 @@ internal class SingleWalletContentLoader(
|
|||
PrimaryCurrencySubscriber(
|
||||
userWallet = userWallet,
|
||||
stateHolder = stateHolder,
|
||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||
getSingleCryptoCurrencyStatusUseCase = getSingleCryptoCurrencyStatusUseCase,
|
||||
setWalletWithFundsFoundUseCase = setWalletWithFundsFoundUseCase,
|
||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
|
|
@ -57,7 +57,7 @@ internal class SingleWalletContentLoader(
|
|||
userWallet = userWallet,
|
||||
stateHolder = stateHolder,
|
||||
clickIntents = clickIntents,
|
||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||
getSingleCryptoCurrencyStatusUseCase = getSingleCryptoCurrencyStatusUseCase,
|
||||
getCryptoCurrencyActionsUseCase = getCryptoCurrencyActionsUseCase,
|
||||
),
|
||||
SingleWalletNotificationsSubscriber(
|
||||
|
|
@ -78,7 +78,7 @@ internal class SingleWalletContentLoader(
|
|||
clickIntents = clickIntents,
|
||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||
getSingleCryptoCurrencyStatusUseCase = getSingleCryptoCurrencyStatusUseCase,
|
||||
getOnrampTransactionsUseCase = getOnrampTransactionsUseCase,
|
||||
onrampRemoveTransactionUseCase = onrampRemoveTransactionUseCase,
|
||||
),
|
||||
|
|
@ -87,7 +87,7 @@ internal class SingleWalletContentLoader(
|
|||
isRefresh = isRefresh,
|
||||
stateHolder = stateHolder,
|
||||
clickIntents = clickIntents,
|
||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||
getSingleCryptoCurrencyStatusUseCase = getSingleCryptoCurrencyStatusUseCase,
|
||||
txHistoryItemsCountUseCase = txHistoryItemsCountUseCase,
|
||||
txHistoryItemsUseCase = txHistoryItemsUseCase,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.tangem.domain.onramp.GetOnrampTransactionsUseCase
|
|||
import com.tangem.domain.onramp.OnrampRemoveTransactionUseCase
|
||||
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
|||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletContentLoaderFactory @Inject constructor(
|
||||
private val stateHolder: WalletStateController,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val getSingleWalletWarningsFactory: GetSingleWalletWarningsFactory,
|
||||
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
|
||||
|
|
@ -42,7 +42,7 @@ internal class SingleWalletContentLoaderFactory @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
isRefresh = isRefresh,
|
||||
stateHolder = stateHolder,
|
||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||
getSingleCryptoCurrencyStatusUseCase = getSingleCryptoCurrencyStatusUseCase,
|
||||
getCryptoCurrencyActionsUseCase = getCryptoCurrencyActionsUseCase,
|
||||
getSingleWalletWarningsFactory = getSingleWalletWarningsFactory,
|
||||
setWalletWithFundsFoundUseCase = setWalletWithFundsFoundUseCase,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsParam
|
|||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -23,7 +23,7 @@ import java.math.BigDecimal
|
|||
internal class PrimaryCurrencySubscriber(
|
||||
private val userWallet: UserWallet,
|
||||
private val stateHolder: WalletStateController,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
|
|
@ -33,7 +33,7 @@ internal class PrimaryCurrencySubscriber(
|
|||
coroutineScope: CoroutineScope,
|
||||
): Flow<Pair<Either<CurrencyStatusError, CryptoCurrencyStatus>, AppCurrency>> {
|
||||
return combine(
|
||||
flow = getPrimaryCurrencyStatusUpdatesUseCase(userWallet.walletId)
|
||||
flow = getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWallet.walletId)
|
||||
.conflate()
|
||||
.distinctUntilChanged(),
|
||||
flow2 = getSelectedAppCurrencyUseCase()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -15,13 +15,13 @@ internal class SingleWalletButtonsSubscriber(
|
|||
private val userWallet: UserWallet,
|
||||
private val stateHolder: WalletStateController,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
) : WalletSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<TokenActionsState> {
|
||||
return channelFlow {
|
||||
getPrimaryCurrencyStatusUpdatesUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
||||
getSingleCryptoCurrencyStatusUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
||||
getCryptoCurrencyActionsUseCase(userWallet = userWallet, cryptoCurrencyStatus = status)
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
|||
import com.tangem.domain.onramp.GetOnrampTransactionsUseCase
|
||||
import com.tangem.domain.onramp.OnrampRemoveTransactionUseCase
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -26,7 +26,7 @@ internal class SingleWalletExpressStatusesSubscriber(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase,
|
||||
private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase,
|
||||
) : WalletSubscriber() {
|
||||
|
|
@ -35,7 +35,7 @@ internal class SingleWalletExpressStatusesSubscriber(
|
|||
coroutineScope: CoroutineScope,
|
||||
): Flow<Pair<Either<CurrencyStatusError, CryptoCurrencyStatus>, AppCurrency>> {
|
||||
return combine(
|
||||
flow = getPrimaryCurrencyStatusUpdatesUseCase(userWalletId = userWallet.walletId)
|
||||
flow = getSingleCryptoCurrencyStatusUseCase.invokeSingleWallet(userWalletId = userWallet.walletId)
|
||||
.conflate()
|
||||
.distinctUntilChanged(),
|
||||
flow2 = getSelectedAppCurrencyUseCase()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import androidx.paging.cachedIn
|
|||
import androidx.paging.map
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.txhistory.models.TxHistoryListError
|
||||
|
|
@ -35,14 +35,14 @@ internal class TxHistorySubscriber(
|
|||
private val isRefresh: Boolean,
|
||||
private val stateHolder: WalletStateController,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||
) : WalletSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<PagingData<TxHistoryItem>> {
|
||||
return flow {
|
||||
getPrimaryCurrencyStatusUpdatesUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
||||
getSingleCryptoCurrencyStatusUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
||||
val maybeTxHistoryItemCount = txHistoryItemsCountUseCase(
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = status.currency,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ package com.tangem.features.walletconnect.components
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
interface WalletConnectEntryComponent : ComposableContentComponent {
|
||||
interface Factory : ComponentFactory<Unit, WalletConnectEntryComponent>
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
interface Factory : ComponentFactory<Params, WalletConnectEntryComponent>
|
||||
}
|
||||
|
|
@ -12,9 +12,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.features.wallet.api)
|
||||
implementation(projects.features.walletconnect.api)
|
||||
implementation(projects.domain.walletConnect)
|
||||
implementation(projects.domain.walletConnect.models)
|
||||
|
||||
/** Core */
|
||||
implementation(projects.core.configToggles)
|
||||
|
|
@ -24,13 +23,22 @@ dependencies {
|
|||
implementation(projects.common.ui)
|
||||
|
||||
/** Domain models */
|
||||
implementation(projects.domain.appCurrency.models)
|
||||
implementation(projects.domain.balanceHiding.models)
|
||||
implementation(projects.domain.blockaid.models)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.qrScanning.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.walletConnect)
|
||||
implementation(projects.domain.walletConnect.models)
|
||||
|
||||
/** Domain */
|
||||
implementation(projects.domain.appCurrency)
|
||||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.domain.qrScanning)
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.wallets)
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
|
|
|
|||
|
|
@ -13,15 +13,17 @@ import com.tangem.core.decompose.context.childByContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.walletconnect.connections.model.WcConnectionsModel
|
||||
import com.tangem.features.walletconnect.connections.routes.WcConnectionsBottomSheetConfig
|
||||
import com.tangem.features.walletconnect.connections.ui.WcConnectionsContent
|
||||
|
||||
internal class ConnectionsComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcConnectionsModel = getOrCreateModel()
|
||||
private val model: WcConnectionsModel = getOrCreateModel(params)
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = model.bottomSheetNavigation,
|
||||
serializer = null,
|
||||
|
|
@ -52,4 +54,6 @@ internal class ConnectionsComponent(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ import dagger.assisted.AssistedInject
|
|||
@Suppress("UnusedPrivateMember")
|
||||
internal class DefaultWalletConnectEntryComponent @AssistedInject constructor(
|
||||
@Assisted private val appComponentContext: AppComponentContext,
|
||||
@Assisted params: Unit,
|
||||
@Assisted private val params: WalletConnectEntryComponent.Params,
|
||||
) : AppComponentContext by appComponentContext, WalletConnectEntryComponent {
|
||||
|
||||
private val contentNavigation = StackNavigation<ConnectionsInnerRoute>()
|
||||
|
|
@ -47,12 +47,18 @@ internal class DefaultWalletConnectEntryComponent @AssistedInject constructor(
|
|||
config: ConnectionsInnerRoute,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableContentComponent = when (config) {
|
||||
ConnectionsInnerRoute.Connections -> ConnectionsComponent(childByContext(componentContext))
|
||||
ConnectionsInnerRoute.Connections -> ConnectionsComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
params = ConnectionsComponent.Params(params.userWalletId),
|
||||
)
|
||||
ConnectionsInnerRoute.QrScan -> TODO("[REDACTED_JIRA]")
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : WalletConnectEntryComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: Unit): DefaultWalletConnectEntryComponent
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: WalletConnectEntryComponent.Params,
|
||||
): DefaultWalletConnectEntryComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
package com.tangem.features.walletconnect.connections.components
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.stack.Children
|
||||
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
|
|
@ -18,8 +17,10 @@ import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
|||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
|
@ -30,9 +31,8 @@ internal class WcAppInfoContainerComponent(
|
|||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcAppInfoModel = getOrCreateModel(params = params)
|
||||
private val contentNavigation = StackNavigation<WcAppInfoRoutes>()
|
||||
private val contentStack = childStack(
|
||||
source = contentNavigation,
|
||||
source = model.contentNavigation,
|
||||
serializer = WcAppInfoRoutes.serializer(),
|
||||
initialConfiguration = WcAppInfoRoutes.AppInfo,
|
||||
childFactory = ::screenChild,
|
||||
|
|
@ -51,10 +51,17 @@ internal class WcAppInfoContainerComponent(
|
|||
onDismissRequest = ::dismiss,
|
||||
content = content.active.configuration,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
onBack = ::contentBack,
|
||||
containerColor = when (content.active.configuration) {
|
||||
is WcAppInfoRoutes.Alert,
|
||||
is WcAppInfoRoutes.SelectNetworks,
|
||||
is WcAppInfoRoutes.AppInfo,
|
||||
-> TangemTheme.colors.background.tertiary
|
||||
is WcAppInfoRoutes.SelectWallet -> TangemTheme.colors.background.primary
|
||||
},
|
||||
title = { config -> Title(route = config) },
|
||||
content = {
|
||||
Children(stack = content, animation = stackAnimation()) { child ->
|
||||
Children(modifier = Modifier.animateContentSize(), stack = content) { child ->
|
||||
child.instance.Content(modifier = Modifier)
|
||||
}
|
||||
},
|
||||
|
|
@ -64,7 +71,12 @@ internal class WcAppInfoContainerComponent(
|
|||
@Composable
|
||||
private fun Title(route: WcAppInfoRoutes) {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_wallet_connect),
|
||||
title = when (route) {
|
||||
is WcAppInfoRoutes.Alert -> null
|
||||
WcAppInfoRoutes.AppInfo -> resourceReference(R.string.wc_wallet_connect)
|
||||
WcAppInfoRoutes.SelectNetworks -> TODO("[REDACTED_TASK_KEY]")
|
||||
WcAppInfoRoutes.SelectWallet -> stringReference("Choose wallet")
|
||||
},
|
||||
startIconRes = when (route) {
|
||||
is WcAppInfoRoutes.AppInfo, is WcAppInfoRoutes.Alert -> null
|
||||
is WcAppInfoRoutes.SelectNetworks, is WcAppInfoRoutes.SelectWallet -> R.drawable.ic_back_24
|
||||
|
|
@ -88,19 +100,25 @@ internal class WcAppInfoContainerComponent(
|
|||
}
|
||||
|
||||
private fun contentBack() {
|
||||
contentNavigation.pop()
|
||||
if (contentStack.value.active.configuration == WcAppInfoRoutes.AppInfo) {
|
||||
dismiss()
|
||||
} else {
|
||||
model.contentNavigation.pop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun screenChild(config: WcAppInfoRoutes, componentContext: ComponentContext): ComposableContentComponent =
|
||||
when (config) {
|
||||
is WcAppInfoRoutes.AppInfo -> WcAppInfoComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
model = model,
|
||||
)
|
||||
private fun screenChild(config: WcAppInfoRoutes, componentContext: ComponentContext): ComposableContentComponent {
|
||||
val appComponentContext = childByContext(componentContext)
|
||||
return when (config) {
|
||||
is WcAppInfoRoutes.AppInfo -> WcAppInfoComponent(appComponentContext = appComponentContext, model = model)
|
||||
is WcAppInfoRoutes.Alert -> TODO()
|
||||
WcAppInfoRoutes.SelectNetworks -> TODO()
|
||||
WcAppInfoRoutes.SelectWallet -> TODO()
|
||||
WcAppInfoRoutes.SelectWallet -> WcSelectWalletComponent(
|
||||
appComponentContext = appComponentContext,
|
||||
model = model,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val wcUrl: String, val source: WcPairRequest.Source)
|
||||
data class Params(val userWalletId: UserWalletId, val wcUrl: String, val source: WcPairRequest.Source)
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package com.tangem.features.walletconnect.connections.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.userwallet.UserWalletItem
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.components.block.TangemBlockCardColors
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class WcSelectWalletComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
private val model: WcAppInfoModel,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val walletsState by model.walletsUiState.collectAsStateWithLifecycle()
|
||||
WcSelectWalletContent(
|
||||
modifier = modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
|
||||
wallets = walletsState.wallets,
|
||||
selectedWalletId = walletsState.selectedUserWallet.walletId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcSelectWalletContent(
|
||||
wallets: ImmutableList<UserWalletItemUM>,
|
||||
selectedWalletId: UserWalletId,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
wallets.fastForEach { state ->
|
||||
key(state.id) {
|
||||
val baseModifier = Modifier
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
.clickable(onClick = state.onClick)
|
||||
val itemModifier = if (state.id == selectedWalletId) {
|
||||
baseModifier.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors.text.accent,
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
)
|
||||
} else {
|
||||
baseModifier
|
||||
}
|
||||
UserWalletItem(
|
||||
modifier = itemModifier,
|
||||
state = state,
|
||||
blockColors = TangemBlockCardColors.copy(
|
||||
containerColor = Color.Unspecified,
|
||||
disabledContainerColor = Color.Unspecified,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcSelectWalletContent_Preview() {
|
||||
TangemThemePreview {
|
||||
WcSelectWalletContent(
|
||||
modifier = Modifier
|
||||
.background(TangemTheme.colors.background.tertiary)
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
|
||||
selectedWalletId = UserWalletId("user_wallet_1".encodeToByteArray()),
|
||||
wallets = persistentListOf(
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_1".encodeToByteArray()),
|
||||
name = stringReference("Tangem 2.0"),
|
||||
information = stringReference("42 tokens"),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_2".encodeToByteArray()),
|
||||
name = stringReference("Tangem White"),
|
||||
information = stringReference("24 tokens"),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Bitcoin"),
|
||||
information = stringReference("1 token"),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_4".encodeToByteArray()),
|
||||
name = stringReference("Tangem 1.0"),
|
||||
information = stringReference("21 tokens"),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ internal sealed class WcAppInfoUM : TangemBottomSheetConfigContent {
|
|||
val appSubtitle: String,
|
||||
val notification: WcAppInfoSecurityNotification?,
|
||||
val walletName: String,
|
||||
val onWalletClick: () -> Unit,
|
||||
val networksInfo: WcNetworksInfo,
|
||||
override val connectButtonConfig: WcPrimaryButtonConfig,
|
||||
override val onDismiss: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.features.walletconnect.connections.entity
|
||||
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
internal data class WcAppInfoWalletUM(
|
||||
val wallets: ImmutableList<UserWalletItemUM>,
|
||||
val selectedUserWallet: UserWallet,
|
||||
)
|
||||
|
|
@ -1,47 +1,98 @@
|
|||
package com.tangem.features.walletconnect.connections.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.arkivanov.decompose.router.stack.pushNew
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.walletconnect.model.WcSessionApprove
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
import com.tangem.domain.walletconnect.usecase.pair.WcPairState
|
||||
import com.tangem.domain.walletconnect.usecase.pair.WcPairUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.walletconnect.connections.components.WcAppInfoContainerComponent
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoWalletUM
|
||||
import com.tangem.features.walletconnect.connections.entity.WcPrimaryButtonConfig
|
||||
import com.tangem.features.walletconnect.connections.model.transformers.WcAppInfoTransformer
|
||||
import com.tangem.features.walletconnect.connections.model.transformers.WcAppInfoWalletChangedTransformer
|
||||
import com.tangem.features.walletconnect.connections.model.transformers.WcConnectButtonProgressTransformer
|
||||
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
|
||||
import com.tangem.features.walletconnect.connections.utils.WcUserWalletsFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
import com.tangem.utils.transformer.update as transformerUpdate
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class WcAppInfoModel @Inject constructor(
|
||||
private val router: Router,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
wcPairUseCaseFactory: WcPairUseCase.Factory,
|
||||
private val router: Router,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
messageSender: UiMessageSender,
|
||||
getCardImageUseCase: GetCardImageUseCase,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params: WcAppInfoContainerComponent.Params = paramsContainer.require()
|
||||
private val wcPairUseCase = wcPairUseCaseFactory.create(WcPairRequest(uri = params.wcUrl, source = params.source))
|
||||
private val wcPairUseCase = wcPairUseCaseFactory.create(
|
||||
WcPairRequest(
|
||||
userWalletId = params.userWalletId,
|
||||
uri = params.wcUrl,
|
||||
source = params.source,
|
||||
),
|
||||
)
|
||||
private val userWalletsFetcher = WcUserWalletsFetcher(
|
||||
getWalletsUseCase = getWalletsUseCase,
|
||||
getWalletTotalBalanceUseCase = getWalletTotalBalanceUseCase,
|
||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
||||
getBalanceHidingSettingsUseCase = getBalanceHidingSettingsUseCase,
|
||||
messageSender = messageSender,
|
||||
getCardImageUseCase = getCardImageUseCase,
|
||||
onWalletSelected = ::onWalletSelected,
|
||||
)
|
||||
|
||||
private val selectedUserWalletFlow =
|
||||
MutableStateFlow(getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId })
|
||||
// TODO(wc) Doston: Temp solution, will be fixed in next PR`s
|
||||
private var proposalNetwork by Delegates.notNull<WcSessionProposal.ProposalNetwork>()
|
||||
internal var sessionProposal by Delegates.notNull<WcSessionProposal>()
|
||||
|
||||
// UI states
|
||||
internal val contentNavigation = StackNavigation<WcAppInfoRoutes>()
|
||||
val appInfoUiState: StateFlow<WcAppInfoUM>
|
||||
field = MutableStateFlow<WcAppInfoUM>(createLoadingState())
|
||||
|
||||
// TODO(wc) Doston: Temp solution, will be fixed in next PR`s
|
||||
private var userWallet by Delegates.notNull<UserWallet>()
|
||||
private var proposalNetwork by Delegates.notNull<WcSessionProposal.ProposalNetwork>()
|
||||
val walletsUiState: StateFlow<WcAppInfoWalletUM>
|
||||
field = MutableStateFlow(WcAppInfoWalletUM(persistentListOf(), selectedUserWalletFlow.value))
|
||||
|
||||
init {
|
||||
loadDAppInfo()
|
||||
combine(
|
||||
flow = userWalletsFetcher.userWallets,
|
||||
flow2 = selectedUserWalletFlow,
|
||||
transform = ::updateWalletsState,
|
||||
).launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun loadDAppInfo() {
|
||||
|
|
@ -62,14 +113,15 @@ internal class WcAppInfoModel @Inject constructor(
|
|||
}
|
||||
is WcPairState.Loading -> appInfoUiState.update { createLoadingState() }
|
||||
is WcPairState.Proposal -> {
|
||||
userWallet = state.dAppSession.proposalNetwork.keys.first { !it.isLocked }
|
||||
proposalNetwork = state.dAppSession.proposalNetwork.getValue(userWallet)
|
||||
sessionProposal = state.dAppSession
|
||||
proposalNetwork = sessionProposal.proposalNetwork.getValue(selectedUserWalletFlow.value)
|
||||
appInfoUiState.transformerUpdate(
|
||||
WcAppInfoTransformer(
|
||||
dAppSession = state.dAppSession,
|
||||
onDismiss = ::dismiss,
|
||||
onConnect = ::onConnect,
|
||||
userWallet = userWallet,
|
||||
onWalletClick = { contentNavigation.pushNew(WcAppInfoRoutes.SelectWallet) },
|
||||
userWallet = selectedUserWalletFlow.value,
|
||||
proposalNetwork = proposalNetwork,
|
||||
),
|
||||
)
|
||||
|
|
@ -87,13 +139,24 @@ internal class WcAppInfoModel @Inject constructor(
|
|||
private fun onConnect() {
|
||||
wcPairUseCase.approve(
|
||||
WcSessionApprove(
|
||||
wallet = userWallet,
|
||||
network =
|
||||
proposalNetwork.required.plus(proposalNetwork.available).toList(),
|
||||
wallet = selectedUserWalletFlow.value,
|
||||
network = proposalNetwork.required.plus(proposalNetwork.available).toList(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onWalletSelected(userWalletId: UserWalletId) {
|
||||
val selectedUserWallet = sessionProposal.proposalNetwork.keys.first { it.walletId == userWalletId }
|
||||
selectedUserWalletFlow.update { selectedUserWallet }
|
||||
proposalNetwork = sessionProposal.proposalNetwork.getValue(selectedUserWallet)
|
||||
appInfoUiState.transformerUpdate(WcAppInfoWalletChangedTransformer(selectedUserWallet, proposalNetwork))
|
||||
contentNavigation.pop()
|
||||
}
|
||||
|
||||
private fun updateWalletsState(items: ImmutableList<UserWalletItemUM>, userWallet: UserWallet) {
|
||||
walletsUiState.update { state -> state.copy(wallets = items, selectedUserWallet = userWallet) }
|
||||
}
|
||||
|
||||
private fun createLoadingState(): WcAppInfoUM.Loading {
|
||||
return WcAppInfoUM.Loading(
|
||||
onDismiss = ::dismiss,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.iconResId
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.walletconnect.model.WcSession
|
||||
|
|
@ -13,9 +14,10 @@ import com.tangem.domain.walletconnect.usecase.WcSessionsUseCase
|
|||
import com.tangem.domain.walletconnect.usecase.disconnect.WcDisconnectUseCase
|
||||
import com.tangem.features.walletconnect.connections.components.WcConnectedAppInfoComponent
|
||||
import com.tangem.features.walletconnect.connections.entity.WcConnectedAppInfoUM
|
||||
import com.tangem.features.walletconnect.connections.entity.WcNetworkInfoItem
|
||||
import com.tangem.features.walletconnect.connections.entity.WcPrimaryButtonConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
@ -56,7 +58,15 @@ internal class WcConnectedAppInfoModel @Inject constructor(
|
|||
isVerified = session.securityStatus == CheckDAppResult.SAFE,
|
||||
appSubtitle = session.sdkModel.appMetaData.description,
|
||||
walletName = session.wallet.name,
|
||||
networks = persistentListOf(), // TODO(wc): Nikolai & Doston: Where to find networks???
|
||||
networks = session.networks
|
||||
.map {
|
||||
WcNetworkInfoItem(
|
||||
id = it.id.value,
|
||||
icon = it.iconResId,
|
||||
name = it.name,
|
||||
symbol = it.currencySymbol,
|
||||
)
|
||||
}.toImmutableList(),
|
||||
disconnectButtonConfig = WcPrimaryButtonConfig(
|
||||
showProgress = false,
|
||||
enabled = true,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.arkivanov.decompose.router.slot.activate
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
|
|
@ -16,11 +17,12 @@ import com.tangem.core.ui.message.EventMessageAction
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.qrscanning.models.SourceType
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.domain.walletconnect.model.WcSession
|
||||
import com.tangem.domain.walletconnect.WcPairService
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.walletconnect.model.WcSession
|
||||
import com.tangem.domain.walletconnect.usecase.WcSessionsUseCase
|
||||
import com.tangem.domain.walletconnect.usecase.disconnect.WcDisconnectUseCase
|
||||
import com.tangem.features.walletconnect.connections.components.ConnectionsComponent
|
||||
import com.tangem.features.walletconnect.connections.entity.WcConnectionsState
|
||||
import com.tangem.features.walletconnect.connections.entity.WcConnectionsTopAppBarConfig
|
||||
import com.tangem.features.walletconnect.connections.model.transformers.WcSessionsTransformer
|
||||
|
|
@ -44,8 +46,10 @@ internal class WcConnectionsModel @Inject constructor(
|
|||
private val wcDisconnectUseCase: WcDisconnectUseCase,
|
||||
private val wcPairService: WcPairService,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<ConnectionsComponent.Params>()
|
||||
val uiState: StateFlow<WcConnectionsState>
|
||||
field = MutableStateFlow<WcConnectionsState>(getInitialState())
|
||||
val bottomSheetNavigation: SlotNavigation<WcConnectionsBottomSheetConfig> = SlotNavigation()
|
||||
|
|
@ -58,7 +62,15 @@ internal class WcConnectionsModel @Inject constructor(
|
|||
private fun listenQrUpdates() {
|
||||
listenToQrScanningUseCase(SourceType.WALLET_CONNECT)
|
||||
.getOrElse { emptyFlow() }
|
||||
.onEach { wcUrl -> wcPairService.pair(WcPairRequest(wcUrl, WcPairRequest.Source.QR)) }
|
||||
.onEach { wcUrl ->
|
||||
wcPairService.pair(
|
||||
WcPairRequest(
|
||||
userWalletId = params.userWalletId,
|
||||
uri = wcUrl,
|
||||
source = WcPairRequest.Source.QR,
|
||||
),
|
||||
)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
package com.tangem.features.walletconnect.connections.model.transformers
|
||||
|
||||
import com.domain.blockaid.models.dapp.CheckDAppResult
|
||||
import com.tangem.core.ui.extensions.iconResId
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.walletconnect.connections.entity.*
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class WcAppInfoTransformer(
|
||||
private val dAppSession: WcSessionProposal,
|
||||
private val onDismiss: () -> Unit,
|
||||
private val onConnect: () -> Unit,
|
||||
private val onWalletClick: () -> Unit,
|
||||
private val userWallet: UserWallet,
|
||||
private val proposalNetwork: WcSessionProposal.ProposalNetwork,
|
||||
) : Transformer<WcAppInfoUM> {
|
||||
|
|
@ -24,7 +23,8 @@ internal class WcAppInfoTransformer(
|
|||
appSubtitle = dAppSession.dAppMetaData.description,
|
||||
notification = createNotification(dAppSession.securityStatus),
|
||||
walletName = userWallet.name,
|
||||
networksInfo = convertNetworksInfo(proposalNetwork),
|
||||
onWalletClick = onWalletClick,
|
||||
networksInfo = WcNetworksInfoConverter.convert(proposalNetwork),
|
||||
connectButtonConfig = WcPrimaryButtonConfig(
|
||||
showProgress = false,
|
||||
enabled = proposalNetwork.missingRequired.isEmpty(),
|
||||
|
|
@ -41,26 +41,4 @@ internal class WcAppInfoTransformer(
|
|||
CheckDAppResult.FAILED_TO_VERIFY -> WcAppInfoSecurityNotification.UnknownDomain
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertNetworksInfo(proposalNetwork: WcSessionProposal.ProposalNetwork): WcNetworksInfo {
|
||||
return if (proposalNetwork.missingRequired.isNotEmpty()) {
|
||||
WcNetworksInfo.MissingRequiredNetworkInfo(
|
||||
networks = proposalNetwork.missingRequired
|
||||
.joinToString { it.name },
|
||||
)
|
||||
} else {
|
||||
WcNetworksInfo.ContainsAllRequiredNetworks(
|
||||
items = (proposalNetwork.required + proposalNetwork.available)
|
||||
.map {
|
||||
WcNetworkInfoItem(
|
||||
id = it.id.value,
|
||||
icon = it.iconResId,
|
||||
name = it.name,
|
||||
symbol = it.currencySymbol,
|
||||
)
|
||||
}
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.features.walletconnect.connections.model.transformers
|
||||
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class WcAppInfoWalletChangedTransformer(
|
||||
private val selectedUserWallet: UserWallet,
|
||||
private val proposalNetwork: WcSessionProposal.ProposalNetwork,
|
||||
) : Transformer<WcAppInfoUM> {
|
||||
override fun transform(prevState: WcAppInfoUM): WcAppInfoUM {
|
||||
val contentState = prevState as? WcAppInfoUM.Content ?: return prevState
|
||||
return contentState.copy(
|
||||
walletName = selectedUserWallet.name,
|
||||
networksInfo = WcNetworksInfoConverter.convert(proposalNetwork),
|
||||
connectButtonConfig = prevState.connectButtonConfig.copy(
|
||||
enabled = proposalNetwork.missingRequired.isEmpty(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.features.walletconnect.connections.model.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.iconResId
|
||||
import com.tangem.domain.walletconnect.model.WcSessionProposal
|
||||
import com.tangem.features.walletconnect.connections.entity.WcNetworkInfoItem
|
||||
import com.tangem.features.walletconnect.connections.entity.WcNetworksInfo
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal object WcNetworksInfoConverter : Converter<WcSessionProposal.ProposalNetwork, WcNetworksInfo> {
|
||||
override fun convert(value: WcSessionProposal.ProposalNetwork): WcNetworksInfo {
|
||||
return if (value.missingRequired.isNotEmpty()) {
|
||||
WcNetworksInfo.MissingRequiredNetworkInfo(
|
||||
networks = value.missingRequired
|
||||
.joinToString { it.name },
|
||||
)
|
||||
} else {
|
||||
WcNetworksInfo.ContainsAllRequiredNetworks(
|
||||
items = (value.required + value.available)
|
||||
.map {
|
||||
WcNetworkInfoItem(
|
||||
id = it.id.value,
|
||||
icon = it.iconResId,
|
||||
name = it.name,
|
||||
symbol = it.currencySymbol,
|
||||
)
|
||||
}
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.walletconnect.components.WcRoutingComponent
|
||||
import com.tangem.features.walletconnect.connections.components.WcAppInfoContainerComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -55,13 +55,17 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor(
|
|||
router = model.innerRouter,
|
||||
)
|
||||
return when (config) {
|
||||
is WcInnerRoute.SignMessage -> WcSignTransactionComponent(
|
||||
is WcInnerRoute.SignMessage -> WcSignTransactionContainerComponent(
|
||||
childContext,
|
||||
params = WcSignTransactionComponent.Params(config.rawRequest),
|
||||
params = WcSignTransactionContainerComponent.Params(config.rawRequest),
|
||||
)
|
||||
is WcInnerRoute.Pair -> WcAppInfoContainerComponent(
|
||||
childContext,
|
||||
WcAppInfoContainerComponent.Params(config.request.uri, config.request.source),
|
||||
WcAppInfoContainerComponent.Params(
|
||||
userWalletId = config.request.userWalletId,
|
||||
wcUrl = config.request.uri,
|
||||
source = config.request.source,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,7 +220,12 @@ private fun WcAppInfoSecondBlock(state: WcAppInfoUM.Content, modifier: Modifier
|
|||
val itemsModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(TangemTheme.dimens.spacing12)
|
||||
WalletRowItem(modifier = itemsModifier, walletName = state.walletName)
|
||||
WalletRowItem(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = state.onWalletClick)
|
||||
.then(itemsModifier),
|
||||
walletName = state.walletName,
|
||||
)
|
||||
HorizontalDivider(thickness = 1.dp, color = TangemTheme.colors.stroke.primary)
|
||||
SelectNetworksBlock(
|
||||
networksInfo = state.networksInfo,
|
||||
|
|
@ -565,6 +570,7 @@ private class WcAppInfoStateProvider : CollectionPreviewParameterProvider<WcAppI
|
|||
appSubtitle = "react-app.walletconnect.com",
|
||||
notification = WcAppInfoSecurityNotification.SecurityRisk,
|
||||
walletName = "Tangem 2.0",
|
||||
onWalletClick = {},
|
||||
networksInfo = WcNetworksInfo.ContainsAllRequiredNetworks(
|
||||
items = persistentListOf(
|
||||
WcNetworkInfoItem(
|
||||
|
|
@ -604,6 +610,7 @@ private class WcAppInfoStateProvider : CollectionPreviewParameterProvider<WcAppI
|
|||
appSubtitle = "react-app.walletconnect.com",
|
||||
notification = WcAppInfoSecurityNotification.UnknownDomain,
|
||||
walletName = "Tangem 2.0",
|
||||
onWalletClick = {},
|
||||
networksInfo = WcNetworksInfo.MissingRequiredNetworkInfo(networks = "Solana"),
|
||||
onDismiss = {},
|
||||
connectButtonConfig = WcPrimaryButtonConfig(showProgress = false, enabled = true, onClick = {}),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,140 @@
|
|||
package com.tangem.features.walletconnect.connections.utils
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.error.SelectedAppCurrencyError
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.BalanceHidingSettings
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.lce.lce
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.core.utils.toLce
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.tokens.model.TotalFiatBalance
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class WcUserWalletsFetcher(
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
private val onWalletSelected: (UserWalletId) -> Unit,
|
||||
) {
|
||||
|
||||
private var loadedArtworks: HashMap<UserWalletId, ArtworkModel> = hashMapOf()
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val userWallets: Flow<ImmutableList<UserWalletItemUM>> = getWalletsUseCase().transformLatest { wallets ->
|
||||
val uiModels = UserWalletItemUMConverter(onClick = onWalletSelected)
|
||||
.convertList(wallets)
|
||||
.toImmutableList()
|
||||
|
||||
emit(uiModels)
|
||||
combine(
|
||||
flow = getSelectedAppCurrencyUseCase().distinctUntilChanged(),
|
||||
flow2 = getBalanceHidingSettingsUseCase().distinctUntilChanged(),
|
||||
flow3 = getWalletTotalBalanceUseCase(wallets.map(UserWallet::walletId)).distinctUntilChanged(),
|
||||
flow4 = loadArtworks(wallets),
|
||||
) { maybeAppCurrency, balanceHidingSettings, maybeBalances, artworks ->
|
||||
val models = createUiModels(
|
||||
wallets = wallets,
|
||||
maybeAppCurrency = maybeAppCurrency,
|
||||
maybeBalances = maybeBalances,
|
||||
balanceHidingSettings = balanceHidingSettings,
|
||||
artworks = artworks,
|
||||
).getOrElse(
|
||||
ifLoading = { return@combine },
|
||||
ifError = {
|
||||
val message = resourceReference(R.string.common_unknown_error)
|
||||
messageSender.send(SnackbarMessage(message))
|
||||
|
||||
return@combine
|
||||
},
|
||||
)
|
||||
|
||||
emit(models)
|
||||
}.collect()
|
||||
}
|
||||
|
||||
private fun loadArtworks(wallets: List<UserWallet>): Flow<HashMap<UserWalletId, ArtworkModel>> {
|
||||
return flow {
|
||||
emit(hashMapOf()) // emits right away so the transform doesn't wait for the images' loading to finish
|
||||
wallets.forEach { wallet ->
|
||||
val card = wallet.scanResponse.card
|
||||
val artwork = getCardImageUseCase(
|
||||
cardId = wallet.cardId,
|
||||
cardPublicKey = card.cardPublicKey,
|
||||
size = ArtworkSize.SMALL,
|
||||
manufacturerName = card.manufacturer.name,
|
||||
firmwareVersion = card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
)
|
||||
loadedArtworks[wallet.walletId] = artwork
|
||||
emit(loadedArtworks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createUiModels(
|
||||
wallets: List<UserWallet>,
|
||||
maybeAppCurrency: Either<SelectedAppCurrencyError, AppCurrency>,
|
||||
maybeBalances: Lce<TokenListError, Map<UserWalletId, TotalFiatBalance>>,
|
||||
balanceHidingSettings: BalanceHidingSettings,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
): Lce<Error, ImmutableList<UserWalletItemUM>> = lce {
|
||||
val balances = withError(
|
||||
transform = { Error.UnableToGetBalances },
|
||||
block = {
|
||||
maybeBalances.bindOrNull().orEmpty()
|
||||
.filterKeys { userWalletId -> wallets.any { it.walletId == userWalletId } }
|
||||
.mapKeys { entry -> wallets.first { it.walletId == entry.key } }
|
||||
},
|
||||
)
|
||||
|
||||
val appCurrency = withError(
|
||||
transform = { Error.UnableToGetAppCurrency },
|
||||
block = { maybeAppCurrency.toLce().bind() },
|
||||
)
|
||||
|
||||
balances
|
||||
.map { (userWallet, balance) ->
|
||||
UserWalletItemUMConverter(
|
||||
onClick = onWalletSelected,
|
||||
appCurrency = appCurrency,
|
||||
balance = balance,
|
||||
isBalanceHidden = balanceHidingSettings.isBalanceHidden,
|
||||
artwork = artworks[userWallet.walletId],
|
||||
)
|
||||
.convert(userWallet)
|
||||
}
|
||||
.toImmutableList()
|
||||
}
|
||||
|
||||
sealed class Error {
|
||||
|
||||
data object UnableToGetAppCurrency : Error()
|
||||
|
||||
data object UnableToGetBalances : Error()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +1,28 @@
|
|||
package com.tangem.features.walletconnect.transaction.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheet
|
||||
import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheetContent
|
||||
|
||||
internal class WcSignTransactionComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val model: WcSignTransactionModel,
|
||||
private val transactionInfoOnClick: () -> Unit,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcSignTransactionModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val content by model.uiState.collectAsStateWithLifecycle()
|
||||
content?.let {
|
||||
WcSignTransactionModalBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = it.actions.onDismiss,
|
||||
content = it,
|
||||
),
|
||||
val content = model.uiState.collectAsStateWithLifecycle().value
|
||||
|
||||
if (content != null) {
|
||||
WcSignTransactionModalBottomSheetContent(
|
||||
state = content,
|
||||
onClickTransactionRequest = transactionInfoOnClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val rawRequest: WcSdkSessionRequest)
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package com.tangem.features.walletconnect.transaction.components
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.stack.Children
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.navigate
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.routes.WcSignTransactionRoutes
|
||||
|
||||
internal class WcSignTransactionContainerComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcSignTransactionModel = getOrCreateModel(params = params)
|
||||
private val contentNavigation = StackNavigation<WcSignTransactionRoutes>()
|
||||
private val contentStack = childStack(
|
||||
source = contentNavigation,
|
||||
serializer = WcSignTransactionRoutes.serializer(),
|
||||
initialConfiguration = WcSignTransactionRoutes.Transaction,
|
||||
childFactory = ::screenChild,
|
||||
)
|
||||
|
||||
private fun dismiss() {
|
||||
model.dismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val content by contentStack.subscribeAsState()
|
||||
TangemModalBottomSheet<WcSignTransactionRoutes>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = ::dismiss,
|
||||
content = content.active.configuration,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = { config -> Title(route = config) },
|
||||
content = {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
Children(stack = content) { child ->
|
||||
child.instance.Content(modifier = Modifier)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Title(route: WcSignTransactionRoutes) {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_wallet_connect),
|
||||
startIconRes = when (route) {
|
||||
is WcSignTransactionRoutes.Transaction -> null
|
||||
else -> R.drawable.ic_back_24
|
||||
},
|
||||
onStartClick = when (route) {
|
||||
is WcSignTransactionRoutes.Transaction -> null
|
||||
else -> ::toTransaction
|
||||
},
|
||||
endIconRes = when (route) {
|
||||
is WcSignTransactionRoutes.Transaction -> R.drawable.ic_close_24
|
||||
else -> null
|
||||
},
|
||||
onEndClick = when (route) {
|
||||
is WcSignTransactionRoutes.Transaction -> ::dismiss
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun toTransactionRequestInfo() {
|
||||
contentNavigation.navigate {
|
||||
listOf(WcSignTransactionRoutes.TransactionRequestInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toTransaction() {
|
||||
contentNavigation.navigate {
|
||||
listOf(WcSignTransactionRoutes.Transaction)
|
||||
}
|
||||
}
|
||||
|
||||
private fun screenChild(
|
||||
config: WcSignTransactionRoutes,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableContentComponent = when (config) {
|
||||
is WcSignTransactionRoutes.Transaction -> WcSignTransactionComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
model = model,
|
||||
transactionInfoOnClick = ::toTransactionRequestInfo,
|
||||
)
|
||||
is WcSignTransactionRoutes.TransactionRequestInfo -> WcSignTransactionRequestInfoComponent(
|
||||
appComponentContext = childByContext(componentContext),
|
||||
model = model,
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(val rawRequest: WcSdkSessionRequest)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.features.walletconnect.transaction.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.ui.common.TransactionRequestInfoContent
|
||||
|
||||
internal class WcSignTransactionRequestInfoComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val model: WcSignTransactionModel,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val content = model.uiState.collectAsStateWithLifecycle().value
|
||||
|
||||
if (content != null) {
|
||||
TransactionRequestInfoContent(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.tangem.features.walletconnect.transaction.entity
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Immutable
|
||||
internal data class WcSignTransactionUM(
|
||||
val actions: WcTransactionActionsUM,
|
||||
val transaction: WcTransactionUM,
|
||||
val transactionRequestInfo: WcTransactionRequestInfoUM,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionUM(
|
||||
val appName: String,
|
||||
val appIcon: String,
|
||||
val isVerified: Boolean,
|
||||
val appSubtitle: String,
|
||||
val walletName: String,
|
||||
val networkInfo: WcNetworkInfoUM,
|
||||
val addressText: String? = null,
|
||||
val networkFee: String? = null,
|
||||
val isLoading: Boolean = false,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionRequestInfoUM(
|
||||
val blocks: ImmutableList<WcTransactionRequestBlockUM>,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionRequestBlockUM(
|
||||
val info: ImmutableList<WcTransactionRequestInfoItemUM>,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionRequestInfoItemUM(
|
||||
val title: TextReference,
|
||||
val description: String = "",
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionActionsUM(
|
||||
val onDismiss: () -> Unit,
|
||||
val onSign: () -> Unit,
|
||||
val onCopy: () -> Unit,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcNetworkInfoUM(
|
||||
val name: String,
|
||||
@DrawableRes val iconRes: Int,
|
||||
)
|
||||
|
|
@ -10,9 +10,9 @@ import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
|
|||
import com.tangem.domain.walletconnect.usecase.method.WcSignState
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSignStep
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSignUseCase
|
||||
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent
|
||||
import com.tangem.features.walletconnect.transaction.entity.sign.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.utils.toUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -35,7 +35,7 @@ internal class WcSignTransactionModel @Inject constructor(
|
|||
private val _uiState = MutableStateFlow<WcSignTransactionUM?>(null)
|
||||
val uiState: StateFlow<WcSignTransactionUM?> = _uiState
|
||||
|
||||
private val params = paramsContainer.require<WcSignTransactionComponent.Params>()
|
||||
private val params = paramsContainer.require<WcSignTransactionContainerComponent.Params>()
|
||||
|
||||
init {
|
||||
modelScope.launch {
|
||||
|
|
@ -47,10 +47,8 @@ internal class WcSignTransactionModel @Inject constructor(
|
|||
signState = signState,
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = { cancel(useCase) },
|
||||
onBack = ::showTransactionState,
|
||||
activeButtonOnClick = useCase::sign,
|
||||
onSign = useCase::sign,
|
||||
onCopy = { copyData(useCase.rawSdkRequest.request.params) },
|
||||
transactionRequestOnClick = ::showTransactionRequestState,
|
||||
),
|
||||
)
|
||||
_uiState.emit(signTransactionUM)
|
||||
|
|
@ -59,6 +57,10 @@ internal class WcSignTransactionModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
_uiState.value?.actions?.onDismiss?.invoke() ?: router.pop()
|
||||
}
|
||||
|
||||
private fun signingIsDone(signState: WcSignState<*>): Boolean {
|
||||
(signState.domainStep as? WcSignStep.Result)?.result?.let {
|
||||
router.pop()
|
||||
|
|
@ -75,12 +77,4 @@ internal class WcSignTransactionModel @Inject constructor(
|
|||
private fun copyData(text: String) {
|
||||
clipboardManager.setText(text = text, isSensitive = true)
|
||||
}
|
||||
|
||||
private fun showTransactionRequestState() {
|
||||
_uiState.value = _uiState.value?.copy(state = WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO)
|
||||
}
|
||||
|
||||
private fun showTransactionState() {
|
||||
_uiState.value = _uiState.value?.copy(state = WcSignTransactionUM.State.TRANSACTION)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.walletconnect.transaction.routes
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@Immutable
|
||||
internal sealed class WcSignTransactionRoutes : TangemBottomSheetConfigContent {
|
||||
@Serializable
|
||||
data object Transaction : WcSignTransactionRoutes()
|
||||
|
||||
@Serializable
|
||||
data object TransactionRequestInfo : WcSignTransactionRoutes()
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.*
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
private const val MIN_HEIGHT_SCREEN_PERCENT = 0.35f
|
||||
private const val MAX_HEIGHT_SCREEN_PERCENT = 0.75f
|
||||
|
||||
@Composable
|
||||
internal fun TransactionRequestInfoContent(state: WcSignTransactionUM) {
|
||||
val screenHeight = LocalConfiguration.current.screenHeightDp
|
||||
val minHeight = (screenHeight * MIN_HEIGHT_SCREEN_PERCENT).dp
|
||||
val maxHeight = (screenHeight * MAX_HEIGHT_SCREEN_PERCENT).dp
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = minHeight, max = maxHeight)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
contentPadding = PaddingValues(top = TangemTheme.dimens.spacing8, bottom = TangemTheme.dimens.spacing70),
|
||||
) {
|
||||
items(state.transactionRequestInfo.blocks) { block ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
top = TangemTheme.dimens.spacing20,
|
||||
),
|
||||
) {
|
||||
block.info.forEach { item ->
|
||||
Text(
|
||||
text = item.title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
if (item.description.isNotEmpty()) {
|
||||
Text(
|
||||
text = item.description,
|
||||
modifier = Modifier.padding(
|
||||
top = TangemTheme.dimens.spacing4,
|
||||
bottom = TangemTheme.dimens.spacing20,
|
||||
),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.size(TangemTheme.dimens.size12))
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.size(TangemTheme.dimens.size20))
|
||||
}
|
||||
}
|
||||
|
||||
SecondaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = TangemTheme.dimens.spacing20)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.wc_copy_data_button_text),
|
||||
onClick = state.actions.onCopy,
|
||||
iconResId = R.drawable.ic_copy_24,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcSignTransactionRequestInfoBottomSheetPreview(
|
||||
@PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
TangemModalBottomSheet<WcSignTransactionUM>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = {},
|
||||
content = state,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wc_transaction_request_title),
|
||||
endIconRes = null,
|
||||
onEndClick = {},
|
||||
startIconRes = R.drawable.ic_back_24,
|
||||
onStartClick = {},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
TransactionRequestInfoContent(state = state)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider<WcSignTransactionUM>(
|
||||
listOf(
|
||||
WcSignTransactionUM(
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onSign = {},
|
||||
onCopy = {},
|
||||
),
|
||||
),
|
||||
WcSignTransactionUM(
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
addressText = "0x345FF...34FA",
|
||||
networkFee = "~ 0.22 $",
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_transaction_info_to_title),
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.settings_wallet_name_title),
|
||||
description = "Bob",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_common_wallet),
|
||||
description = "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onSign = {},
|
||||
onCopy = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun WcAddressItem(addressText: String, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(R.drawable.ic_user_square_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing8)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_address),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing16)
|
||||
.weight(1f),
|
||||
text = addressText,
|
||||
textAlign = TextAlign.End,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun WcNetworkFeeItem(networkFeeText: String, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(R.drawable.ic_fee_new_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens.spacing8),
|
||||
text = stringResourceSafe(R.string.common_network_fee_title),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing6)
|
||||
.size(TangemTheme.dimens.size16),
|
||||
painter = painterResource(id = R.drawable.ic_information_24),
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
Text(
|
||||
text = networkFeeText,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing6))
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.size(width = TangemTheme.dimens.size18, height = TangemTheme.dimens.size24),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ internal fun WcNetworkItem(networkInfo: WcNetworkInfoUM, modifier: Modifier = Mo
|
|||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing4)
|
||||
.padding(start = TangemTheme.dimens.spacing8)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_network),
|
||||
style = TangemTheme.typography.body1,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ internal fun WcWalletItem(walletName: String, modifier: Modifier = Modifier) {
|
|||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing4)
|
||||
.padding(start = TangemTheme.dimens.spacing8)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.manage_tokens_network_selector_wallet),
|
||||
style = TangemTheme.typography.body1,
|
||||
|
|
|
|||
|
|
@ -1,268 +0,0 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.sign
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.sign.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestInfoContent
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun WcSignTransactionModalBottomSheet(config: TangemBottomSheetConfig) {
|
||||
TangemModalBottomSheet<WcSignTransactionUM>(
|
||||
config = config,
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = { state ->
|
||||
TangemModalBottomSheetTitle(
|
||||
title = when (state.state) {
|
||||
WcSignTransactionUM.State.TRANSACTION -> {
|
||||
resourceReference(R.string.wallet_connect_title)
|
||||
}
|
||||
WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO -> {
|
||||
resourceReference(R.string.wc_transaction_request_title)
|
||||
}
|
||||
},
|
||||
endIconRes = R.drawable.ic_close_24.takeIf {
|
||||
state.state == WcSignTransactionUM.State.TRANSACTION
|
||||
},
|
||||
onEndClick = state.actions.onDismiss,
|
||||
startIconRes = R.drawable.ic_back_24.takeIf {
|
||||
state.state == WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO
|
||||
},
|
||||
onStartClick = state.actions.onBack,
|
||||
)
|
||||
},
|
||||
content = { state ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
when (state.state) {
|
||||
WcSignTransactionUM.State.TRANSACTION -> {
|
||||
WcTransactionModalBottomSheetContent(state.transaction, state.actions)
|
||||
}
|
||||
WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO -> {
|
||||
WcTransactionRequestInfoContent(state.transactionRequestInfo, state.actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcSignTransactionBottomSheetPreview(
|
||||
@PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
WcSignTransactionModalBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = {},
|
||||
content = state,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider<WcSignTransactionUM>(
|
||||
listOf(
|
||||
WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION,
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onBack = {},
|
||||
activeButtonOnClick = {},
|
||||
onCopy = {},
|
||||
transactionRequestOnClick = {},
|
||||
),
|
||||
),
|
||||
WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO,
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onBack = {},
|
||||
activeButtonOnClick = {},
|
||||
onCopy = {},
|
||||
transactionRequestOnClick = {},
|
||||
),
|
||||
),
|
||||
WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION,
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
addressText = "0x345FF...34FA",
|
||||
networkFee = "~ 0.22 $",
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_transaction_info_to_title),
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.settings_wallet_name_title),
|
||||
description = "Bob",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_common_wallet),
|
||||
description = "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onBack = {},
|
||||
activeButtonOnClick = {},
|
||||
onCopy = {},
|
||||
transactionRequestOnClick = {},
|
||||
),
|
||||
),
|
||||
WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO,
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
addressText = "0x345FF...34FA",
|
||||
networkFee = "~ 0.22 $",
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
blocks = persistentListOf(
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = "personal_sign",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = "Hello! My name is John Dow. test@tange.com",
|
||||
),
|
||||
),
|
||||
),
|
||||
WcTransactionRequestBlockUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_transaction_info_to_title),
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.settings_wallet_name_title),
|
||||
description = "Bob",
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_common_wallet),
|
||||
description = "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onBack = {},
|
||||
activeButtonOnClick = {},
|
||||
onCopy = {},
|
||||
transactionRequestOnClick = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.sign
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.*
|
||||
import com.tangem.features.walletconnect.transaction.ui.common.*
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun WcSignTransactionModalBottomSheetContent(
|
||||
state: WcSignTransactionUM,
|
||||
onClickTransactionRequest: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action)
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
RequestFromItem()
|
||||
WcAppInfoItem(
|
||||
iconUrl = state.transaction.appIcon,
|
||||
title = state.transaction.appName,
|
||||
subtitle = state.transaction.appSubtitle,
|
||||
isVerified = state.transaction.isVerified,
|
||||
)
|
||||
DividerWithPadding(start = 0.dp, end = 0.dp)
|
||||
WcTransactionRequestItem(
|
||||
iconRes = R.drawable.ic_doc_new_24,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { onClickTransactionRequest() }
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
)
|
||||
}
|
||||
Column(modifier = Modifier.padding(top = TangemTheme.dimens.spacing16)) {
|
||||
WcSignTransactionItems(state)
|
||||
WcTransactionRequestButtons(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
|
||||
onDismiss = state.actions.onDismiss,
|
||||
onSign = state.actions.onSign,
|
||||
isLoading = state.transaction.isLoading,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WcSignTransactionItems(state: WcSignTransactionUM) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action)
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
val itemsModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(TangemTheme.dimens.spacing12)
|
||||
|
||||
DividerWithPadding(start = 0.dp, end = 0.dp)
|
||||
WcWalletItem(
|
||||
modifier = itemsModifier,
|
||||
walletName = state.transaction.walletName,
|
||||
)
|
||||
DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12)
|
||||
WcNetworkItem(
|
||||
modifier = itemsModifier,
|
||||
networkInfo = state.transaction.networkInfo,
|
||||
)
|
||||
if (!state.transaction.addressText.isNullOrEmpty()) {
|
||||
DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12)
|
||||
WcAddressItem(
|
||||
modifier = itemsModifier,
|
||||
addressText = state.transaction.addressText,
|
||||
)
|
||||
}
|
||||
if (!state.transaction.networkFee.isNullOrEmpty()) {
|
||||
DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12)
|
||||
WcNetworkFeeItem(
|
||||
modifier = itemsModifier,
|
||||
networkFeeText = state.transaction.networkFee,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DividerWithPadding(start: Dp, end: Dp) {
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(
|
||||
start = start,
|
||||
end = end,
|
||||
),
|
||||
thickness = TangemTheme.dimens.size1,
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun WcSignTransactionBottomSheetPreview(
|
||||
@PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
TangemModalBottomSheet<WcSignTransactionUM>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = {},
|
||||
content = state,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.wallet_connect_title),
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = {},
|
||||
startIconRes = null,
|
||||
onStartClick = {},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
WcSignTransactionModalBottomSheetContent(state = state, onClickTransactionRequest = {})
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider<WcSignTransactionUM>(
|
||||
listOf(
|
||||
WcSignTransactionUM(
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(persistentListOf()),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onSign = {},
|
||||
onCopy = {},
|
||||
),
|
||||
),
|
||||
WcSignTransactionUM(
|
||||
transaction = WcTransactionUM(
|
||||
appName = "React App",
|
||||
appIcon = "",
|
||||
isVerified = true,
|
||||
appSubtitle = "react-app.walletconnect.com",
|
||||
walletName = "Tangem 2.0",
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
addressText = "0x345FF...34FA",
|
||||
networkFee = "~ 0.22 $",
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(persistentListOf()),
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = {},
|
||||
onSign = {},
|
||||
onCopy = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.features.walletconnect.transaction.utils
|
||||
|
||||
const val ADDRESS_FIRST_PART_LENGTH = 7
|
||||
const val ADDRESS_SECOND_PART_LENGTH = 4
|
||||
|
||||
internal fun String.toShortAddressText() =
|
||||
"${take(ADDRESS_FIRST_PART_LENGTH)}...${takeLast(ADDRESS_SECOND_PART_LENGTH)}"
|
||||
|
|
@ -11,13 +11,13 @@ import com.tangem.domain.walletconnect.usecase.method.WcSignState
|
|||
import com.tangem.domain.walletconnect.usecase.method.WcSignStep
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSignUseCase
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.sign.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestBlockUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
|
|
@ -47,7 +47,6 @@ private fun WcMessageSignUseCase.signTypedDataToUM(
|
|||
signModel: WcMessageSignUseCase.SignModel,
|
||||
actions: WcTransactionActionsUM,
|
||||
) = WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION,
|
||||
actions = actions,
|
||||
transaction = WcTransactionUM(
|
||||
appName = session.sdkModel.appMetaData.name,
|
||||
|
|
@ -60,7 +59,6 @@ private fun WcMessageSignUseCase.signTypedDataToUM(
|
|||
iconRes = getActiveIconRes(network.id.value),
|
||||
),
|
||||
addressText = walletAddress.toShortAddressText(),
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
isLoading = signState.domainStep == WcSignStep.Signing,
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
|
|
@ -94,7 +92,6 @@ private fun WcMessageSignUseCase.messageSignToUM(
|
|||
signModel: WcMessageSignUseCase.SignModel,
|
||||
actions: WcTransactionActionsUM,
|
||||
) = WcSignTransactionUM(
|
||||
state = WcSignTransactionUM.State.TRANSACTION,
|
||||
actions = actions,
|
||||
transaction = WcTransactionUM(
|
||||
appName = session.sdkModel.appMetaData.name,
|
||||
|
|
@ -106,7 +103,6 @@ private fun WcMessageSignUseCase.messageSignToUM(
|
|||
name = network.name,
|
||||
iconRes = getActiveIconRes(network.id.value),
|
||||
),
|
||||
activeButtonText = resourceReference(R.string.common_sign),
|
||||
isLoading = signState.domainStep == WcSignStep.Signing,
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue