diff --git a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt
index 4ddbac7a6a..70ce92ea14 100644
--- a/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt
+++ b/app/src/main/java/com/tangem/tap/di/domain/YieldSupplyDomainModule.kt
@@ -88,4 +88,24 @@ internal object YieldSupplyDomainModule {
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
+
+ @Provides
+ @Singleton
+ fun provideYieldSupplyGetApyUseCase(
+ yieldSupplyMarketRepository: YieldSupplyMarketRepository,
+ ): YieldSupplyGetApyUseCase {
+ return YieldSupplyGetApyUseCase(
+ yieldSupplyMarketRepository = yieldSupplyMarketRepository,
+ )
+ }
+
+ @Provides
+ @Singleton
+ fun provideYieldSupplyGetChartUseCase(
+ yieldSupplyMarketRepository: YieldSupplyMarketRepository,
+ ): YieldSupplyGetChartUseCase {
+ return YieldSupplyGetChartUseCase(
+ yieldSupplyMarketRepository = yieldSupplyMarketRepository,
+ )
+ }
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/YieldSupply.kt b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/YieldSupply.kt
index 9fee6a798a..0665ec199b 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/YieldSupply.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/YieldSupply.kt
@@ -41,47 +41,32 @@ internal class YieldSupply(
private fun createDevEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
environment = ApiEnvironment.DEV,
baseUrl = "[REDACTED_ENV_URL]",
- headers = createHeaders(ApiEnvironment.DEV),
+ headers = createHeaders(),
)
private fun createStageEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
environment = ApiEnvironment.STAGE,
baseUrl = "[REDACTED_ENV_URL]",
- headers = createHeaders(ApiEnvironment.STAGE),
+ headers = createHeaders(),
)
private fun createMockedEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
environment = ApiEnvironment.MOCK,
baseUrl = "[REDACTED_ENV_URL]",
- headers = createHeaders(ApiEnvironment.MOCK),
+ headers = createHeaders(),
)
private fun createProdEnvironment(): ApiEnvironmentConfig = ApiEnvironmentConfig(
environment = ApiEnvironment.PROD,
baseUrl = "https://yield.tangem.org/",
- headers = createHeaders(ApiEnvironment.PROD),
+ headers = createHeaders(),
)
- private fun createHeaders(apiEnvironment: ApiEnvironment) = buildMap {
- put(
- key = "Authorization",
- value = ProviderSuspend {
- "Bearer " + environmentConfigStorage.getConfigSync().yieldModuleApiKey
- },
- )
- put(key = "api-key", value = ProviderSuspend { getApiKey(apiEnvironment) })
+ private fun createHeaders() = buildMap {
+ put(key = "api-key", value = ProviderSuspend {
+ environmentConfigStorage.getConfigSync().yieldModuleApiKey.orEmpty()
+ })
putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider, appInfoProvider).values)
putAll(from = RequestHeader.AuthenticationHeader(authProvider).values)
}
-
- private fun getApiKey(apiEnvironment: ApiEnvironment): String {
- return when (apiEnvironment) {
- ApiEnvironment.MOCK,
- ApiEnvironment.DEV,
- ApiEnvironment.DEV_2,
- -> environmentConfigStorage.getConfigSync().tangemApiKeyDev
- ApiEnvironment.STAGE -> environmentConfigStorage.getConfigSync().tangemApiKeyStage
- ApiEnvironment.PROD -> environmentConfigStorage.getConfigSync().tangemApiKey
- } ?: error("No tangem tech api config provided")
- }
}
\ No newline at end of file
diff --git a/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt b/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt
index 2d7e832808..cb64ca1ea5 100644
--- a/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt
+++ b/core/datasource/src/test/kotlin/com/tangem/datasource/api/common/config/managers/ProdApiConfigsManagerTest.kt
@@ -198,8 +198,7 @@ internal class ProdApiConfigsManagerTest {
environment = ApiEnvironment.PROD,
baseUrl = "https://yield.tangem.org/",
headers = mapOf(
- "Authorization" to ProviderSuspend { "Bearer " + MockEnvironmentConfigStorage.YIELD_MODULE_KEY },
- "api-key" to ProviderSuspend { MockEnvironmentConfigStorage.TANGEM_API_KEY },
+ "api-key" to ProviderSuspend { MockEnvironmentConfigStorage.YIELD_MODULE_KEY },
"card_id" to ProviderSuspend { APP_CARD_ID },
"card_public_key" to ProviderSuspend { APP_CARD_PUBLIC_KEY },
"version" to ProviderSuspend { VERSION_NAME },
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 47b4f344fa..88c15e79d0 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -1266,8 +1266,12 @@
Используйте %s или отсканируйте карту/кольцо, чтобы получить доступ к своему кошельку
Соединение не удалось: это dApp использует Wallet Connect версии 1.0, которая не поддерживается. Убедитесь, что dApp поддерживает Wallet Connect версии 2.0 для успешного подключения.
Будьте в курсе новых функций и новостей
+ Мгновенные уведомления о транзакциях, обменах и важных обновлениях.
+ Уведомления о транзакциях
Получайте уведомления о входящих транзакциях
Узнавайте первым о новых акциях
+ Ранний доступ к новым функциям и эксклюзивным предложениям.
+ Новые функции и важные новости
Хотите использовать Push-уведомления?
Добавить новый кошелек
Вы уверены, что хотите забыть этот кошелек?
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index d29df471fb..ffd86a9798 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -1743,6 +1743,7 @@
Confirm approval
Text about your money in balance [PLACEHOLDER]
Your %s is deposited in Aave
+ Unable to load chart...
The amount received, %1$s %2$s was not deposited to Aave.
Earn %1$s%%
Available
@@ -1760,6 +1761,7 @@
Maximum fee
Fee policy
Network fee is too high right now. Waiting until it falls below your limit.
+ Historical returns
Write description here. In one, two or three lines will be awesome. [PLACEHOLDER]
Some token approve needed
Check your network connection
@@ -1790,6 +1792,7 @@
Stop earning
Turning off will withdraw your funds from Aave, return them to %s in your wallet, and stop earning rewards.
The network fee will be deducted from the amount you withdraw.
+ Supply APR
APY
Make your money work — earn interest on your balance.
Earning on your balance
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt b/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt
index 86dacb20d6..860dba2c51 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt
@@ -5,9 +5,12 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
+import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@@ -82,7 +85,11 @@ fun Label(state: LabelUM, modifier: Modifier = Modifier) {
imageVector = ImageVector.vectorResource(wrappedIcon),
tint = iconColor,
contentDescription = null,
- modifier = Modifier.size(16.dp),
+ modifier = Modifier.size(16.dp).clickable(
+ interactionSource = remember { MutableInteractionSource() },
+ indication = ripple(bounded = false),
+ onClick = { state.onIconClick?.invoke() },
+ ),
)
}
}
diff --git a/core/utils/src/main/java/com/tangem/utils/TangemLinks.kt b/core/utils/src/main/java/com/tangem/utils/TangemBlogUrlBuilder.kt
similarity index 95%
rename from core/utils/src/main/java/com/tangem/utils/TangemLinks.kt
rename to core/utils/src/main/java/com/tangem/utils/TangemBlogUrlBuilder.kt
index 285b5859d2..576a078921 100644
--- a/core/utils/src/main/java/com/tangem/utils/TangemLinks.kt
+++ b/core/utils/src/main/java/com/tangem/utils/TangemBlogUrlBuilder.kt
@@ -2,7 +2,7 @@ package com.tangem.utils
import java.util.Locale
-object TangemLinks {
+object TangemBlogUrlBuilder {
private const val RU_LOCALE = "ru"
private const val EN_LOCALE = "en"
diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetApyUseCase.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetApyUseCase.kt
new file mode 100644
index 0000000000..6bb5070262
--- /dev/null
+++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetApyUseCase.kt
@@ -0,0 +1,14 @@
+package com.tangem.domain.yield.supply.usecase
+
+import arrow.core.Either
+import com.tangem.domain.yield.supply.YieldSupplyMarketRepository
+
+class YieldSupplyGetApyUseCase(
+ private val yieldSupplyMarketRepository: YieldSupplyMarketRepository,
+) {
+
+ suspend operator fun invoke(tokenAddress: String): Either = Either.catch {
+ val apys = yieldSupplyMarketRepository.getCachedMarkets() ?: yieldSupplyMarketRepository.updateMarkets()
+ apys.first { it.tokenAddress == tokenAddress }.apy.toString()
+ }
+}
\ No newline at end of file
diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetChartUseCase.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetChartUseCase.kt
new file mode 100644
index 0000000000..06cb773d1c
--- /dev/null
+++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/usecase/YieldSupplyGetChartUseCase.kt
@@ -0,0 +1,16 @@
+package com.tangem.domain.yield.supply.usecase
+
+import arrow.core.Either
+import com.tangem.domain.models.currency.CryptoCurrency
+import com.tangem.domain.yield.supply.YieldSupplyMarketRepository
+import com.tangem.domain.yield.supply.models.YieldSupplyMarketChartData
+
+class YieldSupplyGetChartUseCase(
+ private val yieldSupplyMarketRepository: YieldSupplyMarketRepository,
+) {
+
+ suspend operator fun invoke(cryptoCurrency: CryptoCurrency.Token): Either =
+ Either.catch {
+ yieldSupplyMarketRepository.getTokenChart(cryptoCurrency)
+ }
+}
\ No newline at end of file
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt
index 664d23a834..ba91d7d75e 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorModel.kt
@@ -29,7 +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.TangemBlogUrlBuilder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
import kotlinx.coroutines.flow.MutableStateFlow
@@ -77,7 +77,7 @@ internal class FeeSelectorModel @Inject constructor(
}
fun onReadMoreClicked() {
- urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
+ urlOpener.openUrl(TangemBlogUrlBuilder.FEE_BLOG_LINK)
}
private fun initAppCurrency() {
diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt
index df672cadf7..539f5ee668 100644
--- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt
+++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt
@@ -74,7 +74,7 @@ import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalcula
import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction
import com.tangem.features.staking.impl.presentation.state.utils.withStubUnstakeAction
import com.tangem.utils.Provider
-import com.tangem.utils.TangemLinks.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
+import com.tangem.utils.TangemBlogUrlBuilder.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.isSingleItem
import com.tangem.utils.extensions.orZero
diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
index f7cf259a23..4f013dac67 100644
--- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
+++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt
@@ -63,7 +63,7 @@ import com.tangem.feature.swap.ui.StateBuilder
import com.tangem.feature.swap.utils.formatToUIRepresentation
import com.tangem.features.swap.SwapComponent
import com.tangem.utils.Provider
-import com.tangem.utils.TangemLinks.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
+import com.tangem.utils.TangemBlogUrlBuilder.RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP
import com.tangem.utils.coroutines.*
import com.tangem.utils.isNullOrZero
import kotlinx.coroutines.NonCancellable
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/YieldSupplyApyComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/YieldSupplyApyComponent.kt
new file mode 100644
index 0000000000..7fde37766d
--- /dev/null
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/YieldSupplyApyComponent.kt
@@ -0,0 +1,61 @@
+package com.tangem.features.yield.supply.impl.apy
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import com.tangem.core.decompose.context.AppComponentContext
+import com.tangem.core.decompose.context.child
+import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
+import com.tangem.domain.models.currency.CryptoCurrency
+import com.tangem.features.yield.supply.impl.apy.ui.YieldSupplyApyContent
+import com.tangem.features.yield.supply.impl.chart.DefaultYieldSupplyChartComponent
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.update
+
+internal class YieldSupplyApyComponent(
+ private val appComponentContext: AppComponentContext,
+ private val params: Params,
+) : ComposableBottomSheetComponent, AppComponentContext by appComponentContext {
+
+ val loadingState: StateFlow
+ field = MutableStateFlow(true)
+ private val chartComponent = DefaultYieldSupplyChartComponent(
+ appComponentContext = child("chartComponent"),
+ params = DefaultYieldSupplyChartComponent.Params(
+ cryptoCurrency = params.cryptoCurrency as CryptoCurrency.Token,
+ callback = object : DefaultYieldSupplyChartComponent.ModelCallback {
+ override fun onStartLoading() {
+ loadingState.update { true }
+ }
+
+ override fun onSuccessLoad() {
+ loadingState.update { false }
+ }
+
+ override fun onLoadFail() {
+ loadingState.update { false }
+ }
+ },
+ ),
+ )
+
+ override fun dismiss() {
+ params.onBackClick()
+ }
+
+ @Composable
+ override fun BottomSheet() {
+ val state by loadingState.collectAsState()
+ YieldSupplyApyContent(
+ isLoading = state,
+ onBackClick = params.onBackClick,
+ chartComponent = chartComponent,
+ )
+ }
+
+ data class Params(
+ val cryptoCurrency: CryptoCurrency,
+ val onBackClick: () -> Unit,
+ )
+}
\ No newline at end of file
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt
new file mode 100644
index 0000000000..8d419ff256
--- /dev/null
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt
@@ -0,0 +1,195 @@
+package com.tangem.features.yield.supply.impl.apy.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.InlineTextContent
+import androidx.compose.foundation.text.appendInlineContent
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.Placeholder
+import androidx.compose.ui.text.PlaceholderVerticalAlign
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.tangem.core.ui.components.SecondaryButton
+import com.tangem.core.ui.components.SpacerH12
+import com.tangem.core.ui.components.SpacerH16
+import com.tangem.core.ui.components.SpacerH2
+import com.tangem.core.ui.components.SpacerH24
+import com.tangem.core.ui.components.SpacerH8
+import com.tangem.core.ui.components.SpacerW4
+import com.tangem.core.ui.components.TextShimmer
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
+import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
+import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
+import com.tangem.core.ui.decompose.ComposableContentComponent
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.yield.supply.impl.R
+
+@Suppress("LongMethod")
+@Composable
+internal fun YieldSupplyApyContent(
+ isLoading: Boolean,
+ onBackClick: () -> Unit,
+ chartComponent: ComposableContentComponent,
+) {
+ TangemModalBottomSheet(
+ config = TangemBottomSheetConfig(
+ isShown = true,
+ onDismissRequest = onBackClick,
+ content = TangemBottomSheetConfigContent.Empty,
+ ),
+ onBack = onBackClick,
+ containerColor = TangemTheme.colors.background.tertiary,
+ title = {
+ TangemModalBottomSheetTitle(
+ endIconRes = com.tangem.core.ui.R.drawable.ic_close_24,
+ onEndClick = onBackClick,
+ )
+ },
+ content = {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ ) {
+ Text(
+ text = stringResourceSafe(R.string.yield_module_rate_info_sheet_title),
+ style = TangemTheme.typography.h3,
+ color = TangemTheme.colors.text.primary1,
+ )
+ SpacerH8()
+ Text(
+ text = stringResourceSafe(R.string.yield_module_rate_info_sheet_description),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.secondary,
+ textAlign = TextAlign.Center,
+ )
+ SpacerH12()
+ val inlineIconId = "aaveIcon"
+ Text(
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ textAlign = TextAlign.Center,
+ text = buildAnnotatedString {
+ append(stringResourceSafe(R.string.yield_module_rate_info_sheet_powered_by))
+ append(" ")
+ appendInlineContent(inlineIconId, "[icon]")
+ append("Aave")
+ },
+ inlineContent = mapOf(
+ inlineIconId to InlineTextContent(
+ Placeholder(
+ width = 16.sp,
+ height = 16.sp,
+ placeholderVerticalAlign = PlaceholderVerticalAlign.Center,
+ ),
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.img_aave_22),
+ contentDescription = null,
+ )
+ },
+ ),
+ )
+ SpacerH24()
+
+ ApyChart(
+ isChartLoading = isLoading,
+ chartComponent = chartComponent,
+ modifier = Modifier.padding(horizontal = 12.dp),
+ )
+
+ SpacerH16()
+
+ SecondaryButton(
+ text = stringResourceSafe(R.string.common_got_it),
+ onClick = onBackClick,
+ modifier = Modifier
+ .fillMaxWidth(),
+ )
+ }
+ },
+ )
+}
+
+@Composable
+private fun ApyChart(
+ isChartLoading: Boolean,
+ chartComponent: ComposableContentComponent,
+ modifier: Modifier = Modifier,
+) {
+ Column(modifier = modifier.fillMaxWidth()) {
+ if (isChartLoading) {
+ TextShimmer(
+ text = stringResourceSafe(R.string.yield_module_historical_returns),
+ style = TangemTheme.typography.subtitle1,
+ )
+ SpacerH2()
+ TextShimmer(
+ text = stringResourceSafe(R.string.yield_module_supply_apr),
+ style = TangemTheme.typography.subtitle2,
+ )
+ } else {
+ Text(
+ text = stringResourceSafe(R.string.yield_module_historical_returns),
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ )
+ SpacerH2()
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ AccentDot()
+ SpacerW4()
+ Text(
+ text = stringResourceSafe(R.string.yield_module_supply_apr),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+ }
+ SpacerH12()
+ chartComponent.Content(Modifier)
+ }
+}
+
+@Composable
+private fun AccentDot(modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .padding(4.dp)
+ .size(TangemTheme.dimens.size8)
+ .background(color = TangemTheme.colors.icon.accent, shape = CircleShape),
+ )
+}
+
+// region Preview
+@Composable
+@Preview(showBackground = true, widthDp = 360)
+@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun YieldSupplyApyContentContentPreview() {
+ TangemThemePreview {
+ YieldSupplyApyContent(
+ isLoading = false,
+ onBackClick = {},
+ chartComponent = ComposableContentComponent.EMPTY,
+ )
+ }
+}
+// endregion
\ No newline at end of file
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/DefaultYieldSupplyChartComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/DefaultYieldSupplyChartComponent.kt
index 0fb4d6b26a..c98ec76f41 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/DefaultYieldSupplyChartComponent.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/DefaultYieldSupplyChartComponent.kt
@@ -6,6 +6,8 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
+import com.tangem.core.ui.decompose.ComposableContentComponent
+import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.yield.supply.impl.chart.model.YieldSupplyChartModel
import com.tangem.features.yield.supply.impl.chart.ui.YieldSupplyChartContent
import dagger.assisted.Assisted
@@ -14,13 +16,13 @@ import dagger.assisted.AssistedInject
internal class DefaultYieldSupplyChartComponent @AssistedInject constructor(
@Assisted private val appComponentContext: AppComponentContext,
- @Assisted private val params: YieldSupplyChartModel.Params,
-) : AppComponentContext by appComponentContext {
+ @Assisted private val params: Params,
+) : ComposableContentComponent, AppComponentContext by appComponentContext {
private val model: YieldSupplyChartModel = getOrCreateModel(params = params)
@Composable
- fun Content(modifier: Modifier = Modifier) {
+ override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
YieldSupplyChartContent(
state = state,
@@ -30,6 +32,17 @@ internal class DefaultYieldSupplyChartComponent @AssistedInject constructor(
@AssistedFactory
internal interface Factory {
- fun create(context: AppComponentContext, params: YieldSupplyChartModel.Params): DefaultYieldSupplyChartComponent
+ fun create(context: AppComponentContext, params: Params): DefaultYieldSupplyChartComponent
+ }
+
+ internal data class Params(
+ val cryptoCurrency: CryptoCurrency.Token,
+ val callback: ModelCallback? = null,
+ )
+
+ internal interface ModelCallback {
+ fun onStartLoading()
+ fun onSuccessLoad()
+ fun onLoadFail()
}
}
\ No newline at end of file
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/entity/YieldSupplyChartUM.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/entity/YieldSupplyChartUM.kt
index a14dd6c6b7..3bba6034ce 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/entity/YieldSupplyChartUM.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/entity/YieldSupplyChartUM.kt
@@ -14,7 +14,10 @@ internal sealed class YieldSupplyChartUM {
data class Error(val onRetry: () -> Unit) : YieldSupplyChartUM()
@Immutable
- data class Data(val chartData: YieldSupplyMarketChartDataUM) : YieldSupplyChartUM()
+ data class Data(
+ val chartData: YieldSupplyMarketChartDataUM,
+ val monthLables: ImmutableList,
+ ) : YieldSupplyChartUM()
}
@Immutable
@@ -22,16 +25,18 @@ internal data class YieldSupplyMarketChartDataUM(
val y: ImmutableList,
val x: ImmutableList,
val avr: Double,
+ val percentFormat: String,
) {
companion object {
@Suppress("MagicNumber")
fun mock(): YieldSupplyMarketChartDataUM {
- // TODO [REDACTED_TASK_KEY] replace mock values with real APY series
val y = listOf(
4.6, 4.0, 4.2, 3.3, 2.5, 5.6, 4.2, 6.7, 3.5, 2.5, 4.5, 3.4,
+ 4.6, 4.0, 4.2, 3.3, 2.5, 5.6, 4.2, 6.7, 3.5, 2.5, 4.5, 3.4,
+ 4.2, 6.7, 3.5, 2.5, 4.5, 3.4,
).toImmutableList()
val x = List(y.size) { 1.0 }.toImmutableList()
- return YieldSupplyMarketChartDataUM(y = y, x = x, avr = 5.15)
+ return YieldSupplyMarketChartDataUM(y = y, x = x, avr = 5.15, "%.1f")
}
}
}
\ No newline at end of file
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/model/YieldSupplyChartModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/model/YieldSupplyChartModel.kt
index e5e0c3992d..8a5df343d6 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/model/YieldSupplyChartModel.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/model/YieldSupplyChartModel.kt
@@ -3,34 +3,95 @@ package com.tangem.features.yield.supply.impl.chart.model
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
+import com.tangem.domain.yield.supply.models.YieldSupplyMarketChartData
+import com.tangem.domain.yield.supply.usecase.YieldSupplyGetChartUseCase
+import com.tangem.features.yield.supply.impl.chart.DefaultYieldSupplyChartComponent
import com.tangem.features.yield.supply.impl.chart.entity.YieldSupplyChartUM
import com.tangem.features.yield.supply.impl.chart.entity.YieldSupplyMarketChartDataUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
import javax.inject.Inject
-@Suppress("UnusedPrivateProperty")
@ModelScoped
internal class YieldSupplyChartModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
+ private val yieldSupplyGetChartUseCase: YieldSupplyGetChartUseCase,
) : Model() {
- data class Params(
- val tokenContractAddress: String,
- val onRetry: () -> Unit = {},
- )
-
- private val params: Params = paramsContainer.require()
+ private val params: DefaultYieldSupplyChartComponent.Params = paramsContainer.require()
val uiState: StateFlow
field = MutableStateFlow(YieldSupplyChartUM.Loading)
init {
- // TODO [REDACTED_TASK_KEY]
- val chartData = YieldSupplyMarketChartDataUM.mock()
- uiState.update { YieldSupplyChartUM.Data(chartData = chartData) }
+ loadChart()
+ }
+
+ private fun loadChart() {
+ modelScope.launch(dispatchers.default) {
+ params.callback?.onStartLoading()
+ yieldSupplyGetChartUseCase(params.cryptoCurrency).onRight { chartData ->
+ if (chartData.y.isEmpty()) {
+ uiState.update {
+ YieldSupplyChartUM.Error({
+ uiState.update { YieldSupplyChartUM.Loading }
+ loadChart()
+ })
+ }
+ params.callback?.onLoadFail()
+ } else {
+ uiState.update {
+ YieldSupplyChartUM.Data(
+ chartData = YieldSupplyMarketChartDataUM(
+ y = chartData.y.toImmutableList(),
+ x = chartData.x.toImmutableList(),
+ avr = chartData.avr,
+ percentFormat = getPercentFormatPattern(chartData),
+ ),
+ monthLables = lastMonthLabels().toImmutableList(),
+ )
+ }
+ params.callback?.onSuccessLoad()
+ }
+ }.onLeft {
+ uiState.update {
+ YieldSupplyChartUM.Error({
+ uiState.update { YieldSupplyChartUM.Loading }
+ loadChart()
+ })
+ }
+ params.callback?.onLoadFail()
+ }
+ }
+ }
+
+ @Suppress("MagicNumber")
+ private fun getPercentFormatPattern(chartData: YieldSupplyMarketChartData): String {
+ return when {
+ chartData.y.all { it < 1.0 } -> "%.1f"
+ chartData.y.all { it < 0.1 } -> "%.2f"
+ else -> "%.0f"
+ }
+ }
+ private fun lastMonthLabels(n: Int = MONTH_LABELS_COUNT, locale: Locale = Locale.getDefault()): List {
+ val calendar = Calendar.getInstance()
+ val formatter = SimpleDateFormat("MMM", locale)
+
+ return (n downTo 1).map {
+ calendar.add(Calendar.MONTH, -1)
+ formatter.format(calendar.time)
+ }.reversed()
+ }
+
+ companion object {
+ private const val MONTH_LABELS_COUNT = 5
}
}
\ No newline at end of file
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/ui/YieldSupplyChartContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/ui/YieldSupplyChartContent.kt
index 8dca6004ab..f820ca39a4 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/ui/YieldSupplyChartContent.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/chart/ui/YieldSupplyChartContent.kt
@@ -1,6 +1,7 @@
package com.tangem.features.yield.supply.impl.chart.ui
import android.content.res.Configuration
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -11,25 +12,31 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
-import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.State
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisLabelComponent
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottomAxis
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberCustomStartAxis
import com.patrykandpatrick.vico.compose.cartesian.decoration.rememberHorizontalLine
-import com.patrykandpatrick.vico.compose.cartesian.fullWidth
+import com.patrykandpatrick.vico.compose.cartesian.layer.grouped
import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoScrollState
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberColumnCartesianLayer
+import com.patrykandpatrick.vico.compose.cartesian.segmented
import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent
import com.patrykandpatrick.vico.compose.common.shape.dashed
import com.patrykandpatrick.vico.core.cartesian.HorizontalLayout
@@ -40,6 +47,9 @@ import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModel
import com.patrykandpatrick.vico.core.cartesian.data.ColumnCartesianLayerModel
+import com.patrykandpatrick.vico.core.cartesian.decoration.HorizontalLine
+import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
+import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer.MergeMode
import com.patrykandpatrick.vico.core.common.shape.Shape
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SpacerH12
@@ -52,6 +62,8 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.yield.supply.impl.chart.entity.YieldSupplyChartUM
import com.tangem.features.yield.supply.impl.chart.entity.YieldSupplyMarketChartDataUM
+import kotlinx.collections.immutable.persistentListOf
+import java.util.Locale
@Composable
internal fun YieldSupplyChartContent(state: YieldSupplyChartUM, modifier: Modifier = Modifier) {
@@ -122,64 +134,187 @@ private fun YieldSupplyChartLoading(modifier: Modifier = Modifier) {
}
}
}
+ }
+}
- CircularProgressIndicator(
+@Suppress("MagicNumber")
+@Composable
+private fun YieldSupplyChartData(state: YieldSupplyChartUM.Data, modifier: Modifier = Modifier) {
+ val model = rememberChartModel(state.chartData)
+
+ val columnsLayer = rememberColumnsLayer(accentColor = TangemTheme.colors.text.accent)
+
+ val startAxis: VerticalAxis = rememberStartAxis(
+ labelColor = TangemTheme.colors.text.tertiary,
+ percentFormat = state.chartData.percentFormat,
+ )
+
+ val bottomAxis: HorizontalAxis = rememberBottomAxis(
+ labelColor = TangemTheme.colors.text.tertiary,
+ )
+
+ val referenceLineThickness = 2.dp
+ val referenceLine = rememberReferenceLine(
+ average = state.chartData.avr,
+ color = TangemTheme.colors.icon.primary1,
+ thickness = referenceLineThickness,
+ )
+
+ val chart = rememberCartesianChart(
+ columnsLayer,
+ startAxis = startAxis,
+ bottomAxis = bottomAxis,
+ decorations = listOf(referenceLine),
+ horizontalLayout = HorizontalLayout.segmented(),
+ )
+
+ val averageLabelTopPadding by rememberAverageLabelTopPadding(state.chartData)
+
+ Box(modifier = modifier) {
+ MonthLabelsRow(labels = state.monthLables, modifier = Modifier.align(Alignment.BottomEnd))
+ CartesianChartHost(
+ modifier = Modifier.padding(bottom = 4.dp),
+ chart = chart,
+ model = model,
+ zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
+ scrollState = rememberVicoScrollState(scrollEnabled = false),
+ )
+ AverageLabel(
modifier = Modifier
- .size(TangemTheme.dimens.size16)
- .align(Alignment.Center),
- color = TangemTheme.colors.text.tertiary,
+ .padding(start = 36.dp, top = averageLabelTopPadding)
+ .height(24.dp),
+ avr = state.chartData.avr.toString(),
)
}
}
@Composable
-private fun YieldSupplyChartData(state: YieldSupplyChartUM.Data, modifier: Modifier = Modifier) {
- val yValues = state.chartData.y
- val model = CartesianChartModel(ColumnCartesianLayerModel.build { series(yValues) })
+private fun rememberChartModel(data: YieldSupplyMarketChartDataUM): CartesianChartModel {
+ return remember(data.y) {
+ CartesianChartModel(
+ ColumnCartesianLayerModel.build {
+ series(data.y)
+ },
+ )
+ }
+}
- val layer = rememberColumnCartesianLayer()
+@Suppress("MagicNumber")
+@Composable
+private fun rememberColumnsLayer(accentColor: Color): ColumnCartesianLayer {
+ val column = rememberLineComponent(
+ color = accentColor,
+ thickness = 6.dp,
+ shape = Shape.rounded(40),
+ )
+ return rememberColumnCartesianLayer(
+ columnProvider = ColumnCartesianLayer.ColumnProvider.series(column),
+ columnCollectionSpacing = 3.dp,
+ mergeMode = { MergeMode.grouped() },
+ )
+}
- val startAxis: VerticalAxis = rememberCustomStartAxis(
- label = rememberAxisLabelComponent(color = TangemTheme.colors.text.tertiary),
+@Composable
+private fun rememberStartAxis(labelColor: Color, percentFormat: String): VerticalAxis {
+ return rememberCustomStartAxis(
+ label = rememberAxisLabelComponent(color = labelColor),
valueFormatter = CartesianValueFormatter { value, _, _ ->
- val pct = value.toInt()
+ val pct = String.format(Locale.getDefault(), percentFormat, value)
"$pct%"
},
- )
-
- val bottomAxis: HorizontalAxis = rememberBottomAxis(
- label = rememberAxisLabelComponent(color = TangemTheme.colors.text.tertiary),
guideline = null,
tick = null,
line = null,
)
+}
- val average = yValues.map { it.toDouble() }.average()
+@Composable
+private fun rememberBottomAxis(labelColor: Color): HorizontalAxis {
+ return rememberBottomAxis(
+ label = rememberAxisLabelComponent(color = labelColor),
+ guideline = null,
+ tick = null,
+ line = null,
+ valueFormatter = CartesianValueFormatter { _, _, _ ->
+ ""
+ },
+ )
+}
- val referenceLine = rememberHorizontalLine(
+@Composable
+private fun rememberReferenceLine(average: Double, color: Color, thickness: Dp): HorizontalLine {
+ return rememberHorizontalLine(
y = { average },
line = rememberLineComponent(
- color = TangemTheme.colors.text.tertiary,
- thickness = TangemTheme.dimens.size1,
- shape = Shape.dashed(Shape.Rectangle, TangemTheme.dimens.size4, TangemTheme.dimens.size4),
+ color = color,
+ thickness = thickness,
+ shape = Shape.dashed(Shape.Pill, 4.dp, 2.dp),
),
)
+}
- val chart = rememberCartesianChart(
- layer,
- startAxis = startAxis,
- bottomAxis = bottomAxis,
- decorations = listOf(referenceLine),
- horizontalLayout = HorizontalLayout.fullWidth(),
- )
+@Composable
+private fun rememberAverageLabelTopPadding(data: YieldSupplyMarketChartDataUM): State {
+ return remember(data.y, data.avr) {
+ derivedStateOf {
+ val chartHeight = 105.dp
+ val labelHeight = 24.dp
+ val referenceLineThickness = 2.dp
+ val desiredGap = 3.dp
+ val opticalNudge = 1.dp
+ val extraPaddingAboveLine = 2.dp
+ val gapAboveLine = desiredGap + referenceLineThickness / 2 + opticalNudge + extraPaddingAboveLine
+ val chartContentBottomInset = 10.dp
- CartesianChartHost(
- modifier = modifier,
- chart = chart,
- model = model,
- zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
- scrollState = rememberVicoScrollState(scrollEnabled = false),
- )
+ val maxValueInSeries = (data.y.maxOrNull() ?: 0.0).coerceAtLeast(data.avr)
+ val averageRatio = if (maxValueInSeries == 0.0) {
+ 0f
+ } else {
+ (data.avr / maxValueInSeries).coerceIn(0.0, 1.0).toFloat()
+ }
+ val computedTopPadding = (chartHeight - chartContentBottomInset) * (1f - averageRatio)
+ -labelHeight - gapAboveLine
+ if (computedTopPadding < 2.dp) 2.dp else computedTopPadding
+ }
+ }
+}
+
+@Composable
+private fun MonthLabelsRow(labels: kotlinx.collections.immutable.ImmutableList, modifier: Modifier = Modifier) {
+ Row(
+ modifier = modifier
+ .padding(start = 38.dp, top = 4.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ ) {
+ repeat(labels.size) { index ->
+ Text(
+ text = labels[index],
+ modifier = Modifier
+ .weight(1f)
+ .height(16.dp),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+ }
+}
+
+@Composable
+private fun AverageLabel(avr: String, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier.background(
+ color = TangemTheme.colors.icon.primary1,
+ shape = TangemTheme.shapes.roundedCornersSmall2,
+ ),
+ ) {
+ Text(
+ text = stringResourceSafe(R.string.yield_module_rate_info_sheet_chart_average, avr),
+ style = TangemTheme.typography.caption1,
+ color = TangemTheme.colors.text.primary2,
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
+ )
+ }
}
// region Preview
@@ -199,7 +334,10 @@ private class YieldSupplyChartPreviewProvider : PreviewParameterProvider EmptyComposableBottomSheetComponent
+ YieldSupplyPromoConfig.Apy -> YieldSupplyApyComponent(
+ appComponentContext = childByContext(componentContext),
+ params = YieldSupplyApyComponent.Params(
+ cryptoCurrency = params.currency,
+ onBackClick = {
+ model.bottomSheetNavigation.dismiss()
+ },
+ ),
+ )
YieldSupplyPromoConfig.Action -> YieldSupplyStartEarningEntryComponent(
appComponentContext = childByContext(componentContext),
params = YieldSupplyStartEarningEntryComponent.Params(
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt
index 1f2e90bf5c..0e7f24f5a7 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt
@@ -30,7 +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.TangemBlogUrlBuilder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
import kotlinx.collections.immutable.persistentListOf
@@ -101,7 +101,7 @@ internal class YieldSupplyApproveModel @Inject constructor(
}
fun onReadMoreClick() {
- urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
+ urlOpener.openUrl(TangemBlogUrlBuilder.FEE_BLOG_LINK)
}
override fun onFeeReload() {
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt
index 5ea64abb48..b1bba83d10 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt
@@ -27,7 +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.TangemBlogUrlBuilder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.orZero
import com.tangem.utils.transformer.update
@@ -103,7 +103,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
}
fun onReadMoreClick() {
- urlOpener.openUrl(TangemLinks.FEE_BLOG_LINK)
+ urlOpener.openUrl(TangemBlogUrlBuilder.FEE_BLOG_LINK)
}
fun onClick() {