Updated on 2026-08-14
This commit is contained in:
parent
7b5a62d593
commit
0dcf1ed23c
18 changed files with 256 additions and 74 deletions
|
|
@ -29,6 +29,7 @@ import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorRelo
|
|||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents.GasPriceInserter
|
||||
import com.tangem.features.send.v2.feeselector.model.transformers.*
|
||||
import com.tangem.utils.TangemLinks
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -36,7 +37,6 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -77,13 +77,7 @@ internal class FeeSelectorModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onReadMoreClicked() {
|
||||
val locale = if (Locale.getDefault().language == RU_LOCALE) RU_LOCALE else EN_LOCALE
|
||||
val url = buildString {
|
||||
append(FEE_READ_MORE_URL_FIRST_PART)
|
||||
append(locale)
|
||||
append(FEE_READ_MORE_URL_SECOND_PART)
|
||||
}
|
||||
urlOpener.openUrl(url)
|
||||
urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
|
||||
}
|
||||
|
||||
private fun initAppCurrency() {
|
||||
|
|
@ -245,11 +239,4 @@ internal class FeeSelectorModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val RU_LOCALE = "ru"
|
||||
const val EN_LOCALE = "en"
|
||||
const val FEE_READ_MORE_URL_FIRST_PART = "https://tangem.com/"
|
||||
const val FEE_READ_MORE_URL_SECOND_PART = "/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/"
|
||||
}
|
||||
}
|
||||
|
|
@ -22,13 +22,13 @@ import com.tangem.features.send.v2.subcomponents.fee.model.transformers.*
|
|||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
|
||||
import com.tangem.utils.TangemLinks
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -136,13 +136,7 @@ internal class SendFeeModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onReadMoreClick() {
|
||||
val locale = if (Locale.getDefault().language == RU_LOCALE) RU_LOCALE else EN_LOCALE
|
||||
val url = buildString {
|
||||
append(FEE_READ_MORE_URL_FIRST_PART)
|
||||
append(locale)
|
||||
append(FEE_READ_MORE_URL_SECOND_PART)
|
||||
}
|
||||
urlOpener.openUrl(url)
|
||||
urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
|
||||
}
|
||||
|
||||
override fun onNextClick() {
|
||||
|
|
@ -297,11 +291,4 @@ internal class SendFeeModel @Inject constructor(
|
|||
)
|
||||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val RU_LOCALE = "ru"
|
||||
const val EN_LOCALE = "en"
|
||||
const val FEE_READ_MORE_URL_FIRST_PART = "https://tangem.com/"
|
||||
const val FEE_READ_MORE_URL_SECOND_PART = "/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/"
|
||||
}
|
||||
}
|
||||
|
|
@ -141,8 +141,7 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
|
||||
data object YeildSupplyApprove : Warning(
|
||||
title = resourceReference(R.string.yield_module_main_view_approve_notification_title),
|
||||
// todo yield supply lokalise
|
||||
subtitle = resourceReference(R.string.yield_module_main_view_approve_notification_title),
|
||||
subtitle = resourceReference(R.string.yield_module_main_view_approve_notification_description),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ dependencies {
|
|||
implementation(projects.domain.transaction.models)
|
||||
implementation(projects.domain.transaction)
|
||||
implementation(projects.domain.yieldSupply)
|
||||
implementation(projects.domain.feedback.models)
|
||||
implementation(projects.domain.feedback)
|
||||
implementation(projects.domain.balanceHiding.models)
|
||||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.libs.crypto)
|
||||
|
||||
/** Compose */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
package com.tangem.features.yield.supply.impl.common
|
||||
|
||||
import com.tangem.common.ui.alerts.TransactionErrorAlertConverter
|
||||
import com.tangem.common.ui.alerts.models.AlertDemoModeUM
|
||||
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.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.transaction.error.SendTransactionError
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
class YieldSupplyAlertFactory @Inject constructor(
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase,
|
||||
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
) {
|
||||
|
||||
fun getGenericErrorState(onFailedTxEmailClick: () -> Unit, popBack: () -> Unit = {}) {
|
||||
uiMessageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(id = R.string.send_alert_transaction_failed_title),
|
||||
message = resourceReference(id = R.string.common_unknown_error),
|
||||
onDismissRequest = popBack,
|
||||
firstAction = EventMessageAction(
|
||||
title = resourceReference(R.string.common_support),
|
||||
onClick = onFailedTxEmailClick,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getSendTransactionErrorState(
|
||||
error: SendTransactionError?,
|
||||
popBack: () -> Unit,
|
||||
onFailedTxEmailClick: (String) -> Unit,
|
||||
) {
|
||||
val transactionErrorAlertConverter = TransactionErrorAlertConverter(
|
||||
popBackStack = popBack,
|
||||
onFailedTxEmailClick = onFailedTxEmailClick,
|
||||
)
|
||||
|
||||
val errorAlert = error?.let { transactionErrorAlertConverter.convert(error) } ?: return
|
||||
val onConfirmClick = errorAlert.onConfirmClick ?: return
|
||||
|
||||
uiMessageSender.send(
|
||||
DialogMessage.Companion(
|
||||
title = errorAlert.title,
|
||||
message = errorAlert.message,
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = errorAlert.confirmButtonText,
|
||||
onClick = onConfirmClick,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = if (errorAlert !is AlertDemoModeUM) {
|
||||
{ cancelAction() }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun onFailedTxEmailClick(userWallet: UserWallet, cryptoCurrency: CryptoCurrency?, errorMessage: String?) {
|
||||
saveBlockchainErrorUseCase(
|
||||
error = BlockchainErrorInfo(
|
||||
errorMessage = errorMessage.orEmpty(),
|
||||
blockchainId = cryptoCurrency?.network?.rawId.orEmpty(),
|
||||
derivationPath = cryptoCurrency?.network?.derivationPath?.value.orEmpty(),
|
||||
tokenSymbol = cryptoCurrency?.symbol.orEmpty(),
|
||||
destinationAddress = "",
|
||||
amount = "",
|
||||
fee = "",
|
||||
),
|
||||
)
|
||||
|
||||
val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return
|
||||
|
||||
sendFeedbackEmailUseCase(
|
||||
type = FeedbackEmailType.TransactionSendingProblem(metaInfo),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -38,8 +38,9 @@ internal class DefaultYieldSupplyComponent @AssistedInject constructor(
|
|||
override fun Content(modifier: Modifier) {
|
||||
val yieldSupplyUM by model.uiState.collectAsStateWithLifecycle()
|
||||
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
||||
val isBalanceHidden by model.isBalanceHiddenFlow.collectAsStateWithLifecycle()
|
||||
|
||||
YieldSupplyBlockContent(yieldSupplyUM = yieldSupplyUM, modifier = modifier)
|
||||
YieldSupplyBlockContent(yieldSupplyUM = yieldSupplyUM, isBalanceHidden = isBalanceHidden, modifier = modifier)
|
||||
|
||||
bottomSheet.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
|
@ -50,6 +51,7 @@ internal class DefaultYieldSupplyComponent @AssistedInject constructor(
|
|||
params = YieldSupplyActiveEntryComponent.Params(
|
||||
userWallet = model.userWallet,
|
||||
cryptoCurrencyStatusFlow = model.cryptoCurrencyStatusFlow,
|
||||
isBalanceHiddenFlow = model.isBalanceHiddenFlow,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.TxInfo
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -39,6 +40,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
@DelayedWork private val coroutineScope: CoroutineScope,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
) : Model(), YieldSupplyClickIntents {
|
||||
|
||||
private val params = paramsContainer.require<YieldSupplyComponent.Params>()
|
||||
|
|
@ -59,8 +61,12 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
val isBalanceHiddenFlow: StateFlow<Boolean>
|
||||
field = MutableStateFlow(false)
|
||||
|
||||
init {
|
||||
subscribeOnCurrencyStatusUpdates()
|
||||
subscribeOnBalanceHidden()
|
||||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
|
|
@ -80,7 +86,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
onDataLoaded(cryptoCurrencyStatus)
|
||||
},
|
||||
ifLeft = {
|
||||
// todo error
|
||||
Timber.w(it.toString())
|
||||
},
|
||||
)
|
||||
}.launchIn(modelScope)
|
||||
|
|
@ -106,6 +112,17 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
bottomSheetNavigation.activate(Unit)
|
||||
}
|
||||
|
||||
private fun subscribeOnBalanceHidden() {
|
||||
getBalanceHidingSettingsUseCase()
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
isBalanceHiddenFlow.value = it.isBalanceHidden
|
||||
}
|
||||
.flowOn(dispatchers.default)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun onDataLoaded(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus
|
||||
val hasActiveTransaction = cryptoCurrencyStatus.value.hasCurrentNetworkTransactions
|
||||
|
|
|
|||
|
|
@ -33,7 +33,11 @@ import com.tangem.features.yield.supply.impl.main.entity.YieldSupplyUM
|
|||
import com.tangem.utils.StringsSigns
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyBlockContent(yieldSupplyUM: YieldSupplyUM, modifier: Modifier = Modifier) {
|
||||
internal fun YieldSupplyBlockContent(
|
||||
yieldSupplyUM: YieldSupplyUM,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = yieldSupplyUM,
|
||||
modifier = modifier,
|
||||
|
|
@ -41,7 +45,7 @@ internal fun YieldSupplyBlockContent(yieldSupplyUM: YieldSupplyUM, modifier: Mod
|
|||
when (supplyUM) {
|
||||
is YieldSupplyUM.Initial -> SupplyInitial(supplyUM)
|
||||
YieldSupplyUM.Loading -> SupplyLoading()
|
||||
is YieldSupplyUM.Content -> SupplyContent(supplyUM)
|
||||
is YieldSupplyUM.Content -> SupplyContent(supplyUM, isBalanceHidden)
|
||||
YieldSupplyUM.Processing.Enter -> SupplyProcessing(
|
||||
resourceReference(R.string.yield_module_token_details_earn_notification_processing),
|
||||
)
|
||||
|
|
@ -100,7 +104,7 @@ private fun SupplyInitial(supplyUM: YieldSupplyUM.Initial) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun SupplyContent(supplyUM: YieldSupplyUM.Content) {
|
||||
private fun SupplyContent(supplyUM: YieldSupplyUM.Content, isBalanceHidden: Boolean) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
|
|
@ -124,7 +128,7 @@ private fun SupplyContent(supplyUM: YieldSupplyUM.Content) {
|
|||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
text = supplyUM.rewardsBalance.resolveReference(),
|
||||
text = supplyUM.rewardsBalance.orMaskWithStars(isBalanceHidden).resolveReference(),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
|
|
@ -224,7 +228,7 @@ private fun SupplyLoading() {
|
|||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun YieldSupplyBlockContent_Preview(@PreviewParameter(PreviewProvider::class) params: YieldSupplyUM) {
|
||||
TangemThemePreview {
|
||||
YieldSupplyBlockContent(params)
|
||||
YieldSupplyBlockContent(params, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ internal class YieldSupplyActiveComponent(
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
val isBalanceHidden by params.isBalanceHiddenFlow.collectAsStateWithLifecycle()
|
||||
|
||||
YieldSupplyActiveContent(state = state, modifier = Modifier)
|
||||
YieldSupplyActiveContent(state = state, isBalanceHidden = isBalanceHidden, modifier = Modifier)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -53,6 +54,7 @@ internal class YieldSupplyActiveComponent(
|
|||
data class Params(
|
||||
val userWallet: UserWallet,
|
||||
val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
|
||||
val isBalanceHiddenFlow: StateFlow<Boolean>,
|
||||
val callback: ModelCallback,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ internal class YieldSupplyActiveEntryComponent(
|
|||
params = YieldSupplyActiveComponent.Params(
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrencyStatusFlow = params.cryptoCurrencyStatusFlow,
|
||||
isBalanceHiddenFlow = params.isBalanceHiddenFlow,
|
||||
callback = model,
|
||||
),
|
||||
)
|
||||
|
|
@ -107,6 +108,7 @@ internal class YieldSupplyActiveEntryComponent(
|
|||
data class Params(
|
||||
val userWallet: UserWallet,
|
||||
val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>,
|
||||
val isBalanceHiddenFlow: StateFlow<Boolean>,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -32,7 +32,11 @@ import com.tangem.features.yield.supply.impl.R
|
|||
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyActiveContent(state: YieldSupplyActiveContentUM, modifier: Modifier = Modifier) {
|
||||
internal fun YieldSupplyActiveContent(
|
||||
state: YieldSupplyActiveContentUM,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(14.dp),
|
||||
modifier = modifier.padding(
|
||||
|
|
@ -54,12 +58,12 @@ internal fun YieldSupplyActiveContent(state: YieldSupplyActiveContentUM, modifie
|
|||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
ResizableText(
|
||||
text = state.totalEarnings.resolveReference(),
|
||||
text = state.totalEarnings.orMaskWithStars(isBalanceHidden).resolveReference(),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
YieldSupplyActiveMyFunds(state = state)
|
||||
YieldSupplyActiveMyFunds(state = state, isBalanceHidden = isBalanceHidden)
|
||||
|
||||
AnimatedVisibility(state.notificationUM != null) {
|
||||
val wrappedNotification = remember(this) { requireNotNull(state.notificationUM) }
|
||||
|
|
@ -73,7 +77,7 @@ internal fun YieldSupplyActiveContent(state: YieldSupplyActiveContentUM, modifie
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM) {
|
||||
private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM, isBalanceHidden: Boolean) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
|
|
@ -112,6 +116,7 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM) {
|
|||
InfoRow(
|
||||
title = resourceReference(R.string.yield_module_earn_sheet_transfers_title),
|
||||
info = resourceReference(R.string.yield_module_transfer_mode_automatic),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
HorizontalDivider(
|
||||
thickness = 0.5.dp,
|
||||
|
|
@ -120,6 +125,7 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM) {
|
|||
InfoRow(
|
||||
title = resourceReference(R.string.yield_module_earn_sheet_available_title),
|
||||
info = state.availableBalance,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +156,7 @@ private fun DescriptionText(state: YieldSupplyActiveContentUM) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoRow(title: TextReference, info: TextReference?) {
|
||||
private fun InfoRow(title: TextReference, isBalanceHidden: Boolean, info: TextReference?) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 12.dp),
|
||||
|
|
@ -165,7 +171,7 @@ private fun InfoRow(title: TextReference, info: TextReference?) {
|
|||
AnimatedContent(info) { currentInfo ->
|
||||
if (currentInfo != null) {
|
||||
Text(
|
||||
text = currentInfo.resolveReference(),
|
||||
text = currentInfo.orMaskWithStars(isBalanceHidden).resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -187,7 +193,7 @@ private fun YieldSupplyActiveBottomSheet_Preview(
|
|||
@PreviewParameter(YieldSupplyActiveBottomSheetPreviewProvider::class) params: YieldSupplyActiveContentUM,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
YieldSupplyActiveContent(params)
|
||||
YieldSupplyActiveContent(params, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
|
|
@ -89,7 +90,7 @@ internal class YieldSupplyApproveComponent(
|
|||
PrimaryButtonIconEnd(
|
||||
text = stringResourceSafe(R.string.common_confirm),
|
||||
onClick = model::onClick,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
iconResId = walletInterationIcon(params.userWallet),
|
||||
enabled = state.isPrimaryButtonEnabled,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
|||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetContractAddressUseCase
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.transformer.YieldSupplyTransactionInProgressTransformer
|
||||
|
|
@ -29,6 +30,7 @@ import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSu
|
|||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsUpdateTrigger
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
|
||||
import com.tangem.utils.StringsSigns.DOT
|
||||
import com.tangem.utils.TangemLinks
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -50,6 +52,7 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val yieldSupplyGetContractAddressUseCase: YieldSupplyGetContractAddressUseCase,
|
||||
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyApproveComponent.Params = paramsContainer.require()
|
||||
|
|
@ -98,7 +101,7 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onReadMoreClick() {
|
||||
urlOpener.openUrl(READ_MORE_URL)
|
||||
urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
|
||||
}
|
||||
|
||||
override fun onFeeReload() {
|
||||
|
|
@ -117,9 +120,22 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
userWallet = userWallet,
|
||||
network = cryptoCurrency.network,
|
||||
).fold(
|
||||
ifLeft = {
|
||||
Timber.e(it.toString())
|
||||
ifLeft = { error ->
|
||||
Timber.e(error.toString())
|
||||
uiState.update(YieldSupplyTransactionReadyTransformer)
|
||||
yieldSupplyAlertFactory.getSendTransactionErrorState(
|
||||
error = error,
|
||||
popBack = params.callback::onBackClick,
|
||||
onFailedTxEmailClick = { errorMessage ->
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyAlertFactory.onFailedTxEmailClick(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
errorMessage = errorMessage,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
ifRight = {
|
||||
params.callback.onTransactionSent()
|
||||
|
|
@ -223,8 +239,4 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
}
|
||||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val READ_MORE_URL = "https://tangem.com" // todo yield supply replace with real link
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
|
|
@ -105,11 +106,17 @@ internal class YieldSupplyStartEarningComponent(
|
|||
override fun Footer() {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
val icon = if (state.isPrimaryButtonEnabled) {
|
||||
walletInterationIcon(model.userWallet)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
text = stringResourceSafe(R.string.yield_module_start_earning),
|
||||
onClick = model::onClick,
|
||||
enabled = state.isPrimaryButtonEnabled,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
iconResId = icon,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
|||
import com.tangem.domain.yield.supply.usecase.YieldSupplyEstimateEnterFeeUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyStartEarningUseCase
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.transformer.YieldSupplyTransactionInProgressTransformer
|
||||
|
|
@ -53,12 +54,13 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val yieldSupplyNotificationsUpdateTrigger: YieldSupplyNotificationsUpdateTrigger,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStartEarningComponent.Params = paramsContainer.require()
|
||||
|
||||
private val cryptoCurrency = params.cryptoCurrency
|
||||
private var userWallet: UserWallet by Delegates.notNull()
|
||||
var userWallet: UserWallet by Delegates.notNull()
|
||||
|
||||
val cryptoCurrencyStatusFlow: StateFlow<CryptoCurrencyStatus>
|
||||
field = MutableStateFlow(
|
||||
|
|
@ -171,6 +173,19 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
ifLeft = { error ->
|
||||
Timber.e(error.toString())
|
||||
uiState.update(YieldSupplyTransactionReadyTransformer)
|
||||
yieldSupplyAlertFactory.getSendTransactionErrorState(
|
||||
error = error,
|
||||
popBack = params.callback::onBackClick,
|
||||
onFailedTxEmailClick = { errorMessage ->
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyAlertFactory.onFailedTxEmailClick(
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
errorMessage = errorMessage,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
ifRight = {
|
||||
fetchCurrencyStatusUseCase(userWalletId = userWallet.walletId, cryptoCurrency.id)
|
||||
|
|
@ -191,8 +206,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
},
|
||||
ifLeft = {
|
||||
Timber.w(it.toString())
|
||||
// showAlertError() todo yield supply error alert
|
||||
return@launch
|
||||
showAlertError()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -230,13 +244,8 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifLeft = {
|
||||
// todo yield supply error
|
||||
// sendConfirmAlertFactory.getGenericErrorState(
|
||||
// onFailedTxEmailClick = {
|
||||
// onFailedTxEmailClick(it.toString())
|
||||
// },
|
||||
// popBack = router::pop,
|
||||
// )
|
||||
Timber.w(it.toString())
|
||||
showAlertError()
|
||||
},
|
||||
)
|
||||
}.launchIn(modelScope)
|
||||
|
|
@ -251,6 +260,21 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun showAlertError() {
|
||||
yieldSupplyAlertFactory.getGenericErrorState(
|
||||
onFailedTxEmailClick = {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyAlertFactory.onFailedTxEmailClick(
|
||||
userWallet,
|
||||
cryptoCurrency,
|
||||
null,
|
||||
)
|
||||
}
|
||||
},
|
||||
popBack = params.callback::onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val MAX_NETWORK_FEE: BigDecimal = BigDecimal.TEN // TODO replace with value from api
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
|
|
@ -89,7 +90,7 @@ internal class YieldSupplyStopEarningComponent(
|
|||
PrimaryButtonIconEnd(
|
||||
text = stringResourceSafe(R.string.common_confirm),
|
||||
onClick = model::onClick,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
iconResId = walletInterationIcon(params.userWallet),
|
||||
enabled = state.isPrimaryButtonEnabled,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
|||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyStopEarningUseCase
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.transformer.YieldSupplyTransactionInProgressTransformer
|
||||
|
|
@ -26,6 +27,7 @@ import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSu
|
|||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.model.transformer.YieldSupplyStopEarningFeeContentTransformer
|
||||
import com.tangem.utils.TangemLinks
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import com.tangem.utils.transformer.update
|
||||
|
|
@ -46,6 +48,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
private val yieldSupplyStopEarningUseCase: YieldSupplyStopEarningUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val yieldSupplyNotificationsUpdateTrigger: YieldSupplyNotificationsUpdateTrigger,
|
||||
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStopEarningComponent.Params = paramsContainer.require()
|
||||
|
|
@ -100,7 +103,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onReadMoreClick() {
|
||||
urlOpener.openUrl(READ_MORE_URL)
|
||||
urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
|
||||
}
|
||||
|
||||
fun onClick() {
|
||||
|
|
@ -113,9 +116,22 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
userWallet = userWallet,
|
||||
network = cryptoCurrency.network,
|
||||
).fold(
|
||||
ifLeft = {
|
||||
Timber.e(it.toString())
|
||||
ifLeft = { error ->
|
||||
Timber.e(error.toString())
|
||||
uiState.update(YieldSupplyTransactionReadyTransformer)
|
||||
yieldSupplyAlertFactory.getSendTransactionErrorState(
|
||||
error = error,
|
||||
popBack = params.callback::onBackClick,
|
||||
onFailedTxEmailClick = { errorMessage ->
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyAlertFactory.onFailedTxEmailClick(
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
errorMessage = error.toString(),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
ifRight = {
|
||||
params.callback.onTransactionSent()
|
||||
|
|
@ -197,8 +213,4 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
}
|
||||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val READ_MORE_URL = "https://tangem.com" // todo yield supply replace with real link
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue