From 8f9b356307182ba917c6019327ef5834b6e891a8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 26 May 2025 16:04:26 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 23 +++++ .../datasource/api/common/config/Express.kt | 4 +- .../api/common/config/TangemTech.kt | 4 +- .../tangem/datasource/di/ApiConfigsModule.kt | 20 +++- .../com/tangem/datasource/di/NetworkModule.kt | 7 +- .../tangem/datasource/utils/RequestHeader.kt | 7 +- .../managers/ProdApiConfigsManagerTest.kt | 9 +- core/res/src/main/res/values-de/strings.xml | 18 ++-- core/res/src/main/res/values-ja/strings.xml | 8 +- core/res/src/main/res/values/strings.xml | 5 + .../ui/components/items/DecriptionItem.kt | 16 ++-- .../data/common/currency/UserTokensSaver.kt | 31 +++--- .../common/currency/UserTokensSaverTest.kt | 94 +++++++------------ .../repository/DefaultCurrenciesRepository.kt | 10 ++ .../data/wallets/DefaultWalletsRepository.kt | 4 + .../tokens/repository/CurrenciesRepository.kt | 12 +++ .../repository/MockCurrenciesRepository.kt | 4 + .../wallets/repository/WalletsRepository.kt | 2 + .../GetWalletNotificationsEnabledUseCase.kt | 13 +++ .../usecase/SetNotificationsEnabledUseCase.kt | 8 ++ .../ui/components/TokenMarketDetailsBody.kt | 4 +- .../wallet-settings/impl/build.gradle.kts | 1 + .../preview/PreviewWalletSettingsComponent.kt | 4 + .../entity/WalletSettingsItemUM.kt | 7 ++ .../model/WalletSettingsModel.kt | 61 ++++++++---- .../walletsettings/ui/WalletSettingsScreen.kt | 29 ++++++ .../walletsettings/utils/ItemsBuilder.kt | 36 +++++++ 27 files changed, 326 insertions(+), 115 deletions(-) rename features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/Description.kt => core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt (90%) create mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNotificationsEnabledUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 1fbf5cb42e..9b80eb5ff0 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -1,6 +1,7 @@ package com.tangem.tap.di.domain import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.transaction.WalletAddressServiceRepository import com.tangem.domain.transaction.usecase.ParseSharedAddressUseCase import com.tangem.domain.transaction.usecase.ValidateWalletAddressUseCase @@ -245,4 +246,26 @@ internal object WalletsDomainModule { walletsRepository = walletsRepository, ) } + + @Provides + @Singleton + fun providesSetNotificationsEnabledUseCase( + walletsRepository: WalletsRepository, + currenciesRepository: CurrenciesRepository, + ): SetNotificationsEnabledUseCase { + return SetNotificationsEnabledUseCase( + walletsRepository = walletsRepository, + currenciesRepository = currenciesRepository, + ) + } + + @Provides + @Singleton + fun providesGetWalletNotificationsEnabledUseCase( + walletsRepository: WalletsRepository, + ): GetWalletNotificationsEnabledUseCase { + return GetWalletNotificationsEnabledUseCase( + walletsRepository = walletsRepository, + ) + } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/Express.kt b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/Express.kt index db32d40409..a42f4d1353 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/Express.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/Express.kt @@ -5,6 +5,7 @@ import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.datasource.utils.RequestHeader import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.utils.ProviderSuspend +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider /** @@ -18,6 +19,7 @@ internal class Express( private val environmentConfigStorage: EnvironmentConfigStorage, private val expressAuthProvider: ExpressAuthProvider, private val appVersionProvider: AppVersionProvider, + private val appInfoProvider: AppInfoProvider, ) : ApiConfig() { override val defaultEnvironment: ApiEnvironment = getInitialEnvironment() @@ -49,7 +51,7 @@ internal class Express( private fun createHeaders(isProd: Boolean) = buildMap { put(key = "api-key", value = ProviderSuspend { getApiKey(isProd) }) put(key = "session-id", value = ProviderSuspend(expressAuthProvider::getSessionId)) - putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider).values) + putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider, appInfoProvider).values) } private fun getApiKey(isProd: Boolean): String { diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemTech.kt b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemTech.kt index e15e7ce4e3..1c6f625016 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemTech.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/common/config/TangemTech.kt @@ -2,12 +2,14 @@ package com.tangem.datasource.api.common.config import com.tangem.datasource.api.common.AuthProvider import com.tangem.datasource.utils.RequestHeader +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider /** TangemTech [ApiConfig] */ internal class TangemTech( private val appVersionProvider: AppVersionProvider, private val authProvider: AuthProvider, + private val appInfoProvider: AppInfoProvider, ) : ApiConfig() { override val defaultEnvironment: ApiEnvironment = ApiEnvironment.PROD @@ -30,7 +32,7 @@ internal class TangemTech( ) private fun createHeaders() = buildMap { - putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider).values) + putAll(from = RequestHeader.AppVersionPlatformHeaders(appVersionProvider, appInfoProvider).values) putAll(from = RequestHeader.AuthenticationHeader(authProvider).values) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt index 174cf88a63..8afffb0a2a 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/ApiConfigsModule.kt @@ -5,6 +5,7 @@ import com.tangem.datasource.api.common.config.* import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider import dagger.Module import dagger.Provides @@ -22,8 +23,14 @@ internal object ApiConfigsModule { environmentConfigStorage: EnvironmentConfigStorage, expressAuthProvider: ExpressAuthProvider, appVersionProvider: AppVersionProvider, + appInfoProvider: AppInfoProvider, ): ApiConfig { - return Express(environmentConfigStorage, expressAuthProvider, appVersionProvider) + return Express( + environmentConfigStorage = environmentConfigStorage, + expressAuthProvider = expressAuthProvider, + appVersionProvider = appVersionProvider, + appInfoProvider = appInfoProvider, + ) } @Provides @@ -34,8 +41,15 @@ internal object ApiConfigsModule { @Provides @IntoSet - fun provideTangemTechConfig(appVersionProvider: AppVersionProvider, authProvider: AuthProvider): ApiConfig = - TangemTech(appVersionProvider, authProvider) + fun provideTangemTechConfig( + appVersionProvider: AppVersionProvider, + authProvider: AuthProvider, + appInfoProvider: AppInfoProvider, + ): ApiConfig = TangemTech( + appVersionProvider = appVersionProvider, + authProvider = authProvider, + appInfoProvider = appInfoProvider, + ) @Provides @IntoSet diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt index bfb13f75b1..1110e9f745 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt @@ -23,6 +23,7 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.utils.* import com.tangem.datasource.utils.RequestHeader.AppVersionPlatformHeaders import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider import dagger.Module import dagger.Provides @@ -162,6 +163,7 @@ internal object NetworkModule { @ApplicationContext context: Context, analyticsErrorHandler: AnalyticsErrorHandler, appVersionProvider: AppVersionProvider, + appInfoProvider: AppInfoProvider, ): TangemTechApiV2 { return provideTangemTechApiInternal( moshi = moshi, @@ -169,6 +171,7 @@ internal object NetworkModule { appVersionProvider = appVersionProvider, baseUrl = PROD_V2_TANGEM_TECH_BASE_URL, analyticsErrorHandler = analyticsErrorHandler, + appInfoProvider = appInfoProvider, ) } @@ -218,15 +221,17 @@ internal object NetworkModule { ) } + @Suppress("LongParameterList") @Deprecated("use createApi instead") private inline fun provideTangemTechApiInternal( moshi: Moshi, context: Context, appVersionProvider: AppVersionProvider, + appInfoProvider: AppInfoProvider, baseUrl: String, analyticsErrorHandler: AnalyticsErrorHandler, timeouts: Timeouts = Timeouts(), - requestHeaders: List = listOf(AppVersionPlatformHeaders(appVersionProvider)), + requestHeaders: List = listOf(AppVersionPlatformHeaders(appVersionProvider, appInfoProvider)), ): T { val client = OkHttpClient.Builder() .applyTimeoutAnnotations() diff --git a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt index a3ae68e61b..9375434e78 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/utils/RequestHeader.kt @@ -4,6 +4,7 @@ import android.os.Build import com.tangem.datasource.api.common.AuthProvider import com.tangem.datasource.utils.RequestHeader.CacheControlHeader.checkHeaderValueOrEmpty import com.tangem.utils.ProviderSuspend +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider import java.util.Locale import java.util.TimeZone @@ -25,7 +26,11 @@ sealed class RequestHeader(vararg pairs: Pair>) "card_public_key" to ProviderSuspend(authProvider::getCardPublicKey), ) - class AppVersionPlatformHeaders(appVersionProvider: AppVersionProvider) : RequestHeader( + class AppVersionPlatformHeaders( + appVersionProvider: AppVersionProvider, + appInfoProvider: AppInfoProvider, + ) : RequestHeader( + "system_version" to ProviderSuspend { appInfoProvider.osVersion }, "version" to ProviderSuspend { appVersionProvider.versionName }, "platform" to ProviderSuspend { "android" }, "language" to ProviderSuspend { Locale.getDefault().language.checkHeaderValueOrEmpty() }, 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 3167db2d61..4570f390fc 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 @@ -13,6 +13,7 @@ import com.tangem.datasource.api.common.config.ApiConfig.Companion.RELEASE_BUILD import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider import com.tangem.utils.ProviderSuspend +import com.tangem.utils.info.AppInfoProvider import com.tangem.utils.version.AppVersionProvider import io.mockk.every import io.mockk.mockk @@ -29,11 +30,12 @@ private val appVersionProvider = mockk() private val expressAuthProvider = mockk() private val stakeKitAuthProvider = mockk() private val appAuthProvider = mockk() +private val appInfoProvider = mockk() // Don't forget to add new config !!! private val API_CONFIGS = setOf( - Express(configManager, expressAuthProvider, appVersionProvider), - TangemTech(appVersionProvider, appAuthProvider), + Express(configManager, expressAuthProvider, appVersionProvider, appInfoProvider), + TangemTech(appVersionProvider, appAuthProvider, appInfoProvider), StakeKit(stakeKitAuthProvider), TangemVisa(appVersionProvider), ) @@ -53,6 +55,7 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { every { stakeKitAuthProvider.getApiKey() } returns STAKE_KIT_API_KEY every { appAuthProvider.getCardId() } returns APP_CARD_ID every { appAuthProvider.getCardPublicKey() } returns APP_CARD_PUBLIC_KEY + every { appInfoProvider.osVersion } returns "Android 16" } @Test @@ -129,6 +132,7 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { }, "session-id" to ProviderSuspend { EXPRESS_SESSION_ID }, "version" to ProviderSuspend { VERSION_NAME }, + "system_version" to ProviderSuspend { "Android 16" }, "platform" to ProviderSuspend { "android" }, "language" to ProviderSuspend { Locale.getDefault().language.checkHeaderValueOrEmpty() }, "timezone" to ProviderSuspend { @@ -151,6 +155,7 @@ internal class ProdApiConfigsManagerTest(private val model: Model) { "card_public_key" to ProviderSuspend { APP_CARD_PUBLIC_KEY }, "version" to ProviderSuspend { VERSION_NAME }, "platform" to ProviderSuspend { "android" }, + "system_version" to ProviderSuspend { "Android 16" }, "language" to ProviderSuspend { Locale.getDefault().language.checkHeaderValueOrEmpty() }, "timezone" to ProviderSuspend { TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT).checkHeaderValueOrEmpty() diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 077fdf8300..7ec5abe680 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -669,7 +669,7 @@ Identische Karten oder Ring Zugangscode Verfügbar mit %s - Der Kauf von Kryptowährungen bei Tangem wird von Drittanbietern zu deren Bedingungen durchgeführt. + Anbieter erleichtern Transaktionen Suche nach Land Nicht verfügbar Andere Währungen @@ -696,6 +696,10 @@ Nach Guthaben Token organisieren Gruppe löschen + Du kannst Benachrichtigungen für Tangem in den Einstellungen aktivieren. + Später aktivieren + Einstellungen + Benachrichtigungen aktivieren Wählen aus der Galerie aus Einstellungen Du hast keinen Zugriff auf deine Kamera gewährt @@ -867,7 +871,7 @@ Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an. Verfügbar Durchschnittliche Belohnungsquote - Was ist Staking? + Wie funktioniert Staking? %s geschätzter Profit Marktposition Metriken @@ -899,10 +903,10 @@ Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken - Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jeden tag. - Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jede Stunde. - Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jeden Monat. - Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jede Woche. + Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen kommen täglich an. + Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen werden stündlich gutgeschrieben. + Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen werden Dir jeden Monat gutgeschrieben. + Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen kommen jede Woche. Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken Verdiene Staking-Belohnungen Dein verbleibender Stakingbetrag ist zu niedrig, um den Einsatz aufzuheben. Du musst mehr Staken, um den Mindestbetrag zum Aufheben des Einsatzes zu erreichen. @@ -1258,6 +1262,8 @@ WalletConnect-Sitzung wurde getrennt Fehlercode: %s. Wenn das Problem weiterhin besteht, wende Dich bitte an unseren Support. Wir haben einen unbekannten Fehler festgestellt. + Fehlercode: 8 005. Wenn das Problem weiterhin besteht, wende Dich bitte an unseren Support. + Wir haben einen unbekannten Fehler festgestellt. Tangem unterstützt derzeit das erforderliches Netzwerk von %s nicht. Nicht unterstützte Netzwerke Tangem unterstützt ein erforderliches Netzwerk um %s. diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 5cf1bb5c9d..29f843c61b 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -518,7 +518,7 @@ NFTについて NFTアセット - アイテム + %d アイテム ウォレットに送信されたNFTがここに表示されます。 コレクションはまだありません @@ -687,6 +687,10 @@ 残高順 トークンを整理する グループ解除 + Tangemの通知は設定で有効にできます。 + 後で有効にする + 設定 + 通知を有効にする ギャラリーから選択 設定 カメラへのアクセスを許可していません。 @@ -1242,6 +1246,8 @@ WalletConnectセッションが接続解除されました エラーコード: %s 。問題が解決しない場合は、お気軽にサポートまでお問い合わせください。 不明なエラーが発生しました + エラーコード: 8 005。問題が解決しない場合は、お気軽にサポートまでお問い合わせください。 + 不明なエラーが発生しました Tangemは現在%sで必要なネットワークをサポートしていません。 サポートされていないネットワーク Tangemは%sで必要なネットワークをサポートします。 diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index fd18d8974b..eeaac91b42 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -701,6 +701,11 @@ By balance Organize tokens Ungroup + More info + You can enable Notifications for Tangem in Settings. + Enable Later + Settings + Enable Notifications Select from the gallery Settings You have not given access to your camera diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/Description.kt b/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt similarity index 90% rename from features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/Description.kt rename to core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt index 76a4172080..25e496e785 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/Description.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/items/DecriptionItem.kt @@ -1,4 +1,4 @@ -package com.tangem.features.markets.details.impl.ui.components +package com.tangem.core.ui.components.items import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column @@ -7,9 +7,11 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R import com.tangem.core.ui.components.TextShimmer import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference @@ -18,15 +20,15 @@ import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.utils.PreviewShimmerContainer -import com.tangem.features.markets.impl.R import com.tangem.utils.StringsSigns @Composable -internal fun Description( +fun DescriptionItem( description: TextReference, hasFullDescription: Boolean, onReadMoreClick: () -> Unit, modifier: Modifier = Modifier, + textStyle: TextStyle = TangemTheme.typography.body2, ) { if (hasFullDescription) { val text = buildAnnotatedString { @@ -51,20 +53,20 @@ internal fun Description( onClick = onReadMoreClick, ), text = text, - style = TangemTheme.typography.body2, + style = textStyle, ) } else { Text( modifier = modifier, text = description.resolveReference(), - style = TangemTheme.typography.body2, + style = textStyle, color = TangemTheme.colors.text.secondary, ) } } @Composable -internal fun DescriptionPlaceholder(modifier: Modifier = Modifier) { +public fun DescriptionPlaceholder(modifier: Modifier = Modifier) { Column( modifier = modifier, ) { @@ -90,7 +92,7 @@ internal fun DescriptionPlaceholder(modifier: Modifier = Modifier) { @Composable private fun ContentPreview() { TangemThemePreview { - Description( + DescriptionItem( description = stringReference( "XRP (XRP) is a cryptocurrency launched in January 2009, where the first " + "genesis block was mined on 9th January 2009", diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt index a0907e1111..de9781bffc 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt @@ -46,18 +46,23 @@ class UserTokensSaver constructor( push(userWalletId, enrichedUserTokensResponse, false) } - suspend fun push(userWalletId: UserWalletId, response: UserTokensResponse, useEnricher: Boolean = true) = - withContext(dispatchers.io) { - val enrichedUserTokensResponse = if (useEnricher) { - userTokensResponseAddressesEnricher( - userWalletId = userWalletId, - response = response, - ) - } else { - response - } - safeApiCall({ tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedUserTokensResponse).bind() }) { - Timber.e(it, "Unable to push user tokens for: ${userWalletId.stringValue}") - } + suspend fun push( + userWalletId: UserWalletId, + response: UserTokensResponse, + useEnricher: Boolean = true, + onFailSend: () -> Unit = {}, + ) = withContext(dispatchers.io) { + val enrichedUserTokensResponse = if (useEnricher) { + userTokensResponseAddressesEnricher( + userWalletId = userWalletId, + response = response, + ) + } else { + response } + safeApiCall({ tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedUserTokensResponse).bind() }) { + Timber.e(it, "Unable to push user tokens for: ${userWalletId.stringValue}") + onFailSend() + } + } } \ No newline at end of file diff --git a/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt b/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt index f72c44f771..8a7e2e922a 100644 --- a/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt +++ b/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt @@ -110,66 +110,42 @@ class UserTokensSaverTest { } @Test - fun `GIVEN user wallet id and response WHEN push THEN should push enriched response`() = runTest { - // GIVEN - val userWalletId = UserWalletId("1234567890abcdef") - val response = UserTokensResponse( - version = 0, - group = UserTokensResponse.GroupType.NETWORK, - sort = UserTokensResponse.SortType.BALANCE, - tokens = emptyList(), - ) - val enrichedResponse = UserTokensResponse( - version = 0, - group = UserTokensResponse.GroupType.NETWORK, - sort = UserTokensResponse.SortType.BALANCE, - tokens = emptyList(), - ) - coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse - coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns ApiResponse.Success(Unit) + fun `GIVEN user wallet id and response WHEN push AND api call fails THEN should log error and call onFailSend`() = + runTest { + // GIVEN + val userWalletId = UserWalletId("1234567890abcdef") + val response = UserTokensResponse( + version = 0, + group = UserTokensResponse.GroupType.NETWORK, + sort = UserTokensResponse.SortType.BALANCE, + tokens = emptyList(), + ) + val enrichedResponse = UserTokensResponse( + version = 0, + group = UserTokensResponse.GroupType.NETWORK, + sort = UserTokensResponse.SortType.BALANCE, + tokens = emptyList(), + ) + val error = ApiResponseError.UnknownException(Exception("API Error")) + var onFailSendCalled = false + coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse + coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns + ApiResponse.Error(error) as ApiResponse - // WHEN - userTokensSaver.push(userWalletId, response) + // WHEN + userTokensSaver.push( + userWalletId = userWalletId, + response = response, + onFailSend = { onFailSendCalled = true }, + ) - // THEN - coVerify { - tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse) + // THEN + coVerify { + tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse) + } + coVerify(exactly = 0) { + dataStore.updateData(any()) + } + assert(onFailSendCalled) { "onFailSend callback should be called when API call fails" } } - coVerify(exactly = 0) { - dataStore.updateData(any()) - } - } - - @Test - fun `GIVEN user wallet id and response WHEN push AND api call fails THEN should log error`() = runTest { - // GIVEN - val userWalletId = UserWalletId("1234567890abcdef") - val response = UserTokensResponse( - version = 0, - group = UserTokensResponse.GroupType.NETWORK, - sort = UserTokensResponse.SortType.BALANCE, - tokens = emptyList(), - ) - val enrichedResponse = UserTokensResponse( - version = 0, - group = UserTokensResponse.GroupType.NETWORK, - sort = UserTokensResponse.SortType.BALANCE, - tokens = emptyList(), - ) - val error = ApiResponseError.UnknownException(Exception("API Error")) - coEvery { userTokensResponseAddressesEnricher(userWalletId, response) } returns enrichedResponse - coEvery { tangemTechApi.saveUserTokens(any(), any()) } returns - ApiResponse.Error(error) as ApiResponse - - // WHEN - userTokensSaver.push(userWalletId, response) - - // THEN - coVerify { - tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse) - } - coVerify(exactly = 0) { - dataStore.updateData(any()) - } - } } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 61c55bc67f..9fb386abac 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -548,6 +548,16 @@ internal class DefaultCurrenciesRepository( return blockchain?.isNetworkFeeZero() ?: false } + override suspend fun syncTokens(userWalletId: UserWalletId) { + val savedCurrencies = requireNotNull( + value = getSavedUserTokensResponseSync(key = userWalletId), + lazyMessage = { "Saved tokens empty. Can not perform add currencies action" }, + ) + userTokensSaver.push(userWalletId, savedCurrencies, onFailSend = { + throw IllegalStateException("Unable to push tokens") + },) + } + private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow> { return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens -> responseCurrenciesFactory.createCurrencies( diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt index 3c4e5fa0ac..66d01cef74 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt @@ -238,6 +238,10 @@ internal class DefaultWalletsRepository( } } + override fun notificationsEnabledStatus(userWalletId: UserWalletId): Flow = appPreferencesStore + .getObjectMap(PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY) + .map { it[userWalletId.stringValue] == true } + override suspend fun isNotificationsEnabled(userWalletId: UserWalletId): Boolean = appPreferencesStore.getObjectMap(PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY) .map { it[userWalletId.stringValue] } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt index 97cc2cdd48..14c39c9320 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/CurrenciesRepository.kt @@ -8,6 +8,7 @@ import com.tangem.domain.tokens.model.FeePaidCurrency import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import kotlinx.coroutines.flow.Flow +import kotlin.jvm.Throws /** * Repository for everything related to the tokens of user wallet @@ -254,4 +255,15 @@ interface CurrenciesRepository { ): Flow>> fun isNetworkFeeZero(userWalletId: UserWalletId, network: Network): Boolean + + /** + * Synchronizes local tokens with remote data for a specific user wallet. + * This method ensures that the local token list matches the remote state by fetching + * the token data from the local cache and push it to backend. + * + * @param userWalletId The unique identifier of the user wallet to sync tokens for. + * @throws Exception if the sync request to the backend fails + */ + @Throws + suspend fun syncTokens(userWalletId: UserWalletId) } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt index 0d4fc5f4ff..f8f52b1471 100644 --- a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockCurrenciesRepository.kt @@ -163,4 +163,8 @@ internal class MockCurrenciesRepository( override fun isNetworkFeeZero(userWalletId: UserWalletId, network: Network): Boolean { return false } + + override suspend fun syncTokens(userWalletId: UserWalletId) { + return Unit + } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt index aec006e796..2467b17947 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt @@ -41,6 +41,8 @@ interface WalletsRepository { suspend fun disableNFT(userWalletId: UserWalletId) + fun notificationsEnabledStatus(userWalletId: UserWalletId): Flow + suspend fun isNotificationsEnabled(userWalletId: UserWalletId): Boolean suspend fun setNotificationsEnabled(userWalletId: UserWalletId, isEnabled: Boolean) diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNotificationsEnabledUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNotificationsEnabledUseCase.kt new file mode 100644 index 0000000000..22ca6bb1b5 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNotificationsEnabledUseCase.kt @@ -0,0 +1,13 @@ +package com.tangem.domain.wallets.usecase + +import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.domain.wallets.repository.WalletsRepository +import kotlinx.coroutines.flow.Flow + +class GetWalletNotificationsEnabledUseCase( + private val walletsRepository: WalletsRepository, +) { + + operator fun invoke(userWalletId: UserWalletId): Flow = walletsRepository + .notificationsEnabledStatus(userWalletId) +} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SetNotificationsEnabledUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SetNotificationsEnabledUseCase.kt index 574bca9f93..7931792d2e 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SetNotificationsEnabledUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SetNotificationsEnabledUseCase.kt @@ -1,11 +1,13 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either +import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.repository.WalletsRepository class SetNotificationsEnabledUseCase( private val walletsRepository: WalletsRepository, + private val currenciesRepository: CurrenciesRepository, ) { suspend operator fun invoke(userWalletId: UserWalletId, isEnabled: Boolean): Either = @@ -14,5 +16,11 @@ class SetNotificationsEnabledUseCase( userWalletId = userWalletId, isEnabled = isEnabled, ) + currenciesRepository.syncTokens(userWalletId) + }.onLeft { + walletsRepository.setNotificationsEnabled( + userWalletId = userWalletId, + isEnabled = !isEnabled, + ) } } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt index b796c0f38a..c2fb267ffe 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt @@ -10,6 +10,8 @@ import androidx.compose.ui.Modifier import com.tangem.core.ui.res.TangemTheme import com.tangem.features.markets.details.impl.ui.state.MarketsTokenDetailsUM import com.tangem.core.ui.components.UnableToLoadData +import com.tangem.core.ui.components.items.DescriptionItem +import com.tangem.core.ui.components.items.DescriptionPlaceholder internal fun LazyListScope.tokenMarketDetailsBody( state: MarketsTokenDetailsUM.Body, @@ -69,7 +71,7 @@ private fun LazyListScope.error(state: MarketsTokenDetailsUM.Body.Error) { private fun LazyListScope.description(description: MarketsTokenDetailsUM.Description) { item("description") { - Description( + DescriptionItem( modifier = Modifier.blockPaddings(), description = description.shortDescription, hasFullDescription = description.fullDescription != null, diff --git a/features/wallet-settings/impl/build.gradle.kts b/features/wallet-settings/impl/build.gradle.kts index 9b694a9073..6f7c482a7f 100644 --- a/features/wallet-settings/impl/build.gradle.kts +++ b/features/wallet-settings/impl/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { implementation(projects.domain.wallets.models) implementation(projects.domain.demo) implementation(projects.domain.nft) + implementation(projects.domain.notifications.toggles) /* AndroidX */ implementation(deps.androidx.fragment.ktx) diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt index 40383c55b5..a78e85d068 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt @@ -31,6 +31,10 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent { onLinkMoreCardsClick = {}, onReferralClick = {}, isManageTokensAvailable = true, + isNotificationsEnabled = true, + isNotificationsFeatureEnabled = true, + onCheckedNotificationsChanged = {}, + onNotificationsDescriptionClick = {}, ), ) diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt index 3e2eb34bad..4eabd5a71b 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt @@ -30,4 +30,11 @@ internal sealed class WalletSettingsItemUM { val isEnabled: Boolean, val onClick: () -> Unit, ) : WalletSettingsItemUM() + + data class DescriptionWithMore( + override val id: String, + val text: TextReference, + val more: TextReference, + val onClick: () -> Unit, + ) : WalletSettingsItemUM() } \ No newline at end of file diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt index 7e895820be..e7925383d4 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt @@ -22,10 +22,9 @@ import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.nft.DisableWalletNFTUseCase import com.tangem.domain.nft.EnableWalletNFTUseCase import com.tangem.domain.nft.GetWalletNFTEnabledUseCase +import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles import com.tangem.domain.wallets.models.UserWallet -import com.tangem.domain.wallets.usecase.DeleteWalletUseCase -import com.tangem.domain.wallets.usecase.GetUserWalletUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase +import com.tangem.domain.wallets.usecase.* import com.tangem.feature.walletsettings.analytics.Settings import com.tangem.feature.walletsettings.component.WalletSettingsComponent import com.tangem.feature.walletsettings.entity.DialogConfig @@ -60,6 +59,9 @@ internal class WalletSettingsModel @Inject constructor( private val getWalletNFTEnabledUseCase: GetWalletNFTEnabledUseCase, private val enableWalletNFTUseCase: EnableWalletNFTUseCase, private val disableWalletNFTUseCase: DisableWalletNFTUseCase, + private val notificationsToggles: NotificationsFeatureToggles, + private val getWalletNotificationsEnabledUseCase: GetWalletNotificationsEnabledUseCase, + private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase, ) : Model() { val params: WalletSettingsComponent.Params = paramsContainer.require() @@ -73,23 +75,27 @@ internal class WalletSettingsModel @Inject constructor( ) init { - getWalletUseCase.invokeFlow(params.userWalletId) - .distinctUntilChanged() - .combine(getWalletNFTEnabledUseCase.invoke(params.userWalletId)) { maybeWallet, nftEnabled -> - val wallet = maybeWallet.getOrNull() ?: return@combine - val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase() - state.update { value -> - value.copy( - items = buildItems( - userWallet = wallet, - dialogNavigation = dialogNavigation, - isRenameWalletAvailable = isRenameWalletAvailable, - isNFTFeatureEnabled = nftFeatureToggles.isNFTEnabled, - isNFTEnabled = nftEnabled, - ), - ) - } + combine( + getWalletUseCase.invokeFlow(params.userWalletId).distinctUntilChanged(), + getWalletNFTEnabledUseCase.invoke(params.userWalletId), + getWalletNotificationsEnabledUseCase(params.userWalletId), + ) { maybeWallet, nftEnabled, notificationsEnabled -> + val wallet = maybeWallet.getOrNull() ?: return@combine + val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase() + state.update { value -> + value.copy( + items = buildItems( + userWallet = wallet, + dialogNavigation = dialogNavigation, + isRenameWalletAvailable = isRenameWalletAvailable, + isNFTFeatureEnabled = nftFeatureToggles.isNFTEnabled, + isNFTEnabled = nftEnabled, + isNotificationsEnabled = notificationsEnabled, + isNotificationsFeatureEnabled = notificationsToggles.isNotificationsEnabled, + ), + ) } + } .launchIn(modelScope) } @@ -99,6 +105,8 @@ internal class WalletSettingsModel @Inject constructor( isRenameWalletAvailable: Boolean, isNFTFeatureEnabled: Boolean, isNFTEnabled: Boolean, + isNotificationsFeatureEnabled: Boolean, + isNotificationsEnabled: Boolean, ): PersistentList = itemsBuilder.buildItems( userWalletId = userWallet.walletId, userWalletName = userWallet.name, @@ -129,6 +137,10 @@ internal class WalletSettingsModel @Inject constructor( onLinkMoreCardsClick(scanResponse = userWallet.scanResponse) }, onReferralClick = { onReferralClick(userWallet) }, + isNotificationsEnabled = isNotificationsEnabled, + isNotificationsFeatureEnabled = isNotificationsFeatureEnabled, + onCheckedNotificationsChanged = ::onCheckedNotificationsChange, + onNotificationsDescriptionClick = ::onNotificationsDescriptionClick, ) private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation) { @@ -180,6 +192,17 @@ internal class WalletSettingsModel @Inject constructor( } } + private fun onCheckedNotificationsChange(isChecked: Boolean) { + // TODO [REDACTED_JIRA] + modelScope.launch { + setNotificationsEnabledUseCase(params.userWalletId, isChecked) + } + } + + private fun onNotificationsDescriptionClick() { + // TODO [REDACTED_JIRA] + } + private fun onReferralClick(userWallet: UserWallet) { if (isDemoCardUseCase(userWallet.cardId)) { messageSender.send( diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt index 165f5c1ca7..84eae80778 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt @@ -13,11 +13,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.TangemSwitch import com.tangem.core.ui.components.appbar.TangemTopAppBar import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.BlockItem +import com.tangem.core.ui.components.items.DescriptionItem import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme @@ -98,6 +101,12 @@ private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) { modifier = itemModifier, model = item, ) + is WalletSettingsItemUM.DescriptionWithMore -> DescriptionWithMoreBlock( + modifier = itemModifier, + model = item, + yOffset = DESCRIPTION_OFFSET, + onDescriptionClick = item.onClick, + ) } } } @@ -195,6 +204,26 @@ private fun SwitchBlock(model: WalletSettingsItemUM.WithSwitch, modifier: Modifi } } +@Composable +private fun DescriptionWithMoreBlock( + model: WalletSettingsItemUM.DescriptionWithMore, + onDescriptionClick: () -> Unit, + modifier: Modifier = Modifier, + yOffset: Dp = 0.dp, +) { + DescriptionItem( + modifier = modifier + .offset(y = yOffset) + .padding(horizontal = 12.dp), + description = model.text, + hasFullDescription = true, + textStyle = TangemTheme.typography.caption2, + onReadMoreClick = onDescriptionClick, + ) +} + +private val DESCRIPTION_OFFSET = -8.dp + // region Preview @Composable @Preview(showBackground = true, widthDp = 360) diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt index 39670ae4c1..17a2b47350 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt @@ -34,6 +34,10 @@ internal class ItemsBuilder @Inject constructor( isNFTFeatureEnabled: Boolean, isNFTEnabled: Boolean, onCheckedNFTChange: (Boolean) -> Unit, + isNotificationsFeatureEnabled: Boolean, + isNotificationsEnabled: Boolean, + onCheckedNotificationsChanged: (Boolean) -> Unit, + onNotificationsDescriptionClick: () -> Unit, forgetWallet: () -> Unit, renameWallet: () -> Unit, onLinkMoreCardsClick: () -> Unit, @@ -57,6 +61,22 @@ internal class ItemsBuilder @Inject constructor( onReferralClick = onReferralClick, ), ) + .run { + if (isNotificationsFeatureEnabled) { + add( + buildNotificationsSwitchItem( + isNotificationsEnabled, + onCheckedNotificationsChanged, + ), + ).add( + buildNotificationsDescriptionItem( + onDescriptionClick = onNotificationsDescriptionClick, + ), + ) + } else { + this + } + } .add(buildForgetItem(forgetWallet)) private fun buildNameItem(walletName: String, isRenameWalletAvailable: Boolean, renameWallet: () -> Unit) = @@ -76,6 +96,22 @@ internal class ItemsBuilder @Inject constructor( onCheckedChange = onCheckedNFTChange, ) + private fun buildNotificationsSwitchItem(isNFTEnabled: Boolean, onCheckedNFTChange: (Boolean) -> Unit) = + WalletSettingsItemUM.WithSwitch( + id = "notifications", + title = resourceReference(id = R.string.wallet_settings_push_notifications_title), + isChecked = isNFTEnabled, + onCheckedChange = onCheckedNFTChange, + ) + + private fun buildNotificationsDescriptionItem(onDescriptionClick: () -> Unit) = + WalletSettingsItemUM.DescriptionWithMore( + id = "notifications_description", + text = resourceReference(id = R.string.wallet_settings_push_notifications_description), + more = resourceReference(id = R.string.push_notifications_more_info), + onClick = onDescriptionClick, + ) + @Suppress("LongParameterList") private fun buildCardItem( userWalletId: UserWalletId,