Updated on 2026-08-14
This commit is contained in:
parent
1485eddbc7
commit
8f9b356307
27 changed files with 326 additions and 115 deletions
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <reified T> provideTangemTechApiInternal(
|
||||
moshi: Moshi,
|
||||
context: Context,
|
||||
appVersionProvider: AppVersionProvider,
|
||||
appInfoProvider: AppInfoProvider,
|
||||
baseUrl: String,
|
||||
analyticsErrorHandler: AnalyticsErrorHandler,
|
||||
timeouts: Timeouts = Timeouts(),
|
||||
requestHeaders: List<RequestHeader> = listOf(AppVersionPlatformHeaders(appVersionProvider)),
|
||||
requestHeaders: List<RequestHeader> = listOf(AppVersionPlatformHeaders(appVersionProvider, appInfoProvider)),
|
||||
): T {
|
||||
val client = OkHttpClient.Builder()
|
||||
.applyTimeoutAnnotations()
|
||||
|
|
|
|||
|
|
@ -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<String, ProviderSuspend<String>>)
|
|||
"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() },
|
||||
|
|
|
|||
|
|
@ -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<AppVersionProvider>()
|
|||
private val expressAuthProvider = mockk<ExpressAuthProvider>()
|
||||
private val stakeKitAuthProvider = mockk<StakeKitAuthProvider>()
|
||||
private val appAuthProvider = mockk<AuthProvider>()
|
||||
private val appInfoProvider = mockk<AppInfoProvider>()
|
||||
|
||||
// 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()
|
||||
|
|
|
|||
|
|
@ -669,7 +669,7 @@
|
|||
<string name="onboarding_wallet_info_title_second">Identische Karten oder Ring</string>
|
||||
<string name="onboarding_wallet_info_title_third">Zugangscode</string>
|
||||
<string name="onramp_avaiable_with_payment_methods">Verfügbar mit %s</string>
|
||||
<string name="onramp_choose_provider_title_hint">Der Kauf von Kryptowährungen bei Tangem wird von Drittanbietern zu deren Bedingungen durchgeführt.</string>
|
||||
<string name="onramp_choose_provider_title_hint">Anbieter erleichtern Transaktionen</string>
|
||||
<string name="onramp_country_search">Suche nach Land</string>
|
||||
<string name="onramp_country_unavailable">Nicht verfügbar</string>
|
||||
<string name="onramp_currency_other">Andere Währungen</string>
|
||||
|
|
@ -696,6 +696,10 @@
|
|||
<string name="organize_tokens_sort_by_balance">Nach Guthaben</string>
|
||||
<string name="organize_tokens_title">Token organisieren</string>
|
||||
<string name="organize_tokens_ungroup">Gruppe löschen</string>
|
||||
<string name="push_notifications_permission_alert_description">Du kannst Benachrichtigungen für Tangem in den Einstellungen aktivieren.</string>
|
||||
<string name="push_notifications_permission_alert_negative_button">Später aktivieren</string>
|
||||
<string name="push_notifications_permission_alert_positive_button">Einstellungen</string>
|
||||
<string name="push_notifications_permission_alert_title">Benachrichtigungen aktivieren</string>
|
||||
<string name="qr_scanner_camera_denied_gallery_button">Wählen aus der Galerie aus</string>
|
||||
<string name="qr_scanner_camera_denied_settings_button">Einstellungen</string>
|
||||
<string name="qr_scanner_camera_denied_text">Du hast keinen Zugriff auf deine Kamera gewährt</string>
|
||||
|
|
@ -867,7 +871,7 @@
|
|||
<string name="staking_details_auto_claiming_rewards_daily_text">Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an.</string>
|
||||
<string name="staking_details_available">Verfügbar</string>
|
||||
<string name="staking_details_average_reward_rate">Durchschnittliche Belohnungsquote</string>
|
||||
<string name="staking_details_banner_text">Was ist Staking?</string>
|
||||
<string name="staking_details_banner_text">Wie funktioniert Staking?</string>
|
||||
<string name="staking_details_estimated_profit">%s geschätzter Profit</string>
|
||||
<string name="staking_details_market_rating">Marktposition</string>
|
||||
<string name="staking_details_metrics_block_header">Metriken</string>
|
||||
|
|
@ -899,10 +903,10 @@
|
|||
<string name="staking_notification_earn_rewards_text_daily">Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken</string>
|
||||
<string name="staking_notification_earn_rewards_text_hourly">Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken</string>
|
||||
<string name="staking_notification_earn_rewards_text_monthly">Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_day">Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jeden tag.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_hour">Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jede Stunde.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_month">Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jeden Monat.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_week">Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jede Woche.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_day">Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen kommen täglich an.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_hour">Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen werden stündlich gutgeschrieben.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_month">Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen werden Dir jeden Monat gutgeschrieben.</string>
|
||||
<string name="staking_notification_earn_rewards_text_period_week">Durch Staking kannst Du %1$s erhalten. Deine Staking-Belohnungen kommen jede Woche.</string>
|
||||
<string name="staking_notification_earn_rewards_text_weekly">Tangem ermöglicht es Benutzern, ihre Kryptowährungen zu Staken</string>
|
||||
<string name="staking_notification_earn_rewards_title">Verdiene Staking-Belohnungen</string>
|
||||
<string name="staking_notification_low_staked_balance_text">Dein verbleibender Stakingbetrag ist zu niedrig, um den Einsatz aufzuheben. Du musst mehr Staken, um den Mindestbetrag zum Aufheben des Einsatzes zu erreichen.</string>
|
||||
|
|
@ -1258,6 +1262,8 @@
|
|||
<string name="wc_alert_session_disconnected_title">WalletConnect-Sitzung wurde getrennt</string>
|
||||
<string name="wc_alert_unknown_error_description">Fehlercode: %s. Wenn das Problem weiterhin besteht, wende Dich bitte an unseren Support.</string>
|
||||
<string name="wc_alert_unknown_error_title">Wir haben einen unbekannten Fehler festgestellt.</string>
|
||||
<string name="wc_alert_unsupported_method_description">Fehlercode: 8 005. Wenn das Problem weiterhin besteht, wende Dich bitte an unseren Support.</string>
|
||||
<string name="wc_alert_unsupported_method_title">Wir haben einen unbekannten Fehler festgestellt.</string>
|
||||
<string name="wc_alert_unsupported_networks_description">Tangem unterstützt derzeit das erforderliches Netzwerk von %s nicht.</string>
|
||||
<string name="wc_alert_unsupported_networks_title">Nicht unterstützte Netzwerke</string>
|
||||
<string name="wc_alert_verified_domain_description">Tangem unterstützt ein erforderliches Netzwerk um %s.</string>
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@
|
|||
<string name="nft_about_title">NFTについて</string>
|
||||
<string name="nft_asset">NFTアセット</string>
|
||||
<plurals name="nft_collections_count">
|
||||
<item quantity="other">アイテム</item>
|
||||
<item quantity="other">%d アイテム</item>
|
||||
</plurals>
|
||||
<string name="nft_collections_empty_description">ウォレットに送信されたNFTがここに表示されます。</string>
|
||||
<string name="nft_collections_empty_title">コレクションはまだありません</string>
|
||||
|
|
@ -687,6 +687,10 @@
|
|||
<string name="organize_tokens_sort_by_balance">残高順</string>
|
||||
<string name="organize_tokens_title">トークンを整理する</string>
|
||||
<string name="organize_tokens_ungroup">グループ解除</string>
|
||||
<string name="push_notifications_permission_alert_description">Tangemの通知は設定で有効にできます。</string>
|
||||
<string name="push_notifications_permission_alert_negative_button">後で有効にする</string>
|
||||
<string name="push_notifications_permission_alert_positive_button">設定</string>
|
||||
<string name="push_notifications_permission_alert_title">通知を有効にする</string>
|
||||
<string name="qr_scanner_camera_denied_gallery_button">ギャラリーから選択</string>
|
||||
<string name="qr_scanner_camera_denied_settings_button">設定</string>
|
||||
<string name="qr_scanner_camera_denied_text">カメラへのアクセスを許可していません。</string>
|
||||
|
|
@ -1242,6 +1246,8 @@
|
|||
<string name="wc_alert_session_disconnected_title">WalletConnectセッションが接続解除されました</string>
|
||||
<string name="wc_alert_unknown_error_description">エラーコード: %s 。問題が解決しない場合は、お気軽にサポートまでお問い合わせください。</string>
|
||||
<string name="wc_alert_unknown_error_title">不明なエラーが発生しました</string>
|
||||
<string name="wc_alert_unsupported_method_description">エラーコード: 8 005。問題が解決しない場合は、お気軽にサポートまでお問い合わせください。</string>
|
||||
<string name="wc_alert_unsupported_method_title">不明なエラーが発生しました</string>
|
||||
<string name="wc_alert_unsupported_networks_description">Tangemは現在%sで必要なネットワークをサポートしていません。</string>
|
||||
<string name="wc_alert_unsupported_networks_title">サポートされていないネットワーク</string>
|
||||
<string name="wc_alert_verified_domain_description">Tangemは%sで必要なネットワークをサポートします。</string>
|
||||
|
|
|
|||
|
|
@ -701,6 +701,11 @@
|
|||
<string name="organize_tokens_sort_by_balance">By balance</string>
|
||||
<string name="organize_tokens_title">Organize tokens</string>
|
||||
<string name="organize_tokens_ungroup">Ungroup</string>
|
||||
<string name="push_notifications_more_info">More info</string>
|
||||
<string name="push_notifications_permission_alert_description">You can enable Notifications for Tangem in Settings.</string>
|
||||
<string name="push_notifications_permission_alert_negative_button">Enable Later</string>
|
||||
<string name="push_notifications_permission_alert_positive_button">Settings</string>
|
||||
<string name="push_notifications_permission_alert_title">Enable Notifications</string>
|
||||
<string name="qr_scanner_camera_denied_gallery_button">Select from the gallery</string>
|
||||
<string name="qr_scanner_camera_denied_settings_button">Settings</string>
|
||||
<string name="qr_scanner_camera_denied_text">You have not given access to your camera</string>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Unit>
|
||||
|
||||
// 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<Unit>
|
||||
|
||||
// WHEN
|
||||
userTokensSaver.push(userWalletId, response)
|
||||
|
||||
// THEN
|
||||
coVerify {
|
||||
tangemTechApi.saveUserTokens(userWalletId.stringValue, enrichedResponse)
|
||||
}
|
||||
coVerify(exactly = 0) {
|
||||
dataStore.updateData(any())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<List<CryptoCurrency>> {
|
||||
return getSavedUserTokensResponse(userWallet.walletId).map { storedTokens ->
|
||||
responseCurrenciesFactory.createCurrencies(
|
||||
|
|
|
|||
|
|
@ -238,6 +238,10 @@ internal class DefaultWalletsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override fun notificationsEnabledStatus(userWalletId: UserWalletId): Flow<Boolean> = appPreferencesStore
|
||||
.getObjectMap<Boolean>(PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY)
|
||||
.map { it[userWalletId.stringValue] == true }
|
||||
|
||||
override suspend fun isNotificationsEnabled(userWalletId: UserWalletId): Boolean =
|
||||
appPreferencesStore.getObjectMap<Boolean>(PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY)
|
||||
.map { it[userWalletId.stringValue] }
|
||||
|
|
|
|||
|
|
@ -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<Map<UserWallet, List<CryptoCurrency>>>
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,8 @@ interface WalletsRepository {
|
|||
|
||||
suspend fun disableNFT(userWalletId: UserWalletId)
|
||||
|
||||
fun notificationsEnabledStatus(userWalletId: UserWalletId): Flow<Boolean>
|
||||
|
||||
suspend fun isNotificationsEnabled(userWalletId: UserWalletId): Boolean
|
||||
|
||||
suspend fun setNotificationsEnabled(userWalletId: UserWalletId, isEnabled: Boolean)
|
||||
|
|
|
|||
|
|
@ -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<Boolean> = walletsRepository
|
||||
.notificationsEnabledStatus(userWalletId)
|
||||
}
|
||||
|
|
@ -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<Throwable, Unit> =
|
||||
|
|
@ -14,5 +16,11 @@ class SetNotificationsEnabledUseCase(
|
|||
userWalletId = userWalletId,
|
||||
isEnabled = isEnabled,
|
||||
)
|
||||
currenciesRepository.syncTokens(userWalletId)
|
||||
}.onLeft {
|
||||
walletsRepository.setNotificationsEnabled(
|
||||
userWalletId = userWalletId,
|
||||
isEnabled = !isEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onLinkMoreCardsClick = {},
|
||||
onReferralClick = {},
|
||||
isManageTokensAvailable = true,
|
||||
isNotificationsEnabled = true,
|
||||
isNotificationsFeatureEnabled = true,
|
||||
onCheckedNotificationsChanged = {},
|
||||
onNotificationsDescriptionClick = {},
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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<WalletSettingsItemUM> = 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<DialogConfig>) {
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue