Updated on 2026-08-14
This commit is contained in:
commit
6a342ab06b
16 changed files with 217 additions and 78 deletions
|
|
@ -10,6 +10,7 @@ import com.orhanobut.logger.AndroidLogAdapter
|
|||
import com.orhanobut.logger.Logger
|
||||
import com.tangem.Log
|
||||
import com.tangem.LogFormat
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
||||
|
|
@ -159,6 +160,9 @@ internal class TapApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
@Inject
|
||||
lateinit var testerFeatureToggles: TesterFeatureToggles
|
||||
|
||||
@Inject
|
||||
lateinit var blockchainWalletManagerFactory: WalletManagerFactory
|
||||
// endregion Injected
|
||||
|
||||
override fun onCreate() {
|
||||
|
|
@ -236,6 +240,7 @@ internal class TapApplication : Application(), ImageLoaderFactory {
|
|||
sendFeatureToggles = sendFeatureToggles,
|
||||
derivationsRepository = derivationsRepository,
|
||||
testerFeatureToggles = testerFeatureToggles,
|
||||
blockchainWalletManagerFactory = blockchainWalletManagerFactory,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.datasource.di.SdkMoshi
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
||||
|
|
@ -24,7 +24,7 @@ internal object WalletManagersFacadeModule {
|
|||
fun provideWalletManagersFacade(
|
||||
walletManagersStore: WalletManagersStore,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
configManager: ConfigManager,
|
||||
blockchainWalletManagerFactory: WalletManagerFactory,
|
||||
mnemonicRepository: MnemonicRepository,
|
||||
assetReader: AssetReader,
|
||||
@SdkMoshi moshi: Moshi,
|
||||
|
|
@ -32,7 +32,7 @@ internal object WalletManagersFacadeModule {
|
|||
return DefaultWalletManagersFacade(
|
||||
walletManagersStore = walletManagersStore,
|
||||
userWalletsStore = userWalletsStore,
|
||||
configManager = configManager,
|
||||
blockchainWalletManagerFactory = blockchainWalletManagerFactory,
|
||||
assetReader = assetReader,
|
||||
moshi = moshi,
|
||||
mnemonic = mnemonicRepository.generateDefaultMnemonic(),
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainSdkConfig
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.operations.attestation.Attestation
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
|
|
@ -30,18 +30,15 @@ class TapWalletManager(
|
|||
private val dispatchers: CoroutineDispatcherProvider = AppCoroutineDispatcherProvider(),
|
||||
) {
|
||||
|
||||
private val blockchainSdkConfig by lazy {
|
||||
store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig()
|
||||
}
|
||||
|
||||
private var loadUserWalletDataJob: Job? = null
|
||||
set(value) {
|
||||
field?.cancel()
|
||||
field = value
|
||||
}
|
||||
|
||||
val walletManagerFactory: WalletManagerFactory
|
||||
by lazy { WalletManagerFactory(blockchainSdkConfig) }
|
||||
val walletManagerFactory: WalletManagerFactory by lazy {
|
||||
store.state.daggerGraphState.get(DaggerGraphState::blockchainWalletManagerFactory)
|
||||
}
|
||||
|
||||
suspend fun onWalletSelected(userWallet: UserWallet, sendAnalyticsEvent: Boolean) {
|
||||
// If a previous job was running, it gets cancelled before the new one starts,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.proxy.redux
|
||||
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
|
|
@ -57,6 +58,7 @@ data class DaggerGraphState(
|
|||
val currenciesRepository: CurrenciesRepository? = null,
|
||||
val derivationsRepository: DerivationsRepository? = null,
|
||||
val testerFeatureToggles: TesterFeatureToggles? = null,
|
||||
val blockchainWalletManagerFactory: WalletManagerFactory? = null,
|
||||
) : StateType {
|
||||
|
||||
inline fun <reified T> get(getDependency: DaggerGraphState.() -> T?): T {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.datasource.local.blockchain.DefaultBlockchainDataStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object BlockchainWalletManagerFactoryModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBlockchainWalletManagerFactory(
|
||||
configManager: ConfigManager,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
): WalletManagerFactory {
|
||||
return WalletManagerFactory(
|
||||
config = configManager.config.blockchainSdkConfig,
|
||||
blockchainDataStorage = DefaultBlockchainDataStorage(appPreferencesStore),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.datasource.local.blockchain
|
||||
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import com.tangem.blockchain.common.datastorage.BlockchainDataStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrNull
|
||||
|
||||
/**
|
||||
* [BlockchainDataStorage] implementation
|
||||
*
|
||||
* @property appPreferencesStore app preferences store
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class DefaultBlockchainDataStorage(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : BlockchainDataStorage {
|
||||
|
||||
override suspend fun getOrNull(key: String): String? {
|
||||
return appPreferencesStore.getSyncOrNull(key = stringPreferencesKey(name = key))
|
||||
}
|
||||
|
||||
override suspend fun store(key: String, value: String) {
|
||||
appPreferencesStore.edit {
|
||||
it[stringPreferencesKey(key)] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ import com.tangem.blockchain.extensions.SimpleResult
|
|||
import com.tangem.crypto.bip39.Mnemonic
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
||||
import com.tangem.domain.common.util.hasDerivation
|
||||
|
|
@ -39,6 +38,7 @@ import kotlinx.coroutines.flow.Flow
|
|||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import java.util.EnumSet
|
||||
import com.tangem.blockchain.common.WalletManagerFactory as BlockchainWalletManagerFactory
|
||||
|
||||
@Suppress("LargeClass", "TooManyFunctions")
|
||||
// FIXME: Move to its own module and make internal
|
||||
|
|
@ -46,7 +46,7 @@ import java.util.EnumSet
|
|||
class DefaultWalletManagersFacade(
|
||||
private val walletManagersStore: WalletManagersStore,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
configManager: ConfigManager,
|
||||
blockchainWalletManagerFactory: BlockchainWalletManagerFactory,
|
||||
mnemonic: Mnemonic,
|
||||
assetReader: AssetReader,
|
||||
moshi: Moshi,
|
||||
|
|
@ -54,7 +54,7 @@ class DefaultWalletManagersFacade(
|
|||
|
||||
private val demoConfig by lazy { DemoConfig() }
|
||||
private val resultFactory by lazy { UpdateWalletManagerResultFactory() }
|
||||
private val walletManagerFactory by lazy { WalletManagerFactory(configManager) }
|
||||
private val walletManagerFactory by lazy { WalletManagerFactory(blockchainWalletManagerFactory) }
|
||||
private val sdkTokenConverter by lazy { SdkTokenConverter() }
|
||||
private val txHistoryStateConverter by lazy { SdkTransactionHistoryStateConverter() }
|
||||
private val txHistoryItemConverter by lazy { SdkTransactionHistoryItemConverter(assetReader, moshi) }
|
||||
|
|
|
|||
|
|
@ -3,23 +3,18 @@ package com.tangem.domain.walletmanager.utils
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.DerivationParams
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
import com.tangem.domain.common.DerivationStyleProvider
|
||||
import com.tangem.domain.common.extensions.makeWalletManagerForApp
|
||||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import timber.log.Timber
|
||||
import com.tangem.blockchain.common.WalletManagerFactory as BlockchainWalletManagerFactory
|
||||
|
||||
internal class WalletManagerFactory(
|
||||
private val configManager: ConfigManager,
|
||||
private val sdkWalletManagerFactory: BlockchainWalletManagerFactory,
|
||||
) {
|
||||
|
||||
private val sdkWalletManagerFactory by lazy {
|
||||
WalletManagerFactory(configManager.config.blockchainSdkConfig)
|
||||
}
|
||||
|
||||
fun createWalletManager(
|
||||
scanResponse: ScanResponse,
|
||||
blockchain: Blockchain,
|
||||
|
|
|
|||
|
|
@ -15,12 +15,16 @@ internal class StateRouter(
|
|||
fragmentManager.get()?.popBackStack()
|
||||
}
|
||||
|
||||
fun onBackClick() {
|
||||
when (currentState.value) {
|
||||
SendUiStateType.Recipient -> popBackStack()
|
||||
SendUiStateType.Amount -> showRecipient()
|
||||
SendUiStateType.Fee -> showAmount()
|
||||
SendUiStateType.Send -> showFee()
|
||||
fun onBackClick(isSuccess: Boolean = false) {
|
||||
if (isSuccess) {
|
||||
popBackStack()
|
||||
} else {
|
||||
when (currentState.value) {
|
||||
SendUiStateType.Recipient -> popBackStack()
|
||||
SendUiStateType.Amount -> showRecipient()
|
||||
SendUiStateType.Fee -> showAmount()
|
||||
SendUiStateType.Send -> showFee()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +58,7 @@ internal class StateRouter(
|
|||
currentState.update { SendUiStateType.Fee }
|
||||
}
|
||||
|
||||
private fun showSend() {
|
||||
fun showSend() {
|
||||
currentState.update { SendUiStateType.Send }
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ internal class FeeNotificationFactory(
|
|||
val customAmount = customFee.firstOrNull() ?: return
|
||||
val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals)
|
||||
if (selectedFee == FeeType.CUSTOM && minimumValue > customValue) {
|
||||
add(SendFeeNotification.Informational.TooLow)
|
||||
add(SendFeeNotification.Warning.TooLow)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,6 @@ import com.tangem.features.send.impl.R
|
|||
|
||||
sealed class SendFeeNotification(val config: NotificationConfig) {
|
||||
|
||||
sealed class Informational(
|
||||
val title: TextReference,
|
||||
val subtitle: TextReference,
|
||||
) : SendFeeNotification(
|
||||
config = NotificationConfig(
|
||||
title = title,
|
||||
subtitle = subtitle,
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
),
|
||||
) {
|
||||
object TooLow : Informational(
|
||||
title = resourceReference(id = R.string.send_notification_transaction_delay_title),
|
||||
subtitle = resourceReference(id = R.string.send_notification_transaction_delay_text),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Warning(
|
||||
val title: TextReference,
|
||||
val subtitle: TextReference,
|
||||
|
|
@ -36,6 +20,11 @@ sealed class SendFeeNotification(val config: NotificationConfig) {
|
|||
buttonsState = buttonsState,
|
||||
),
|
||||
) {
|
||||
object TooLow : Warning(
|
||||
title = resourceReference(id = R.string.send_notification_transaction_delay_title),
|
||||
subtitle = resourceReference(id = R.string.send_notification_transaction_delay_text),
|
||||
)
|
||||
|
||||
data class TooHigh(
|
||||
val value: String,
|
||||
) : Warning(
|
||||
|
|
|
|||
|
|
@ -15,14 +15,15 @@ import com.tangem.core.ui.components.notifications.Notification
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.send.impl.presentation.state.SendStates
|
||||
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
|
||||
import com.tangem.features.send.impl.presentation.state.fee.FeeType
|
||||
import com.tangem.features.send.impl.presentation.state.fee.SendFeeNotification
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
private const val FEE_SELECTOR_KEY = "FEE_SELECTOR_KEY"
|
||||
private const val FEE_CUSTOM_KEY = "FEE_CUSTOM_KEY"
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
internal fun SendSpeedAndFeeContent(state: SendStates.FeeState?, clickIntents: SendClickIntents) {
|
||||
if (state == null) return
|
||||
|
|
@ -36,46 +37,92 @@ internal fun SendSpeedAndFeeContent(state: SendStates.FeeState?, clickIntents: S
|
|||
horizontal = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
) {
|
||||
item(
|
||||
key = FEE_SELECTOR_KEY,
|
||||
) {
|
||||
SendSpeedSelector(
|
||||
state = state,
|
||||
clickIntents = clickIntents,
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
)
|
||||
}
|
||||
feeSelector(state, clickIntents)
|
||||
topNotifications(notifications)
|
||||
customFee(feeSendState)
|
||||
notifications(notifications)
|
||||
subtractButton(
|
||||
receivedAmount = state.receivedAmount,
|
||||
isSubtract = state.isSubtract,
|
||||
isSubtractAvailable = state.isSubtractAvailable,
|
||||
clickIntents = clickIntents,
|
||||
)
|
||||
middleNotifications(notifications)
|
||||
subtractButton(state, clickIntents)
|
||||
bottomNotifications(notifications)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
internal fun LazyListScope.notifications(configs: ImmutableList<SendFeeNotification>, modifier: Modifier = Modifier) {
|
||||
private fun LazyListScope.feeSelector(state: SendStates.FeeState, clickIntents: SendClickIntents) {
|
||||
item(
|
||||
key = FEE_SELECTOR_KEY,
|
||||
) {
|
||||
SendSpeedSelector(
|
||||
state = state,
|
||||
clickIntents = clickIntents,
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.topNotifications(
|
||||
configs: ImmutableList<SendFeeNotification>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
notifications(
|
||||
configs = configs.filter {
|
||||
it is SendFeeNotification.Error.ExceedsBalance ||
|
||||
it is SendFeeNotification.Warning.NetworkFeeUnreachable
|
||||
}.toImmutableList(),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyListScope.middleNotifications(
|
||||
configs: ImmutableList<SendFeeNotification>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
notifications(
|
||||
configs = configs.filter {
|
||||
it is SendFeeNotification.Warning.TooLow ||
|
||||
it is SendFeeNotification.Warning.TooHigh
|
||||
}.toImmutableList(),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyListScope.bottomNotifications(
|
||||
configs: ImmutableList<SendFeeNotification>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
notifications(
|
||||
configs = configs.filterIsInstance<SendFeeNotification.Warning.NetworkCoverage>().toImmutableList(),
|
||||
isLast = true,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
private fun LazyListScope.notifications(
|
||||
configs: ImmutableList<SendFeeNotification>,
|
||||
modifier: Modifier = Modifier,
|
||||
isLast: Boolean = false,
|
||||
) {
|
||||
items(
|
||||
items = configs,
|
||||
key = { it::class.java },
|
||||
contentType = { it::class.java },
|
||||
itemContent = {
|
||||
val bottomPadding = if (isLast) TangemTheme.dimens.spacing12 else TangemTheme.dimens.spacing0
|
||||
Notification(
|
||||
config = it.config,
|
||||
modifier = modifier
|
||||
.padding(top = TangemTheme.dimens.spacing12)
|
||||
.padding(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
bottom = bottomPadding,
|
||||
)
|
||||
.animateItemPlacement(),
|
||||
containerColor = when (it) {
|
||||
is SendFeeNotification.Error.ExceedsBalance,
|
||||
is SendFeeNotification.Warning.NetworkFeeUnreachable,
|
||||
-> TangemTheme.colors.background.primary
|
||||
-> TangemTheme.colors.background.action
|
||||
else -> TangemTheme.colors.button.disabled
|
||||
},
|
||||
iconTint = when (it) {
|
||||
is SendFeeNotification.Informational -> TangemTheme.colors.icon.accent
|
||||
is SendFeeNotification.Error.ExceedsBalance -> {
|
||||
if (it.config.buttonsState == null) {
|
||||
TangemTheme.colors.icon.warning
|
||||
|
|
@ -116,20 +163,30 @@ internal fun LazyListScope.customFee(feeSendState: FeeSelectorState, modifier: M
|
|||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
internal fun LazyListScope.subtractButton(
|
||||
receivedAmount: String,
|
||||
isSubtract: Boolean,
|
||||
isSubtractAvailable: Boolean,
|
||||
state: SendStates.FeeState,
|
||||
clickIntents: SendClickIntents,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val receivedAmount = state.receivedAmount
|
||||
val isSubtract = state.isSubtract
|
||||
val isSubtractAvailable = state.isSubtractAvailable
|
||||
val feeSendState = state.feeSelectorState
|
||||
if (isSubtractAvailable) {
|
||||
item {
|
||||
val feeStateContent = feeSendState as? FeeSelectorState.Content
|
||||
val isCustomAvailable = feeStateContent?.customValues.isNullOrEmpty().not()
|
||||
val isCustomSelected = feeStateContent?.selectedFee == FeeType.CUSTOM
|
||||
val topPadding = if (isCustomSelected && isCustomAvailable) {
|
||||
TangemTheme.dimens.spacing12
|
||||
} else {
|
||||
TangemTheme.dimens.spacing20
|
||||
}
|
||||
SendSpeedSubtract(
|
||||
receivingAmount = receivedAmount,
|
||||
isSubtract = isSubtract,
|
||||
onSelectClick = clickIntents::onSubtractSelect,
|
||||
modifier = modifier
|
||||
.padding(vertical = TangemTheme.dimens.spacing12)
|
||||
.padding(top = topPadding)
|
||||
.animateItemPlacement(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import androidx.annotation.DrawableRes
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
|
|
@ -39,6 +42,7 @@ import com.tangem.features.send.impl.R
|
|||
import com.tangem.features.send.impl.presentation.state.SendStates
|
||||
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
|
||||
import com.tangem.features.send.impl.presentation.state.fee.FeeType
|
||||
import com.tangem.features.send.impl.presentation.state.fee.SendFeeNotification
|
||||
import com.tangem.features.send.impl.presentation.ui.common.FooterContainer
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -112,12 +116,17 @@ internal fun SendSpeedSelector(
|
|||
visible = fees.normal is Fee.Ethereum,
|
||||
label = "Custom fee appearance animation",
|
||||
) {
|
||||
val showWarning = state.notifications.any {
|
||||
it is SendFeeNotification.Warning.TooHigh ||
|
||||
it is SendFeeNotification.Warning.TooLow
|
||||
}
|
||||
SendSpeedSelectorItem(
|
||||
titleRes = R.string.common_fee_selector_option_custom,
|
||||
iconRes = R.drawable.ic_edit_24,
|
||||
isSelected = isSelected == FeeType.CUSTOM,
|
||||
onSelect = { clickIntents.onFeeSelectorClick(FeeType.CUSTOM) },
|
||||
showDivider = fees.normal !is Fee.Ethereum,
|
||||
showWarning = showWarning,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -224,6 +233,7 @@ private fun SendSpeedSelectorItem(
|
|||
symbolLength: Int? = null,
|
||||
isSelected: Boolean = false,
|
||||
showDivider: Boolean = true,
|
||||
showWarning: Boolean = false,
|
||||
) {
|
||||
val iconTint by animateColorAsState(
|
||||
targetValue = if (isSelected) {
|
||||
|
|
@ -259,7 +269,10 @@ private fun SendSpeedSelectorItem(
|
|||
symbolLength = symbolLength,
|
||||
textStyle = textStyle,
|
||||
)
|
||||
} else {
|
||||
SpacerWMax()
|
||||
}
|
||||
WarningIcon(showWarning = showWarning)
|
||||
}
|
||||
if (showDivider) {
|
||||
Box(
|
||||
|
|
@ -340,6 +353,26 @@ private fun RowScope.SelectorValueContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WarningIcon(showWarning: Boolean = false) {
|
||||
AnimatedVisibility(
|
||||
visible = showWarning,
|
||||
label = "Custom fee warning indicator",
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_alert_triangle_20),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
vertical = TangemTheme.dimens.spacing12,
|
||||
horizontal = TangemTheme.dimens.spacing14,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//region preview
|
||||
@Preview
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -67,16 +67,16 @@ internal fun SendContent(uiState: SendUiState) {
|
|||
walletBalance = amountState.walletBalance.resolveReference(),
|
||||
)
|
||||
}
|
||||
AmountBlock(
|
||||
amountState = amountState,
|
||||
isSuccess = isSuccess,
|
||||
onClick = uiState.clickIntents::showAmount,
|
||||
)
|
||||
RecipientBlock(
|
||||
recipientState = recipientState,
|
||||
isSuccess = isSuccess,
|
||||
onClick = uiState.clickIntents::showRecipient,
|
||||
)
|
||||
AmountBlock(
|
||||
amountState = amountState,
|
||||
isSuccess = isSuccess,
|
||||
onClick = uiState.clickIntents::showAmount,
|
||||
)
|
||||
FeeBlock(
|
||||
feeState = feeState,
|
||||
isSuccess = isSuccess,
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ internal class SendViewModel @Inject constructor(
|
|||
|
||||
// region screen state navigation
|
||||
override fun popBackStack() = stateRouter.popBackStack()
|
||||
override fun onBackClick() = stateRouter.onBackClick()
|
||||
override fun onBackClick() = stateRouter.onBackClick(uiState.sendState.isSuccess)
|
||||
override fun onNextClick() = stateRouter.onNextClick()
|
||||
override fun onPrevClick() = stateRouter.onPrevClick()
|
||||
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ spr-client = "3.6.2"
|
|||
# endregion Other libraries
|
||||
|
||||
# region Tangem
|
||||
tangemBlockchainSdk = "release-app_5.6-472"
|
||||
tangemBlockchainSdk = "develop-475"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "release-app_5.6-325"
|
||||
tangemCardSdk = "develop-324"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||
# endregion Tangem
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue