Updated on 2026-08-14
This commit is contained in:
parent
b004f8df6b
commit
1964b3cfad
22 changed files with 204 additions and 173 deletions
|
|
@ -16,14 +16,6 @@ object TangemBlogUrlBuilder {
|
||||||
|
|
||||||
val path: String
|
val path: String
|
||||||
|
|
||||||
data object SeedNotify : Post {
|
|
||||||
override val path: String = "seed-notify"
|
|
||||||
}
|
|
||||||
|
|
||||||
data object SeedNotifySecond : Post {
|
|
||||||
override val path: String = "tangem-resolves-log-issue"
|
|
||||||
}
|
|
||||||
|
|
||||||
data object SeedPhraseRiskySolution : Post {
|
data object SeedPhraseRiskySolution : Post {
|
||||||
override val path: String = "seed-phrase-faq"
|
override val path: String = "seed-phrase-faq"
|
||||||
}
|
}
|
||||||
|
|
@ -39,5 +31,21 @@ object TangemBlogUrlBuilder {
|
||||||
data object HowToScan : Post {
|
data object HowToScan : Post {
|
||||||
override val path: String = "scan-tangem-card"
|
override val path: String = "scan-tangem-card"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data object HowToStake : Post {
|
||||||
|
override val path: String = "how-to-stake-cryptocurrency"
|
||||||
|
}
|
||||||
|
|
||||||
|
data object GiveRevokePermission : Post {
|
||||||
|
override val path: String = "give-revoke-permission"
|
||||||
|
}
|
||||||
|
|
||||||
|
data object HowYieldModeWorks : Post {
|
||||||
|
override val path: String = "yield-mode"
|
||||||
|
}
|
||||||
|
|
||||||
|
data object AboutCrossChainBridges : Post {
|
||||||
|
override val path: String = "an-overview-of-cross-chain-bridges"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ object SupportedLanguages {
|
||||||
const val CHINESE = "zh"
|
const val CHINESE = "zh"
|
||||||
const val SPANISH = "es"
|
const val SPANISH = "es"
|
||||||
|
|
||||||
val supportedLangugeCodes = listOf(
|
val supportedLanguageCodes = listOf(
|
||||||
ENGLISH,
|
ENGLISH,
|
||||||
RUSSIAN,
|
RUSSIAN,
|
||||||
GERMAN,
|
GERMAN,
|
||||||
|
|
@ -25,10 +25,17 @@ object SupportedLanguages {
|
||||||
SPANISH,
|
SPANISH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ISO 639-1 code of the device's current language when it belongs to
|
||||||
|
* [supportedLanguageCodes], otherwise falls back to [ENGLISH].
|
||||||
|
*
|
||||||
|
* Intended for callers that need a plain two-letter language code (e.g. URL path segments
|
||||||
|
* like `tangem.com/{en|ru}/...`).
|
||||||
|
*/
|
||||||
fun getCurrentSupportedLanguageCode(): String {
|
fun getCurrentSupportedLanguageCode(): String {
|
||||||
val locale = Locale.getDefault()
|
val locale = Locale.getDefault()
|
||||||
|
|
||||||
return if (supportedLangugeCodes.contains(locale.language)) {
|
return if (supportedLanguageCodes.contains(locale.language)) {
|
||||||
locale.language
|
locale.language
|
||||||
} else {
|
} else {
|
||||||
ENGLISH
|
ENGLISH
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package com.tangem.utils
|
|
||||||
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
@Deprecated("Use TangemBlogUrlBuilder from common module")
|
|
||||||
object TangemBlogUrlBuilder {
|
|
||||||
|
|
||||||
private const val RU_LOCALE = "ru"
|
|
||||||
private const val EN_LOCALE = "en"
|
|
||||||
|
|
||||||
private const val TANGEM_MAIN = "https://tangem.com/"
|
|
||||||
|
|
||||||
val FEE_BLOG_LINK: String
|
|
||||||
get(): String {
|
|
||||||
val locale = if (Locale.getDefault().language == RU_LOCALE) RU_LOCALE else EN_LOCALE
|
|
||||||
return buildString {
|
|
||||||
append(TANGEM_MAIN)
|
|
||||||
append(locale)
|
|
||||||
append("/blog/post/what-is-a-transaction-fee-and-why-do-we-need-it/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const val RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP = "https://tangem.com/en/blog/post/give-revoke-permission/"
|
|
||||||
|
|
||||||
const val YIELD_SUPPLY_HOW_IT_WORKS_URL = "https://tangem.com/en/blog/post/yield-mode"
|
|
||||||
const val YIELD_SUPPLY_TOS_URL = "https://aave.com/terms-of-service"
|
|
||||||
const val YIELD_SUPPLY_PRIVACY_URL = "https://aave.com/privacy-policy"
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.tangem.utils
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth
|
||||||
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class SupportedLanguagesTest {
|
||||||
|
|
||||||
|
private lateinit var originalLocale: Locale
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
originalLocale = Locale.getDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
fun tearDown() {
|
||||||
|
Locale.setDefault(originalLocale)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCurrentSupportedLanguageCode returns primary language when locale is supported`() {
|
||||||
|
// Arrange
|
||||||
|
Locale.setDefault(Locale("en", "US"))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(actual).isEqualTo("en")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCurrentSupportedLanguageCode drops region for supported language`() {
|
||||||
|
// Arrange
|
||||||
|
Locale.setDefault(Locale("zh", "CN"))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(actual).isEqualTo("zh")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCurrentSupportedLanguageCode returns ENGLISH when locale is not supported`() {
|
||||||
|
// Arrange — pt (Portuguese) is not in supportedLanguageCodes
|
||||||
|
Locale.setDefault(Locale("pt", "BR"))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(actual).isEqualTo(SupportedLanguages.ENGLISH)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCurrentSupportedLanguageCode returns ENGLISH for empty language`() {
|
||||||
|
// Arrange
|
||||||
|
Locale.setDefault(Locale("", ""))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(actual).isEqualTo(SupportedLanguages.ENGLISH)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getCurrentSupportedLanguageCode supports every code in supportedLanguageCodes`() {
|
||||||
|
SupportedLanguages.supportedLanguageCodes.forEach { code ->
|
||||||
|
// Arrange
|
||||||
|
Locale.setDefault(Locale(code))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val actual = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(actual).isEqualTo(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `supportedLanguageCodes contains the expected nine ISO 639-1 codes`() {
|
||||||
|
// Assert
|
||||||
|
Truth.assertThat(SupportedLanguages.supportedLanguageCodes)
|
||||||
|
.containsExactly("en", "ru", "de", "fr", "it", "ja", "uk", "zh", "es")
|
||||||
|
.inOrder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package com.tangem.data.common.locale
|
|
||||||
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
internal class DefaultLocaleProvider : LocaleProvider {
|
|
||||||
|
|
||||||
override fun getLocale(): Locale {
|
|
||||||
return Locale.getDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getWebUriLocaleLanguage(): String {
|
|
||||||
val language = getLocale().language
|
|
||||||
return if (LOCALE_LANG_RU.equals(language, true) || LOCALE_LANG_BY.equals(language, true)) {
|
|
||||||
LOCALE_LANG_RU
|
|
||||||
} else {
|
|
||||||
LOCALE_LANG_EN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val LOCALE_LANG_RU = "ru"
|
|
||||||
const val LOCALE_LANG_BY = "by"
|
|
||||||
const val LOCALE_LANG_EN = "en"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package com.tangem.data.common.locale
|
|
||||||
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
interface LocaleProvider {
|
|
||||||
|
|
||||||
fun getLocale(): Locale
|
|
||||||
|
|
||||||
fun getWebUriLocaleLanguage(): String
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.tangem.data.common.locale.di
|
|
||||||
|
|
||||||
import com.tangem.data.common.locale.DefaultLocaleProvider
|
|
||||||
import com.tangem.data.common.locale.LocaleProvider
|
|
||||||
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 LocaleProviderModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
fun provideCacheRegistry(): LocaleProvider {
|
|
||||||
return DefaultLocaleProvider()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.tangem.blockchain.common.TransactionData
|
||||||
import com.tangem.blockchain.common.TransactionSender.MultipleTransactionSendMode
|
import com.tangem.blockchain.common.TransactionSender.MultipleTransactionSendMode
|
||||||
import com.tangem.blockchain.common.transaction.Fee
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
|
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
|
||||||
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
|
|
@ -16,10 +17,7 @@ import com.tangem.core.analytics.models.Basic
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
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.navigation.url.UrlOpener
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.message.DialogMessage
|
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.transaction.error.GetFeeError
|
import com.tangem.domain.transaction.error.GetFeeError
|
||||||
|
|
@ -37,7 +35,6 @@ import com.tangem.features.approval.api.GiveApprovalComponent
|
||||||
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
|
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
|
||||||
import com.tangem.features.send.v2.api.entity.FeeItem
|
import com.tangem.features.send.v2.api.entity.FeeItem
|
||||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.logging.TangemLogger
|
import com.tangem.utils.logging.TangemLogger
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
@ -61,7 +58,6 @@ internal class GiveApprovalModel @Inject constructor(
|
||||||
private val getFeeForGaslessUseCase: GetFeeForGaslessUseCase,
|
private val getFeeForGaslessUseCase: GetFeeForGaslessUseCase,
|
||||||
private val getFeeForTokenUseCase: GetFeeForTokenUseCase,
|
private val getFeeForTokenUseCase: GetFeeForTokenUseCase,
|
||||||
private val createAndSendGaslessTransactionUseCase: CreateAndSendGaslessTransactionUseCase,
|
private val createAndSendGaslessTransactionUseCase: CreateAndSendGaslessTransactionUseCase,
|
||||||
private val uiMessageSender: UiMessageSender,
|
|
||||||
private val urlOpener: UrlOpener,
|
private val urlOpener: UrlOpener,
|
||||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||||
|
|
@ -119,16 +115,9 @@ internal class GiveApprovalModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onOpenLearnMoreAboutApproveClick() {
|
fun onOpenLearnMoreAboutApproveClick() {
|
||||||
urlOpener.openUrl(RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP)
|
modelScope.launch {
|
||||||
}
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.GiveRevokePermission))
|
||||||
|
}
|
||||||
fun showPermissionInfoDialog() {
|
|
||||||
uiMessageSender.send(
|
|
||||||
DialogMessage(
|
|
||||||
message = resourceReference(com.tangem.common.ui.R.string.give_permission_staking_footer),
|
|
||||||
title = resourceReference(com.tangem.common.ui.R.string.common_approve),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun loadFee(): Either<GetFeeError, TransactionFee> {
|
suspend fun loadFee(): Either<GetFeeError, TransactionFee> {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package com.tangem.features.details.model
|
package com.tangem.features.details.model
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.tangem.utils.logging.TangemLogger
|
|
||||||
import com.tangem.common.routing.AppRoute
|
import com.tangem.common.routing.AppRoute
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
|
@ -37,6 +35,7 @@ import com.tangem.features.details.utils.ItemsBuilder
|
||||||
import com.tangem.features.details.utils.SocialsBuilder
|
import com.tangem.features.details.utils.SocialsBuilder
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.info.AppInfoProvider
|
import com.tangem.utils.info.AppInfoProvider
|
||||||
|
import com.tangem.utils.logging.TangemLogger
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
|
@ -44,7 +43,6 @@ import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.util.Locale
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
|
|
@ -270,13 +268,4 @@ internal class DetailsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAppVersion(): String = "${appInfoProvider.appVersion} (${appInfoProvider.appVersionCode})"
|
private fun getAppVersion(): String = "${appInfoProvider.appVersion} (${appInfoProvider.appVersionCode})"
|
||||||
|
|
||||||
private companion object {
|
|
||||||
val SYSTEM_LANGUAGE = runCatching { Resources.getSystem().configuration.locales[0].language }.getOrElse { "" }
|
|
||||||
val APP_LANGUAGE = Locale.getDefault().language
|
|
||||||
val UTM_MARKS = "utm_source=tangem-app" +
|
|
||||||
"&utm_medium=app" +
|
|
||||||
"&utm_campaign=users-$SYSTEM_LANGUAGE" +
|
|
||||||
"&utm_content=devicelang-$APP_LANGUAGE"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import com.arkivanov.decompose.router.slot.dismiss
|
||||||
import com.tangem.blockchain.common.TransactionData
|
import com.tangem.blockchain.common.TransactionData
|
||||||
import com.tangem.blockchain.common.transaction.Fee
|
import com.tangem.blockchain.common.transaction.Fee
|
||||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.getValidatorsCount
|
import com.tangem.common.getValidatorsCount
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer.ReduceByData
|
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer.ReduceByData
|
||||||
|
|
@ -95,7 +96,6 @@ import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction
|
||||||
import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction
|
import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction
|
||||||
import com.tangem.lib.crypto.BlockchainUtils.isTon
|
import com.tangem.lib.crypto.BlockchainUtils.isTon
|
||||||
import com.tangem.utils.Provider
|
import com.tangem.utils.Provider
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
|
|
||||||
import com.tangem.utils.coroutines.*
|
import com.tangem.utils.coroutines.*
|
||||||
import com.tangem.utils.extensions.isSingleItem
|
import com.tangem.utils.extensions.isSingleItem
|
||||||
import com.tangem.utils.extensions.orZero
|
import com.tangem.utils.extensions.orZero
|
||||||
|
|
@ -603,7 +603,9 @@ internal class StakingModel @Inject constructor(
|
||||||
|
|
||||||
override fun onInitialInfoBannerClick() {
|
override fun onInitialInfoBannerClick() {
|
||||||
analyticsEventHandler.send(StakingAnalyticsEvent.WhatIsStaking())
|
analyticsEventHandler.send(StakingAnalyticsEvent.WhatIsStaking())
|
||||||
innerRouter.openUrl(WHAT_IS_STAKING_ARTICLE_URL)
|
modelScope.launch {
|
||||||
|
innerRouter.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.HowToStake))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onInfoClick(infoType: InfoType) {
|
override fun onInfoClick(infoType: InfoType) {
|
||||||
|
|
@ -1100,7 +1102,9 @@ internal class StakingModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenLearnMoreAboutApproveClick() {
|
override fun onOpenLearnMoreAboutApproveClick() {
|
||||||
urlOpener.openUrl(RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP)
|
modelScope.launch {
|
||||||
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.GiveRevokePermission))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivateTonAccountNotificationClick() {
|
override fun onActivateTonAccountNotificationClick() {
|
||||||
|
|
@ -1495,7 +1499,6 @@ internal class StakingModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val WHAT_IS_STAKING_ARTICLE_URL = "https://tangem.com/en/blog/post/how-to-stake-cryptocurrency/"
|
|
||||||
const val ALLOWANCE_UPDATE_DELAY = 10_000L
|
const val ALLOWANCE_UPDATE_DELAY = 10_000L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.features.staking.impl.presentation.model
|
package com.tangem.features.staking.impl.presentation.model
|
||||||
|
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.core.analytics.models.Basic
|
import com.tangem.core.analytics.models.Basic
|
||||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||||
import com.tangem.core.ui.message.DialogMessage
|
import com.tangem.core.ui.message.DialogMessage
|
||||||
|
|
@ -300,21 +301,24 @@ internal class StakingModelNavigationTest : StakingModelTestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `WHEN onInitialInfoBannerClick THEN analytics sent and url opened`() = runTest {
|
fun `WHEN onInitialInfoBannerClick THEN analytics sent and url opened`() = runTest {
|
||||||
|
val expectedUrl = "https://tangem.com/blog/post/how-to-stake-cryptocurrency/?utm_source=tangem-app"
|
||||||
|
mockkObject(TangemBlogUrlBuilder)
|
||||||
|
coEvery { TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.HowToStake) } returns expectedUrl
|
||||||
every { innerRouter.openUrl(any()) } just Runs
|
every { innerRouter.openUrl(any()) } just Runs
|
||||||
|
|
||||||
val model = createModel(testScope = this)
|
val model = createModel(testScope = this)
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
model.onInitialInfoBannerClick()
|
model.onInitialInfoBannerClick()
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
analyticsEventHandler.send(match { it is StakingAnalyticsEvent.WhatIsStaking })
|
analyticsEventHandler.send(match { it is StakingAnalyticsEvent.WhatIsStaking })
|
||||||
}
|
}
|
||||||
verify {
|
verify { innerRouter.openUrl(expectedUrl) }
|
||||||
innerRouter.openUrl("https://tangem.com/en/blog/post/how-to-stake-cryptocurrency/")
|
|
||||||
}
|
|
||||||
|
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
|
unmockkObject(TangemBlogUrlBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -478,15 +482,20 @@ internal class StakingModelNavigationTest : StakingModelTestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `WHEN onOpenLearnMoreAboutApproveClick THEN urlOpener opens approve url`() = runTest {
|
fun `WHEN onOpenLearnMoreAboutApproveClick THEN urlOpener opens approve url`() = runTest {
|
||||||
|
val expectedUrl = "https://tangem.com/blog/post/give-revoke-permission/?utm_source=tangem-app"
|
||||||
|
mockkObject(TangemBlogUrlBuilder)
|
||||||
|
coEvery { TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.GiveRevokePermission) } returns expectedUrl
|
||||||
every { urlOpener.openUrl(any()) } just Runs
|
every { urlOpener.openUrl(any()) } just Runs
|
||||||
|
|
||||||
val model = createModel(testScope = this)
|
val model = createModel(testScope = this)
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
model.onOpenLearnMoreAboutApproveClick()
|
model.onOpenLearnMoreAboutApproveClick()
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
verify { urlOpener.openUrl("https://tangem.com/en/blog/post/give-revoke-permission/") }
|
verify { urlOpener.openUrl(expectedUrl) }
|
||||||
|
|
||||||
|
unmockkObject(TangemBlogUrlBuilder)
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +96,7 @@ import com.tangem.feature.swap.utils.getContractAddress
|
||||||
import com.tangem.features.approval.api.GiveApprovalComponent
|
import com.tangem.features.approval.api.GiveApprovalComponent
|
||||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||||
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
|
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.features.swap.SwapComponent
|
import com.tangem.features.swap.SwapComponent
|
||||||
import com.tangem.utils.Provider
|
import com.tangem.utils.Provider
|
||||||
import com.tangem.utils.coroutines.*
|
import com.tangem.utils.coroutines.*
|
||||||
|
|
@ -1357,12 +1358,16 @@ internal class SwapModel @Inject constructor(
|
||||||
val selectedFee = (getSelectedFee() as? TxFee.Legacy)?.feeType ?: FeeType.NORMAL
|
val selectedFee = (getSelectedFee() as? TxFee.Legacy)?.feeType ?: FeeType.NORMAL
|
||||||
val txFeeState =
|
val txFeeState =
|
||||||
dataState.getCurrentLoadedSwapState()?.txFee as? TxFeeState.MultipleFeeState ?: return@UiActions
|
dataState.getCurrentLoadedSwapState()?.txFee as? TxFeeState.MultipleFeeState ?: return@UiActions
|
||||||
uiState = stateBuilder.showSelectFeeBottomSheet(
|
modelScope.launch {
|
||||||
uiState = uiState,
|
val readMoreUrl = TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.WhatIsTransactionFee)
|
||||||
selectedFee = selectedFee,
|
uiState = stateBuilder.showSelectFeeBottomSheet(
|
||||||
txFeeState = txFeeState,
|
uiState = uiState,
|
||||||
) {
|
selectedFee = selectedFee,
|
||||||
uiState = stateBuilder.dismissBottomSheet(uiState)
|
txFeeState = txFeeState,
|
||||||
|
readMoreUrl = readMoreUrl,
|
||||||
|
) {
|
||||||
|
uiState = stateBuilder.dismissBottomSheet(uiState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSelectFeeType = { txFee ->
|
onSelectFeeType = { txFee ->
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import com.tangem.utils.Provider
|
||||||
import com.tangem.utils.StringsSigns
|
import com.tangem.utils.StringsSigns
|
||||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||||
import com.tangem.utils.StringsSigns.TILDE_SIGN
|
import com.tangem.utils.StringsSigns.TILDE_SIGN
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder.FEE_BLOG_LINK
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
@ -984,6 +983,7 @@ internal class StateBuilder(
|
||||||
uiState: SwapStateHolder,
|
uiState: SwapStateHolder,
|
||||||
selectedFee: FeeType,
|
selectedFee: FeeType,
|
||||||
txFeeState: TxFeeState.MultipleFeeState,
|
txFeeState: TxFeeState.MultipleFeeState,
|
||||||
|
readMoreUrl: String,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
): SwapStateHolder {
|
): SwapStateHolder {
|
||||||
val config = ChooseFeeBottomSheetConfig(
|
val config = ChooseFeeBottomSheetConfig(
|
||||||
|
|
@ -995,7 +995,7 @@ internal class StateBuilder(
|
||||||
}
|
}
|
||||||
actions.onSelectFeeType.invoke(selectedItem)
|
actions.onSelectFeeType.invoke(selectedItem)
|
||||||
},
|
},
|
||||||
readMoreUrl = FEE_BLOG_LINK,
|
readMoreUrl = readMoreUrl,
|
||||||
feeItems = txFeeState.toFeeItemState(),
|
feeItems = txFeeState.toFeeItemState(),
|
||||||
readMore = resourceReference(R.string.common_read_more),
|
readMore = resourceReference(R.string.common_read_more),
|
||||||
onReadMoreClick = actions.onLinkClick,
|
onReadMoreClick = actions.onLinkClick,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
||||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||||
|
|
@ -114,6 +115,12 @@ internal class ExpressTransactionsModel @Inject constructor(
|
||||||
router.openUrl(url)
|
router.openUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onReadAboutCrossChainBridgesClick() {
|
||||||
|
modelScope.launch {
|
||||||
|
router.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.AboutCrossChainBridges))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onConfirmDisposeExpressStatus() {
|
override fun onConfirmDisposeExpressStatus() {
|
||||||
uiMessageSender.send(
|
uiMessageSender.send(
|
||||||
DialogMessage(
|
DialogMessage(
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ interface ExpressTransactionsClickIntents {
|
||||||
|
|
||||||
fun onOpenUrlClick(url: String)
|
fun onOpenUrlClick(url: String)
|
||||||
|
|
||||||
|
fun onReadAboutCrossChainBridgesClick()
|
||||||
|
|
||||||
fun onConfirmDisposeExpressStatus()
|
fun onConfirmDisposeExpressStatus()
|
||||||
|
|
||||||
fun onDisposeExpressStatus()
|
fun onDisposeExpressStatus()
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import com.tangem.domain.dynamicaddresses.DynamicAddressesDerivationChecker
|
||||||
import com.tangem.domain.dynamicaddresses.DynamicAddressesFeatureToggles
|
import com.tangem.domain.dynamicaddresses.DynamicAddressesFeatureToggles
|
||||||
import com.tangem.domain.dynamicaddresses.DynamicAddressesSupportedBlockchains
|
import com.tangem.domain.dynamicaddresses.DynamicAddressesSupportedBlockchains
|
||||||
import com.tangem.domain.dynamicaddresses.IsXpubSupportedUseCase
|
import com.tangem.domain.dynamicaddresses.IsXpubSupportedUseCase
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.routing.AppRoute
|
import com.tangem.common.routing.AppRoute
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.common.ui.bottomsheet.receive.AddressModel
|
import com.tangem.common.ui.bottomsheet.receive.AddressModel
|
||||||
|
|
@ -960,6 +961,12 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
router.openUrl(url)
|
router.openUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onReadAboutCrossChainBridgesClick() {
|
||||||
|
modelScope.launch {
|
||||||
|
router.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.AboutCrossChainBridges))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSwapPromoDismiss(promoId: PromoId) {
|
override fun onSwapPromoDismiss(promoId: PromoId) {
|
||||||
modelScope.launch(dispatchers.main) {
|
modelScope.launch(dispatchers.main) {
|
||||||
shouldShowPromoTokenUseCase.neverToShow(promoId)
|
shouldShowPromoTokenUseCase.neverToShow(promoId)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
import com.tangem.utils.logging.TangemLogger
|
import com.tangem.utils.logging.TangemLogger
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
// Fixme [REDACTED_JIRA]
|
// Fixme [REDACTED_JIRA]
|
||||||
@Suppress("LargeClass")
|
@Suppress("LargeClass")
|
||||||
|
|
@ -232,7 +231,7 @@ internal class TokenDetailsSwapTransactionsStateConverter(
|
||||||
} else {
|
} else {
|
||||||
ExchangeStatusNotification.TokenRefunded(
|
ExchangeStatusNotification.TokenRefunded(
|
||||||
cryptoCurrency = refundToken,
|
cryptoCurrency = refundToken,
|
||||||
onReadMoreClick = { clickIntents.onOpenUrlClick(url = getAboutCrossChainBridgesLink()) },
|
onReadMoreClick = clickIntents::onReadAboutCrossChainBridgesClick,
|
||||||
onGoToTokenClick = { clickIntents.onGoToRefundedTokenClick(refundToken) },
|
onGoToTokenClick = { clickIntents.onGoToRefundedTokenClick(refundToken) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -424,12 +423,4 @@ internal class TokenDetailsSwapTransactionsStateConverter(
|
||||||
isDone = isSendingDone,
|
isDone = isSendingDone,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAboutCrossChainBridgesLink(): String {
|
|
||||||
return if (Locale.getDefault().country == "RU") {
|
|
||||||
"https://tangem.com/ru/blog/post/an-overview-of-cross-chain-bridges/"
|
|
||||||
} else {
|
|
||||||
"https://tangem.com/en/blog/post/an-overview-of-cross-chain-bridges/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import com.domain.blockaid.models.transaction.SimulationResult
|
||||||
import com.domain.blockaid.models.transaction.ValidationResult
|
import com.domain.blockaid.models.transaction.ValidationResult
|
||||||
import com.tangem.blockchain.common.TransactionData
|
import com.tangem.blockchain.common.TransactionData
|
||||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
|
@ -59,7 +60,6 @@ import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransacti
|
||||||
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
||||||
import com.tangem.features.walletconnect.transaction.ui.blockaid.WcSendAndReceiveBlockAidUiConverter
|
import com.tangem.features.walletconnect.transaction.ui.blockaid.WcSendAndReceiveBlockAidUiConverter
|
||||||
import com.tangem.features.walletconnect.utils.WcNotificationsFactory
|
import com.tangem.features.walletconnect.utils.WcNotificationsFactory
|
||||||
import com.tangem.utils.SupportedLanguages
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -301,14 +301,10 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
stackNavigation.pop()
|
stackNavigation.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Use TangemBlockUrlBuilder instead")
|
|
||||||
private fun onApproveLearnMoreClick() {
|
private fun onApproveLearnMoreClick() {
|
||||||
val code = SupportedLanguages.getCurrentSupportedLanguageCode()
|
modelScope.launch {
|
||||||
.takeIf { it == SupportedLanguages.RUSSIAN }
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.GiveRevokePermission))
|
||||||
?: SupportedLanguages.ENGLISH
|
}
|
||||||
|
|
||||||
val url = "https://tangem.com/$code/blog/post/give-revoke-permission/"
|
|
||||||
urlOpener.openUrl(url)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isMultipleSignRequired(useCase: WcSignUseCase<*>): Boolean {
|
private fun isMultipleSignRequired(useCase: WcSignUseCase<*>): Boolean {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import arrow.core.getOrElse
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
import com.arkivanov.decompose.router.slot.activate
|
import com.arkivanov.decompose.router.slot.activate
|
||||||
import com.arkivanov.decompose.router.slot.dismiss
|
import com.arkivanov.decompose.router.slot.dismiss
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
|
|
@ -34,13 +35,12 @@ import com.tangem.features.yield.supply.impl.active.model.transformers.YieldSupp
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyApproveComponent
|
import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyApproveComponent
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
||||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import com.tangem.utils.logging.TangemLogger
|
||||||
import com.tangem.utils.transformer.update
|
import com.tangem.utils.transformer.update
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import com.tangem.utils.logging.TangemLogger
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("LongParameterList", "LargeClass")
|
@Suppress("LongParameterList", "LargeClass")
|
||||||
|
|
@ -160,7 +160,9 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onReadMoreClick() {
|
fun onReadMoreClick() {
|
||||||
urlOpener.openUrl(TangemBlogUrlBuilder.YIELD_SUPPLY_HOW_IT_WORKS_URL)
|
modelScope.launch {
|
||||||
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.HowYieldModeWorks))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeOnCurrencyStatusUpdates() {
|
private fun subscribeOnCurrencyStatusUpdates() {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.promo.model
|
||||||
|
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
import com.arkivanov.decompose.router.slot.activate
|
import com.arkivanov.decompose.router.slot.activate
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
|
|
@ -11,13 +12,12 @@ import com.tangem.core.navigation.url.UrlOpener
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.features.yield.supply.api.YieldSupplyPromoComponent
|
import com.tangem.features.yield.supply.api.YieldSupplyPromoComponent
|
||||||
import com.tangem.features.yield.supply.impl.R
|
|
||||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||||
|
import com.tangem.features.yield.supply.impl.R
|
||||||
import com.tangem.features.yield.supply.impl.promo.YieldSupplyPromoConfig
|
import com.tangem.features.yield.supply.impl.promo.YieldSupplyPromoConfig
|
||||||
import com.tangem.features.yield.supply.impl.promo.entity.YieldSupplyPromoUM
|
import com.tangem.features.yield.supply.impl.promo.entity.YieldSupplyPromoUM
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder
|
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder.YIELD_SUPPLY_HOW_IT_WORKS_URL
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
|
|
@ -32,8 +32,8 @@ internal class YieldSupplyPromoModel @Inject constructor(
|
||||||
val params: YieldSupplyPromoComponent.Params = paramsContainer.require()
|
val params: YieldSupplyPromoComponent.Params = paramsContainer.require()
|
||||||
|
|
||||||
val uiState: YieldSupplyPromoUM = YieldSupplyPromoUM(
|
val uiState: YieldSupplyPromoUM = YieldSupplyPromoUM(
|
||||||
tosLink = TangemBlogUrlBuilder.YIELD_SUPPLY_TOS_URL,
|
tosLink = AAVE_TOS_URL,
|
||||||
policyLink = TangemBlogUrlBuilder.YIELD_SUPPLY_PRIVACY_URL,
|
policyLink = AAVE_PRIVACY_URL,
|
||||||
tokenSymbol = params.currency.symbol,
|
tokenSymbol = params.currency.symbol,
|
||||||
title = resourceReference(
|
title = resourceReference(
|
||||||
R.string.yield_module_promo_screen_title_v2,
|
R.string.yield_module_promo_screen_title_v2,
|
||||||
|
|
@ -69,10 +69,17 @@ internal class YieldSupplyPromoModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHowItWorksClick() {
|
override fun onHowItWorksClick() {
|
||||||
urlOpener.openUrl(YIELD_SUPPLY_HOW_IT_WORKS_URL)
|
modelScope.launch {
|
||||||
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.HowYieldModeWorks))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartEarningClick() {
|
override fun onStartEarningClick() {
|
||||||
bottomSheetNavigation.activate(YieldSupplyPromoConfig.Action)
|
bottomSheetNavigation.activate(YieldSupplyPromoConfig.Action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val AAVE_TOS_URL = "https://aave.com/terms-of-service"
|
||||||
|
const val AAVE_PRIVACY_URL = "https://aave.com/privacy-policy"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.approve.model
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import com.tangem.blockchain.common.TransactionData
|
import com.tangem.blockchain.common.TransactionData
|
||||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
import com.tangem.common.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
|
@ -39,7 +40,6 @@ import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyAp
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsComponent
|
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsComponent
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsUpdateTrigger
|
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsUpdateTrigger
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
|
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.logging.TangemLogger
|
import com.tangem.utils.logging.TangemLogger
|
||||||
import com.tangem.utils.transformer.update
|
import com.tangem.utils.transformer.update
|
||||||
|
|
@ -113,7 +113,9 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onReadMoreClick() {
|
fun onReadMoreClick() {
|
||||||
urlOpener.openUrl(TangemBlogUrlBuilder.FEE_BLOG_LINK)
|
modelScope.launch {
|
||||||
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.WhatIsTransactionFee))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFeeReload() {
|
override fun onFeeReload() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.features.yield.supply.impl.subcomponents.stopearning.model
|
package com.tangem.features.yield.supply.impl.subcomponents.stopearning.model
|
||||||
|
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
|
import com.tangem.common.TangemBlogUrlBuilder
|
||||||
import com.tangem.common.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
import com.tangem.common.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
|
@ -39,7 +40,6 @@ 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.notifications.entity.YieldSupplyNotificationData
|
||||||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
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.features.yield.supply.impl.subcomponents.stopearning.model.transformer.YieldSupplyStopEarningFeeContentTransformer
|
||||||
import com.tangem.utils.TangemBlogUrlBuilder
|
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.extensions.orZero
|
import com.tangem.utils.extensions.orZero
|
||||||
import com.tangem.utils.logging.TangemLogger
|
import com.tangem.utils.logging.TangemLogger
|
||||||
|
|
@ -128,7 +128,9 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onReadMoreClick() {
|
fun onReadMoreClick() {
|
||||||
urlOpener.openUrl(TangemBlogUrlBuilder.FEE_BLOG_LINK)
|
modelScope.launch {
|
||||||
|
urlOpener.openUrl(TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.WhatIsTransactionFee))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClick() {
|
fun onClick() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue