Updated on 2026-08-14
This commit is contained in:
parent
8106b36fd6
commit
1e0876eea6
45 changed files with 301 additions and 292 deletions
|
|
@ -80,6 +80,7 @@ dependencies {
|
||||||
implementation(projects.data.analytics)
|
implementation(projects.data.analytics)
|
||||||
implementation(projects.data.transaction)
|
implementation(projects.data.transaction)
|
||||||
implementation(projects.data.visa)
|
implementation(projects.data.visa)
|
||||||
|
implementation(projects.data.promo)
|
||||||
|
|
||||||
/** Features */
|
/** Features */
|
||||||
implementation(projects.features.onboarding)
|
implementation(projects.features.onboarding)
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ internal object TokensDomainModule {
|
||||||
marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
||||||
swapRepository: SwapRepository,
|
swapRepository: SwapRepository,
|
||||||
showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
|
showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
|
||||||
|
promoRepository: PromoRepository,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
): GetCurrencyWarningsUseCase {
|
): GetCurrencyWarningsUseCase {
|
||||||
return GetCurrencyWarningsUseCase(
|
return GetCurrencyWarningsUseCase(
|
||||||
|
|
@ -110,6 +111,7 @@ internal object TokensDomainModule {
|
||||||
marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
|
marketCryptoCurrencyRepository = marketCryptoCurrencyRepository,
|
||||||
swapRepository = swapRepository,
|
swapRepository = swapRepository,
|
||||||
showSwapPromoTokenUseCase = showSwapPromoTokenUseCase,
|
showSwapPromoTokenUseCase = showSwapPromoTokenUseCase,
|
||||||
|
promoRepository = promoRepository,
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion
|
|
||||||
|
|
||||||
import com.tangem.datasource.api.promotion.models.*
|
|
||||||
import retrofit2.http.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Promotion API
|
|
||||||
* @see <a href = "https://www.notion.so/tangem/Promotion-Program-API-0907159c3fdb4975aac761be632f44da">Documentation<a/>
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
interface PromotionApi {
|
|
||||||
|
|
||||||
@Headers("Cache-Control: max-age=3600")
|
|
||||||
@GET("promotion")
|
|
||||||
suspend fun getPromotionInfo(@Query("programName") name: String): PromotionInfoResponse
|
|
||||||
|
|
||||||
@POST("promotion/code/validate")
|
|
||||||
suspend fun validateCode(@Body request: CodeValidateRequestBody): CodeValidateResponse
|
|
||||||
|
|
||||||
@POST("promotion/code/award")
|
|
||||||
suspend fun requestAwardByCode(@Body request: CodeAwardRequestBody): CodeAwardResponse
|
|
||||||
|
|
||||||
@POST("promotion/validate")
|
|
||||||
suspend fun validate(@Body request: ValidateRequestBody): ValidateResponse
|
|
||||||
|
|
||||||
@POST("promotion/award")
|
|
||||||
suspend fun requestAward(@Body request: AwardRequestBody): AwardResponse
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
abstract class AbstractPromotionResponse {
|
|
||||||
|
|
||||||
abstract val error: Error?
|
|
||||||
|
|
||||||
fun isError(): Boolean = error != null
|
|
||||||
|
|
||||||
data class Error(
|
|
||||||
@Json(name = "code") val code: Int,
|
|
||||||
@Json(name = "message") val message: String,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class AwardRequestBody(
|
|
||||||
@Json(name = "walletId") val walletId: String,
|
|
||||||
@Json(name = "address") val address: String,
|
|
||||||
@Json(name = "programName") val programName: String,
|
|
||||||
)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class AwardResponse(
|
|
||||||
@Json(name = "status") val status: Boolean?,
|
|
||||||
@Json(name = "error") override val error: Error? = null,
|
|
||||||
) : AbstractPromotionResponse()
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class CodeAwardRequestBody(
|
|
||||||
@Json(name = "walletId") val walletId: String,
|
|
||||||
@Json(name = "address") val address: String,
|
|
||||||
@Json(name = "code") val code: String?,
|
|
||||||
)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class CodeAwardResponse(
|
|
||||||
@Json(name = "status") val status: Boolean?,
|
|
||||||
@Json(name = "error") override val error: Error? = null,
|
|
||||||
) : AbstractPromotionResponse()
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class CodeValidateRequestBody(
|
|
||||||
@Json(name = "walletId") val walletId: String,
|
|
||||||
@Json(name = "code") val code: String?,
|
|
||||||
)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class CodeValidateResponse(
|
|
||||||
@Json(name = "valid") val valid: Boolean?,
|
|
||||||
@Json(name = "error") override val error: Error? = null,
|
|
||||||
) : AbstractPromotionResponse()
|
|
||||||
|
|
@ -1,40 +1,23 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
package com.tangem.datasource.api.promotion.models
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
/**
|
@JsonClass(generateAdapter = true)
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class PromotionInfoResponse(
|
data class PromotionInfoResponse(
|
||||||
@Json(name = "newCard") val newCard: Data?,
|
|
||||||
@Json(name = "oldCard") val oldCard: Data?,
|
|
||||||
@Json(name = "awardPaymentToken") val awardPaymentToken: TokenData?,
|
|
||||||
@Json(name = "error") override val error: Error? = null,
|
|
||||||
) : AbstractPromotionResponse() {
|
|
||||||
|
|
||||||
data class Data(
|
|
||||||
@Json(name = "status") val status: Status,
|
|
||||||
@Json(name = "award") val award: Double,
|
|
||||||
)
|
|
||||||
|
|
||||||
enum class Status(val value: String) {
|
|
||||||
@Json(name = "pending")
|
|
||||||
PENDING("pending"),
|
|
||||||
|
|
||||||
@Json(name = "active")
|
|
||||||
ACTIVE("active"),
|
|
||||||
|
|
||||||
@Json(name = "finished")
|
|
||||||
FINISHED("finished"),
|
|
||||||
}
|
|
||||||
|
|
||||||
data class TokenData(
|
|
||||||
@Json(name = "id") val id: String,
|
|
||||||
@Json(name = "name") val name: String,
|
@Json(name = "name") val name: String,
|
||||||
@Json(name = "symbol") val symbol: String,
|
@Json(name = "all") val bannerState: BannerState?,
|
||||||
@Json(name = "active") val active: Boolean,
|
) {
|
||||||
@Json(name = "networkId") val networkId: String,
|
|
||||||
@Json(name = "contractAddress") val contractAddress: String,
|
@JsonClass(generateAdapter = true)
|
||||||
@Json(name = "decimalCount") val decimalCount: Int,
|
data class BannerState(
|
||||||
|
@Json(name = "timeline") val timeline: Timeline,
|
||||||
|
@Json(name = "status") val status: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class Timeline(
|
||||||
|
@Json(name = "start") val start: String,
|
||||||
|
@Json(name = "end") val end: String,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class ValidateRequestBody(
|
|
||||||
@Json(name = "walletId") val walletId: String,
|
|
||||||
@Json(name = "programName") val programName: String,
|
|
||||||
)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package com.tangem.datasource.api.promotion.models
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
data class ValidateResponse(
|
|
||||||
@Json(name = "valid") val valid: Boolean?,
|
|
||||||
@Json(name = "error") override val error: Error? = null,
|
|
||||||
) : AbstractPromotionResponse()
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.datasource.api.tangemTech
|
package com.tangem.datasource.api.tangemTech
|
||||||
|
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.datasource.api.promotion.models.PromotionInfoResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.*
|
import com.tangem.datasource.api.tangemTech.models.*
|
||||||
import retrofit2.http.*
|
import retrofit2.http.*
|
||||||
|
|
||||||
|
|
@ -71,4 +72,7 @@ interface TangemTechApi {
|
||||||
@Query("coinIds") coinIds: String,
|
@Query("coinIds") coinIds: String,
|
||||||
@Query("fields") fields: String = "price,priceChange24h,lastUpdatedAt",
|
@Query("fields") fields: String = "price,priceChange24h,lastUpdatedAt",
|
||||||
): ApiResponse<QuotesResponse>
|
): ApiResponse<QuotesResponse>
|
||||||
|
|
||||||
|
@GET("promotion")
|
||||||
|
suspend fun getPromotionInfo(@Query("programName") name: String): ApiResponse<PromotionInfoResponse>
|
||||||
}
|
}
|
||||||
|
|
@ -5,4 +5,4 @@ import javax.inject.Qualifier
|
||||||
@Qualifier
|
@Qualifier
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
annotation class PromotionOneInch
|
annotation class DevTangemApi
|
||||||
|
|
@ -5,12 +5,10 @@ import com.squareup.moshi.Moshi
|
||||||
import com.tangem.datasource.BuildConfig
|
import com.tangem.datasource.BuildConfig
|
||||||
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
|
import com.tangem.datasource.api.common.response.ApiResponseCallAdapterFactory
|
||||||
import com.tangem.datasource.api.express.TangemExpressApi
|
import com.tangem.datasource.api.express.TangemExpressApi
|
||||||
import com.tangem.datasource.api.promotion.PromotionApi
|
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.utils.RequestHeader.*
|
import com.tangem.datasource.utils.RequestHeader.*
|
||||||
import com.tangem.datasource.utils.addHeaders
|
import com.tangem.datasource.utils.addHeaders
|
||||||
import com.tangem.datasource.utils.addLoggers
|
import com.tangem.datasource.utils.addLoggers
|
||||||
import com.tangem.lib.auth.AuthProvider
|
|
||||||
import com.tangem.lib.auth.ExpressAuthProvider
|
import com.tangem.lib.auth.ExpressAuthProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
|
@ -20,7 +18,6 @@ import dagger.hilt.components.SingletonComponent
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
|
@ -75,31 +72,25 @@ class NetworkModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@DevTangemApi
|
||||||
@Singleton
|
@Singleton
|
||||||
@PromotionOneInch
|
fun provideTangemTechDevApi(@NetworkMoshi moshi: Moshi, @ApplicationContext context: Context): TangemTechApi {
|
||||||
fun providePromotionOneInchApi(
|
|
||||||
authProvider: AuthProvider,
|
|
||||||
@NetworkMoshi moshi: Moshi,
|
|
||||||
@ApplicationContext context: Context,
|
|
||||||
): PromotionApi {
|
|
||||||
val okClient = OkHttpClient.Builder()
|
|
||||||
.addHeaders(AuthenticationHeader(authProvider))
|
|
||||||
.addLoggers(context)
|
|
||||||
.callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
|
||||||
.connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
|
||||||
.readTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
|
||||||
.writeTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
|
||||||
.build()
|
|
||||||
return createBasePromotionRetrofit(okClient, moshi)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createBasePromotionRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): PromotionApi {
|
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||||
.baseUrl(PROD_TANGEM_TECH_BASE_URL)
|
.addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
|
||||||
.client(okHttpClient)
|
.baseUrl(DEV_TANGEM_TECH_BASE_URL)
|
||||||
|
.client(
|
||||||
|
OkHttpClient.Builder()
|
||||||
|
.addHeaders(
|
||||||
|
CacheControlHeader,
|
||||||
|
// TODO("refactor header init") get auth data after biometric auth to avoid race condition
|
||||||
|
// AuthenticationHeader(authProvider),
|
||||||
|
)
|
||||||
|
.addLoggers(context)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
.create(PromotionApi::class.java)
|
.create(TangemTechApi::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,13 @@ object PreferencesKeys {
|
||||||
|
|
||||||
val LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY by lazy { stringPreferencesKey(name = "lastSwappedCryptoCurrency") }
|
val LAST_SWAPPED_CRYPTOCURRENCY_ID_KEY by lazy { stringPreferencesKey(name = "lastSwappedCryptoCurrency") }
|
||||||
|
|
||||||
val IS_WALLET_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isWalletSwapPromoShown") }
|
val IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY by lazy {
|
||||||
|
booleanPreferencesKey(name = "isWalletSwapPromoChangellyShown")
|
||||||
|
}
|
||||||
|
|
||||||
val IS_TOKEN_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isTokenSwapPromoShown") }
|
val IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY by lazy {
|
||||||
|
booleanPreferencesKey(name = "isTokenSwapPromoChangellyShown")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,8 @@
|
||||||
<string name="main_promotion_credited">1INCH токены будут зачислены на адрес вашего кошелька в сети %s в течение 48 часов</string>
|
<string name="main_promotion_credited">1INCH токены будут зачислены на адрес вашего кошелька в сети %s в течение 48 часов</string>
|
||||||
<string name="main_scan_card_warning_view_subtitle">Чтобы получить доступ ко всем сетям, вам необходимо отсканировать карту</string>
|
<string name="main_scan_card_warning_view_subtitle">Чтобы получить доступ ко всем сетям, вам необходимо отсканировать карту</string>
|
||||||
<string name="main_scan_card_warning_view_title">Отсканируйте карту</string>
|
<string name="main_scan_card_warning_view_title">Отсканируйте карту</string>
|
||||||
<string name="main_swap_promotion_message">Обменивайте свои цифровые активы между различными сетями</string>
|
<string name="main_swap_changelly_promotion_message">Обменивайте свои токены с %1$s комиссии провайдера через Changelly с %2$s по %3$s февраля.</string>
|
||||||
<string name="main_swap_promotion_title">Кроссчейн-своп теперь доступен</string>
|
<string name="main_swap_changelly_promotion_title">Обмен с Changelly, %s комиссии</string>
|
||||||
<string name="main_tokens">Токены</string>
|
<string name="main_tokens">Токены</string>
|
||||||
<string name="manage_tokens_add">Добавить</string>
|
<string name="manage_tokens_add">Добавить</string>
|
||||||
<string name="manage_tokens_edit">Изменить</string>
|
<string name="manage_tokens_edit">Изменить</string>
|
||||||
|
|
@ -575,9 +575,9 @@
|
||||||
<string name="token_details_unable_hide_alert_message">Токен %1$s является основной валютой в сети %2$s и не может быть скрыт до тех пор, пока у вас в списке есть другие токены этой сети.</string>
|
<string name="token_details_unable_hide_alert_message">Токен %1$s является основной валютой в сети %2$s и не может быть скрыт до тех пор, пока у вас в списке есть другие токены этой сети.</string>
|
||||||
<string name="token_details_unable_hide_alert_title">Невозможно скрыть %s</string>
|
<string name="token_details_unable_hide_alert_title">Невозможно скрыть %s</string>
|
||||||
<string name="token_item_no_rate">Нет цены</string>
|
<string name="token_item_no_rate">Нет цены</string>
|
||||||
|
<string name="token_swap_changelly_promotion_message">Обменивайте этот токен на другие с %1$s комиссии за обслуживание с %2$s по %3$s февраля.</string>
|
||||||
|
<string name="token_swap_changelly_promotion_title">Обмен с Changelly, %s комиссии</string>
|
||||||
<string name="token_swap_promotion_button">Обменять</string>
|
<string name="token_swap_promotion_button">Обменять</string>
|
||||||
<string name="token_swap_promotion_message">Обменяйте этот токен на другие активы в вашем портфеле</string>
|
|
||||||
<string name="token_swap_promotion_title">Представляем кроссчейн-своп</string>
|
|
||||||
<string name="transaction_history_contract_address">контракт: %s</string>
|
<string name="transaction_history_contract_address">контракт: %s</string>
|
||||||
<string name="transaction_history_empty_transactions">У вас еще нет транзакций</string>
|
<string name="transaction_history_empty_transactions">У вас еще нет транзакций</string>
|
||||||
<string name="transaction_history_error_failed_to_load">Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.</string>
|
<string name="transaction_history_error_failed_to_load">Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.</string>
|
||||||
|
|
|
||||||
|
|
@ -273,8 +273,8 @@
|
||||||
<string name="main_promotion_credited">1INCH tokens will be credited to your %s wallet address within 48 hours</string>
|
<string name="main_promotion_credited">1INCH tokens will be credited to your %s wallet address within 48 hours</string>
|
||||||
<string name="main_scan_card_warning_view_subtitle">To access all the networks you need to scan the card</string>
|
<string name="main_scan_card_warning_view_subtitle">To access all the networks you need to scan the card</string>
|
||||||
<string name="main_scan_card_warning_view_title">Scan your card</string>
|
<string name="main_scan_card_warning_view_title">Scan your card</string>
|
||||||
<string name="main_swap_promotion_message">Swap multiple currencies across several blockchains</string>
|
<string name="main_swap_changelly_promotion_message">Enjoy %1$s service fees on swaps via Changelly from February %2$s-%3$s</string>
|
||||||
<string name="main_swap_promotion_title">Cross-chain swaps are now available</string>
|
<string name="main_swap_changelly_promotion_title">Swap with Changelly, %s fees</string>
|
||||||
<string name="main_tokens">Tokens</string>
|
<string name="main_tokens">Tokens</string>
|
||||||
<string name="manage_tokens_add">Add</string>
|
<string name="manage_tokens_add">Add</string>
|
||||||
<string name="manage_tokens_edit">Edit</string>
|
<string name="manage_tokens_edit">Edit</string>
|
||||||
|
|
@ -587,8 +587,8 @@
|
||||||
<string name="token_details_unable_hide_alert_message">The %1$s token is the main currency on the %2$s network and cannot be hidden as long as you have other tokens on this network in the list.</string>
|
<string name="token_details_unable_hide_alert_message">The %1$s token is the main currency on the %2$s network and cannot be hidden as long as you have other tokens on this network in the list.</string>
|
||||||
<string name="token_details_unable_hide_alert_title">Unable to hide %s</string>
|
<string name="token_details_unable_hide_alert_title">Unable to hide %s</string>
|
||||||
<string name="token_item_no_rate">No rate</string>
|
<string name="token_item_no_rate">No rate</string>
|
||||||
<string name="token_swap_promotion_message">Exchange this token for other assets in your portfolio</string>
|
<string name="token_swap_changelly_promotion_message">Exchange this token for another at %1$s service fees from February %2$s-%3$s.</string>
|
||||||
<string name="token_swap_promotion_title">Introducing cross-chain swaps</string>
|
<string name="token_swap_changelly_promotion_title">Swap with Changelly, %s fees</string>
|
||||||
<string name="token_swap_promotion_button">Swap now</string>
|
<string name="token_swap_promotion_button">Swap now</string>
|
||||||
<string name="transaction_history_contract_address">contract: %s</string>
|
<string name="transaction_history_contract_address">contract: %s</string>
|
||||||
<string name="transaction_history_empty_transactions">You don\'t have any transactions yet</string>
|
<string name="transaction_history_empty_transactions">You don\'t have any transactions yet</string>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
import com.tangem.core.ui.extensions.resolveReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.core.ui.res.LocalIsInDarkTheme
|
import com.tangem.core.ui.res.LocalIsInDarkTheme
|
||||||
import com.tangem.core.ui.res.TangemColorPalette.Dark6
|
import com.tangem.core.ui.res.TangemColorPalette.Dark6
|
||||||
import com.tangem.core.ui.res.TangemColorPalette.Light4
|
import com.tangem.core.ui.res.TangemColorPalette.Light4
|
||||||
|
|
@ -55,7 +56,7 @@ fun NotificationWithBackground(config: NotificationConfig, modifier: Modifier =
|
||||||
val spacing14 = TangemTheme.dimens.spacing14
|
val spacing14 = TangemTheme.dimens.spacing14
|
||||||
|
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(config.backgroundResId ?: R.drawable.img_swap_promo_banner_background),
|
painter = painterResource(config.backgroundResId ?: R.drawable.img_swap_promo_blue_banner_background),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
modifier = Modifier.constrainAs(backgroundRef) {
|
modifier = Modifier.constrainAs(backgroundRef) {
|
||||||
|
|
@ -171,13 +172,19 @@ private class NotificationWithBackgroundPreviewProvider : PreviewParameterProvid
|
||||||
override val values: Sequence<NotificationConfig>
|
override val values: Sequence<NotificationConfig>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
NotificationConfig(
|
NotificationConfig(
|
||||||
title = resourceReference(id = R.string.main_swap_promotion_title),
|
title = resourceReference(id = R.string.main_swap_changelly_promotion_title),
|
||||||
subtitle = resourceReference(id = R.string.main_swap_promotion_message),
|
subtitle = resourceReference(
|
||||||
|
id = R.string.main_swap_changelly_promotion_message,
|
||||||
|
formatArgs = wrappedList("1", "2"),
|
||||||
|
),
|
||||||
iconResId = R.drawable.img_swap_promo,
|
iconResId = R.drawable.img_swap_promo,
|
||||||
backgroundResId = R.drawable.img_swap_promo_banner_background,
|
backgroundResId = R.drawable.img_swap_promo_blue_banner_background,
|
||||||
),
|
),
|
||||||
NotificationConfig(
|
NotificationConfig(
|
||||||
title = resourceReference(id = R.string.token_swap_promotion_title),
|
title = resourceReference(
|
||||||
|
id = R.string.token_swap_changelly_promotion_title,
|
||||||
|
formatArgs = wrappedList("1", "2"),
|
||||||
|
),
|
||||||
subtitle = stringReference(
|
subtitle = stringReference(
|
||||||
"Swap multiple currencies between any chains you wish. Swap multiple " +
|
"Swap multiple currencies between any chains you wish. Swap multiple " +
|
||||||
"currencies between any chains you wish. Swap multiple " +
|
"currencies between any chains you wish. Swap multiple " +
|
||||||
|
|
@ -185,7 +192,7 @@ private class NotificationWithBackgroundPreviewProvider : PreviewParameterProvid
|
||||||
"till Dec 31.",
|
"till Dec 31.",
|
||||||
),
|
),
|
||||||
iconResId = R.drawable.img_swap_promo,
|
iconResId = R.drawable.img_swap_promo,
|
||||||
backgroundResId = R.drawable.img_swap_promo_banner_background,
|
backgroundResId = R.drawable.img_swap_promo_blue_banner_background,
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||||
text = resourceReference(id = R.string.token_swap_promotion_button),
|
text = resourceReference(id = R.string.token_swap_promotion_button),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
1
data/promo/.gitignore
vendored
Normal file
1
data/promo/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
25
data/promo/build.gradle.kts
Normal file
25
data/promo/build.gradle.kts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
alias(deps.plugins.kotlin.kapt)
|
||||||
|
alias(deps.plugins.hilt.android)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.tangem.data.promo"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(deps.androidx.datastore)
|
||||||
|
|
||||||
|
implementation(deps.jodatime)
|
||||||
|
implementation(deps.hilt.android)
|
||||||
|
kapt(deps.hilt.kapt)
|
||||||
|
|
||||||
|
implementation(projects.domain.tokens)
|
||||||
|
implementation(projects.domain.tokens.models)
|
||||||
|
|
||||||
|
implementation(projects.core.datasource)
|
||||||
|
implementation(projects.core.utils)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.tangem.data.promo
|
||||||
|
|
||||||
|
import com.tangem.data.promo.converters.PromoResponseConverter
|
||||||
|
import com.tangem.datasource.api.common.response.getOrThrow
|
||||||
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.domain.promo.PromoBanner
|
||||||
|
import com.tangem.domain.tokens.repository.PromoRepository
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import com.tangem.utils.coroutines.runCatching
|
||||||
|
|
||||||
|
internal class DefaultPromoRepository(
|
||||||
|
private val tangemApi: TangemTechApi,
|
||||||
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
|
) : PromoRepository {
|
||||||
|
|
||||||
|
private val promoResponseConverter = PromoResponseConverter()
|
||||||
|
override suspend fun getChangellyPromoBanner(): PromoBanner? {
|
||||||
|
return runCatching(dispatchers.io) {
|
||||||
|
promoResponseConverter.convert(
|
||||||
|
tangemApi.getPromotionInfo(CHANGELLY_NAME)
|
||||||
|
.getOrThrow(),
|
||||||
|
)
|
||||||
|
}.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private const val CHANGELLY_NAME = "changelly"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.tangem.data.promo.converters
|
||||||
|
|
||||||
|
import com.tangem.datasource.api.promotion.models.PromotionInfoResponse
|
||||||
|
import com.tangem.domain.promo.PromoBanner
|
||||||
|
import com.tangem.utils.converter.Converter
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
class PromoResponseConverter : Converter<PromotionInfoResponse, PromoBanner?> {
|
||||||
|
|
||||||
|
override fun convert(value: PromotionInfoResponse): PromoBanner? {
|
||||||
|
val bannerState = value.bannerState ?: return null
|
||||||
|
return PromoBanner(
|
||||||
|
name = value.name,
|
||||||
|
bannerState = PromoBanner.BannerState(
|
||||||
|
status = bannerState.status,
|
||||||
|
timeline = PromoBanner.Timeline(
|
||||||
|
start = DateTime.parse(bannerState.timeline.start),
|
||||||
|
end = DateTime.parse(bannerState.timeline.end),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.tangem.data.promo.di
|
||||||
|
|
||||||
|
import com.tangem.data.promo.DefaultPromoRepository
|
||||||
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
|
import com.tangem.datasource.di.DevTangemApi
|
||||||
|
import com.tangem.domain.tokens.repository.PromoRepository
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object PromoDataModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun providePromoRepository(
|
||||||
|
@DevTangemApi tangemTechApi: TangemTechApi,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
): PromoRepository {
|
||||||
|
return DefaultPromoRepository(tangemTechApi, dispatchers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
package com.tangem.data.settings
|
package com.tangem.data.settings
|
||||||
|
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys.IS_TOKEN_SWAP_PROMO_SHOW_KEY
|
import com.tangem.datasource.local.preferences.PreferencesKeys.IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_SWAP_PROMO_SHOW_KEY
|
import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY
|
||||||
import com.tangem.datasource.local.preferences.utils.get
|
import com.tangem.datasource.local.preferences.utils.get
|
||||||
import com.tangem.datasource.local.preferences.utils.store
|
import com.tangem.datasource.local.preferences.utils.store
|
||||||
import com.tangem.domain.settings.repositories.SwapPromoRepository
|
import com.tangem.domain.settings.repositories.SwapPromoRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository for showing swap promo notification.
|
* Repository for showing swap promo notification.
|
||||||
|
|
@ -16,47 +14,25 @@ import java.util.Calendar
|
||||||
class DefaultSwapPromoRepository(
|
class DefaultSwapPromoRepository(
|
||||||
private val appPreferencesStore: AppPreferencesStore,
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
) : SwapPromoRepository {
|
) : SwapPromoRepository {
|
||||||
override fun isReadyToShowWallet(): Flow<Boolean> {
|
override fun isReadyToShowWalletPromo(): Flow<Boolean> {
|
||||||
return appPreferencesStore.get(IS_WALLET_SWAP_PROMO_SHOW_KEY, true)
|
return appPreferencesStore.get(IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY, true)
|
||||||
.map { it && checkPromoPeriod() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isReadyToShowToken(): Flow<Boolean> {
|
override fun isReadyToShowTokenPromo(): Flow<Boolean> {
|
||||||
return appPreferencesStore.get(IS_TOKEN_SWAP_PROMO_SHOW_KEY, true)
|
return appPreferencesStore.get(IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY, true)
|
||||||
.map { it && checkPromoPeriod() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setNeverToShowWallet() {
|
override suspend fun setNeverToShowWalletPromo() {
|
||||||
appPreferencesStore.store(
|
appPreferencesStore.store(
|
||||||
key = IS_WALLET_SWAP_PROMO_SHOW_KEY,
|
key = IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY,
|
||||||
value = false,
|
value = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setNeverToShowToken() {
|
override suspend fun setNeverToShowTokenPromo() {
|
||||||
appPreferencesStore.store(
|
appPreferencesStore.store(
|
||||||
key = IS_TOKEN_SWAP_PROMO_SHOW_KEY,
|
key = IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY,
|
||||||
value = false,
|
value = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun checkPromoPeriod(): Boolean {
|
|
||||||
val calendar = Calendar.getInstance()
|
|
||||||
val currentTime = calendar.timeInMillis
|
|
||||||
calendar.set(END_YEAR_KEY, END_MONTH_KEY, END_DAY_KEY, 0, 0, 0)
|
|
||||||
val endTime = calendar.timeInMillis
|
|
||||||
|
|
||||||
val shouldShow = endTime - currentTime > 0
|
|
||||||
if (!shouldShow) {
|
|
||||||
setNeverToShowToken()
|
|
||||||
setNeverToShowWallet()
|
|
||||||
}
|
|
||||||
return shouldShow
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val END_DAY_KEY = 1
|
|
||||||
private const val END_MONTH_KEY = 1 // February
|
|
||||||
private const val END_YEAR_KEY = 2024
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class ShouldShowSwapPromoTokenUseCase(private val swapPromoRepository: SwapPromoRepository) {
|
class ShouldShowSwapPromoTokenUseCase(private val swapPromoRepository: SwapPromoRepository) {
|
||||||
|
|
||||||
operator fun invoke(): Flow<Boolean> = swapPromoRepository.isReadyToShowToken()
|
operator fun invoke(): Flow<Boolean> = swapPromoRepository.isReadyToShowTokenPromo()
|
||||||
|
|
||||||
suspend fun neverToShow() = swapPromoRepository.setNeverToShowToken()
|
suspend fun neverToShow() = swapPromoRepository.setNeverToShowTokenPromo()
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class ShouldShowSwapPromoWalletUseCase(private val swapPromoRepository: SwapPromoRepository) {
|
class ShouldShowSwapPromoWalletUseCase(private val swapPromoRepository: SwapPromoRepository) {
|
||||||
|
|
||||||
operator fun invoke(): Flow<Boolean> = swapPromoRepository.isReadyToShowWallet()
|
operator fun invoke(): Flow<Boolean> = swapPromoRepository.isReadyToShowWalletPromo()
|
||||||
|
|
||||||
suspend fun neverToShow() = swapPromoRepository.setNeverToShowWallet()
|
suspend fun neverToShow() = swapPromoRepository.setNeverToShowWalletPromo()
|
||||||
}
|
}
|
||||||
|
|
@ -3,11 +3,11 @@ package com.tangem.domain.settings.repositories
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface SwapPromoRepository {
|
interface SwapPromoRepository {
|
||||||
fun isReadyToShowWallet(): Flow<Boolean>
|
fun isReadyToShowWalletPromo(): Flow<Boolean>
|
||||||
|
|
||||||
fun isReadyToShowToken(): Flow<Boolean>
|
fun isReadyToShowTokenPromo(): Flow<Boolean>
|
||||||
|
|
||||||
suspend fun setNeverToShowWallet()
|
suspend fun setNeverToShowWalletPromo()
|
||||||
|
|
||||||
suspend fun setNeverToShowToken()
|
suspend fun setNeverToShowTokenPromo()
|
||||||
}
|
}
|
||||||
|
|
@ -15,4 +15,5 @@ dependencies {
|
||||||
implementation(deps.tangem.blockchain) {
|
implementation(deps.tangem.blockchain) {
|
||||||
exclude(module = "joda-time")
|
exclude(module = "joda-time")
|
||||||
}
|
}
|
||||||
|
implementation(deps.jodatime)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.tangem.domain.promo
|
||||||
|
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
data class PromoBanner(
|
||||||
|
val name: String,
|
||||||
|
val bannerState: BannerState,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val isActive = bannerState.status == ACTIVE_STATUS && bannerState.timeline.end.isAfterNow
|
||||||
|
|
||||||
|
data class BannerState(
|
||||||
|
val timeline: Timeline,
|
||||||
|
val status: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Timeline(
|
||||||
|
val start: DateTime,
|
||||||
|
val end: DateTime,
|
||||||
|
)
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val ACTIVE_STATUS = "active"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.domain.tokens.model.warnings
|
package com.tangem.domain.tokens.model.warnings
|
||||||
|
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
|
import org.joda.time.DateTime
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
sealed class CryptoCurrencyWarning {
|
sealed class CryptoCurrencyWarning {
|
||||||
|
|
@ -42,5 +43,8 @@ sealed class CryptoCurrencyWarning {
|
||||||
|
|
||||||
data class HasPendingTransactions(val blockchainSymbol: String) : CryptoCurrencyWarning()
|
data class HasPendingTransactions(val blockchainSymbol: String) : CryptoCurrencyWarning()
|
||||||
|
|
||||||
object SwapPromo : CryptoCurrencyWarning()
|
data class SwapPromo(
|
||||||
|
val startDateTime: DateTime,
|
||||||
|
val endDateTime: DateTime,
|
||||||
|
) : CryptoCurrencyWarning()
|
||||||
}
|
}
|
||||||
|
|
@ -7,10 +7,7 @@ import com.tangem.domain.tokens.model.FeePaidCurrency
|
||||||
import com.tangem.domain.tokens.model.Network
|
import com.tangem.domain.tokens.model.Network
|
||||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
||||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
import com.tangem.domain.tokens.repository.*
|
||||||
import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository
|
|
||||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
|
||||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||||
|
|
@ -29,6 +26,7 @@ class GetCurrencyWarningsUseCase(
|
||||||
private val networksRepository: NetworksRepository,
|
private val networksRepository: NetworksRepository,
|
||||||
private val swapRepository: SwapRepository,
|
private val swapRepository: SwapRepository,
|
||||||
private val marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
private val marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
|
||||||
|
private val promoRepository: PromoRepository,
|
||||||
private val showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
|
private val showSwapPromoTokenUseCase: ShouldShowSwapPromoTokenUseCase,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) {
|
) {
|
||||||
|
|
@ -90,7 +88,9 @@ class GetCurrencyWarningsUseCase(
|
||||||
showSwapPromoTokenUseCase().conflate(),
|
showSwapPromoTokenUseCase().conflate(),
|
||||||
flowOf(marketCryptoCurrencyRepository.isExchangeable(userWalletId, currency)).conflate(),
|
flowOf(marketCryptoCurrencyRepository.isExchangeable(userWalletId, currency)).conflate(),
|
||||||
) { shouldShowSwapPromo, isExchangeable ->
|
) { shouldShowSwapPromo, isExchangeable ->
|
||||||
if (shouldShowSwapPromo && isExchangeable && currencyStatus.value !is CryptoCurrencyStatus.Unreachable) {
|
val promoBanner = promoRepository.getChangellyPromoBanner() ?: return@combine null
|
||||||
|
val showPromo = promoBanner.isActive && shouldShowSwapPromo
|
||||||
|
if (showPromo && isExchangeable && currencyStatus.value !is CryptoCurrencyStatus.Unreachable) {
|
||||||
cryptoStatuses.fold(
|
cryptoStatuses.fold(
|
||||||
ifLeft = { null },
|
ifLeft = { null },
|
||||||
ifRight = { cryptoCurrencyStatuses ->
|
ifRight = { cryptoCurrencyStatuses ->
|
||||||
|
|
@ -124,7 +124,10 @@ class GetCurrencyWarningsUseCase(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (showPromo) {
|
if (showPromo) {
|
||||||
CryptoCurrencyWarning.SwapPromo
|
CryptoCurrencyWarning.SwapPromo(
|
||||||
|
startDateTime = promoBanner.bannerState.timeline.start,
|
||||||
|
endDateTime = promoBanner.bannerState.timeline.end,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.tangem.domain.tokens.repository
|
||||||
|
|
||||||
|
import com.tangem.domain.promo.PromoBanner
|
||||||
|
|
||||||
|
interface PromoRepository {
|
||||||
|
|
||||||
|
suspend fun getChangellyPromoBanner(): PromoBanner?
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||||
import com.tangem.features.tokendetails.impl.R
|
import com.tangem.features.tokendetails.impl.R
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
||||||
|
|
@ -41,14 +42,22 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SwapPromo(
|
data class SwapPromo(
|
||||||
|
val startDateTime: DateTime,
|
||||||
|
val endDateTime: DateTime,
|
||||||
val onSwapClick: () -> Unit,
|
val onSwapClick: () -> Unit,
|
||||||
val onCloseClick: () -> Unit,
|
val onCloseClick: () -> Unit,
|
||||||
) : TokenDetailsNotification(
|
) : TokenDetailsNotification(
|
||||||
config = NotificationConfig(
|
config = NotificationConfig(
|
||||||
title = resourceReference(id = R.string.token_swap_promotion_title),
|
title = resourceReference(
|
||||||
subtitle = resourceReference(id = R.string.token_swap_promotion_message),
|
id = R.string.token_swap_changelly_promotion_title,
|
||||||
|
formatArgs = wrappedList("0%"),
|
||||||
|
),
|
||||||
|
subtitle = resourceReference(
|
||||||
|
id = R.string.token_swap_changelly_promotion_message,
|
||||||
|
formatArgs = wrappedList("0%", startDateTime.dayOfMonth, endDateTime.dayOfMonth),
|
||||||
|
),
|
||||||
iconResId = R.drawable.img_swap_promo,
|
iconResId = R.drawable.img_swap_promo,
|
||||||
backgroundResId = R.drawable.img_swap_promo_banner_background,
|
backgroundResId = R.drawable.img_swap_promo_green_banner_background,
|
||||||
onCloseClick = onCloseClick,
|
onCloseClick = onCloseClick,
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||||
text = resourceReference(id = com.tangem.core.ui.R.string.token_swap_promotion_button),
|
text = resourceReference(id = com.tangem.core.ui.R.string.token_swap_promotion_button),
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ internal class TokenDetailsNotificationConverter(
|
||||||
coinSymbol = warning.blockchainSymbol,
|
coinSymbol = warning.blockchainSymbol,
|
||||||
)
|
)
|
||||||
is CryptoCurrencyWarning.SwapPromo -> SwapPromo(
|
is CryptoCurrencyWarning.SwapPromo -> SwapPromo(
|
||||||
|
startDateTime = warning.startDateTime,
|
||||||
|
endDateTime = warning.endDateTime,
|
||||||
onSwapClick = clickIntents::onSwapPromoClick,
|
onSwapClick = clickIntents::onSwapPromoClick,
|
||||||
onCloseClick = clickIntents::onSwapPromoDismiss,
|
onCloseClick = clickIntents::onSwapPromoDismiss,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,16 @@ import arrow.core.Either
|
||||||
import com.tangem.domain.common.CardTypesResolver
|
import com.tangem.domain.common.CardTypesResolver
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||||
|
import com.tangem.domain.promo.PromoBanner
|
||||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||||
|
import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase
|
||||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||||
import com.tangem.domain.tokens.error.TokenListError
|
import com.tangem.domain.tokens.error.TokenListError
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.tokens.model.NetworkGroup
|
import com.tangem.domain.tokens.model.NetworkGroup
|
||||||
import com.tangem.domain.tokens.model.TokenList
|
import com.tangem.domain.tokens.model.TokenList
|
||||||
|
import com.tangem.domain.tokens.repository.PromoRepository
|
||||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
||||||
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||||
|
|
@ -26,12 +29,15 @@ import kotlinx.coroutines.flow.flowOf
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
@ViewModelScoped
|
@ViewModelScoped
|
||||||
internal class GetMultiWalletWarningsFactory @Inject constructor(
|
internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||||
private val getTokenListUseCase: GetTokenListUseCase,
|
private val getTokenListUseCase: GetTokenListUseCase,
|
||||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||||
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||||
|
private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase,
|
||||||
|
private val promoRepository: PromoRepository,
|
||||||
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -52,9 +58,15 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
flow = getTokenListUseCase(userWallet.walletId).conflate(),
|
flow = getTokenListUseCase(userWallet.walletId).conflate(),
|
||||||
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
||||||
flow3 = isNeedToBackupUseCase(userWallet.walletId).conflate(),
|
flow3 = isNeedToBackupUseCase(userWallet.walletId).conflate(),
|
||||||
) { maybeTokenList, isReadyToShowRating, isNeedToBackup ->
|
flow4 = shouldShowSwapPromoWalletUseCase().conflate(),
|
||||||
|
) { maybeTokenList, isReadyToShowRating, isNeedToBackup, shouldShowPromo ->
|
||||||
|
|
||||||
|
val promoBanner = promoRepository.getChangellyPromoBanner()
|
||||||
|
|
||||||
readyForRateAppNotification = true
|
readyForRateAppNotification = true
|
||||||
buildList {
|
buildList {
|
||||||
|
addSwapPromoNotification(shouldShowPromo, promoBanner, clickIntents)
|
||||||
|
|
||||||
addCriticalNotifications(cardTypesResolver)
|
addCriticalNotifications(cardTypesResolver)
|
||||||
|
|
||||||
addInformationalNotifications(cardTypesResolver, maybeTokenList, clickIntents)
|
addInformationalNotifications(cardTypesResolver, maybeTokenList, clickIntents)
|
||||||
|
|
@ -66,6 +78,23 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MutableList<WalletNotification>.addSwapPromoNotification(
|
||||||
|
shouldShowPromo: Boolean,
|
||||||
|
promoBanner: PromoBanner?,
|
||||||
|
clickIntents: WalletClickIntentsV2,
|
||||||
|
) {
|
||||||
|
promoBanner ?: return
|
||||||
|
val promoNotification = WalletNotification.SwapPromo(
|
||||||
|
startDateTime = promoBanner.bannerState.timeline.start,
|
||||||
|
endDateTime = promoBanner.bannerState.timeline.end,
|
||||||
|
onCloseClick = clickIntents::onCloseSwapPromoClick,
|
||||||
|
)
|
||||||
|
addIf(
|
||||||
|
element = promoNotification,
|
||||||
|
condition = shouldShowPromo && promoBanner.isActive,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
||||||
addIf(
|
addIf(
|
||||||
element = WalletNotification.Critical.DevCard,
|
element = WalletNotification.Critical.DevCard,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import com.tangem.core.ui.extensions.pluralReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.feature.wallet.impl.R
|
import com.tangem.feature.wallet.impl.R
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wallet notification component state
|
* Wallet notification component state
|
||||||
|
|
@ -168,13 +169,21 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SwapPromo(
|
data class SwapPromo(
|
||||||
|
val startDateTime: DateTime,
|
||||||
|
val endDateTime: DateTime,
|
||||||
val onCloseClick: () -> Unit,
|
val onCloseClick: () -> Unit,
|
||||||
) : WalletNotification(
|
) : WalletNotification(
|
||||||
config = NotificationConfig(
|
config = NotificationConfig(
|
||||||
title = resourceReference(id = R.string.main_swap_promotion_title),
|
title = resourceReference(
|
||||||
subtitle = resourceReference(id = R.string.main_swap_promotion_message),
|
id = R.string.main_swap_changelly_promotion_title,
|
||||||
|
formatArgs = wrappedList("0%"),
|
||||||
|
),
|
||||||
|
subtitle = resourceReference(
|
||||||
|
id = R.string.main_swap_changelly_promotion_message,
|
||||||
|
formatArgs = wrappedList("0%", startDateTime.dayOfMonth, endDateTime.dayOfMonth),
|
||||||
|
),
|
||||||
iconResId = R.drawable.img_swap_promo,
|
iconResId = R.drawable.img_swap_promo,
|
||||||
backgroundResId = R.drawable.img_swap_promo_banner_background,
|
backgroundResId = R.drawable.img_swap_promo_green_banner_background,
|
||||||
onCloseClick = onCloseClick,
|
onCloseClick = onCloseClick,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,4 @@ internal interface WalletClickIntents {
|
||||||
fun onExploreClick()
|
fun onExploreClick()
|
||||||
|
|
||||||
fun onTransactionClick(txHash: String)
|
fun onTransactionClick(txHash: String)
|
||||||
|
|
||||||
fun onCloseSwapPromoNotificationClick()
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ import com.tangem.domain.common.CardTypesResolver
|
||||||
import com.tangem.domain.common.util.cardTypesResolver
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||||
import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase
|
|
||||||
import com.tangem.domain.tokens.GetMissedAddressesCryptoCurrenciesUseCase
|
import com.tangem.domain.tokens.GetMissedAddressesCryptoCurrenciesUseCase
|
||||||
import com.tangem.domain.tokens.error.GetCurrenciesError
|
import com.tangem.domain.tokens.error.GetCurrenciesError
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
|
|
@ -41,7 +40,6 @@ internal class WalletNotificationsListFactory(
|
||||||
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||||
private val getMissedAddressCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
private val getMissedAddressCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
||||||
private val hasSingleWalletSignedHashesUseCase: HasSingleWalletSignedHashesUseCase,
|
private val hasSingleWalletSignedHashesUseCase: HasSingleWalletSignedHashesUseCase,
|
||||||
private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase,
|
|
||||||
private val clickIntents: WalletClickIntents,
|
private val clickIntents: WalletClickIntents,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -57,12 +55,9 @@ internal class WalletNotificationsListFactory(
|
||||||
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
flow2 = isReadyToShowRateAppUseCase().conflate(),
|
||||||
flow3 = isNeedToBackupUseCase(selectedWallet.walletId).conflate(),
|
flow3 = isNeedToBackupUseCase(selectedWallet.walletId).conflate(),
|
||||||
flow4 = getMissedAddressCryptoCurrenciesUseCase(selectedWallet.walletId).conflate(),
|
flow4 = getMissedAddressCryptoCurrenciesUseCase(selectedWallet.walletId).conflate(),
|
||||||
flow5 = shouldShowSwapPromoWalletUseCase().conflate(),
|
) { hasSignedHashes, isReadyToShowRating, isNeedToBackup, maybeMissedAddressCurrencies ->
|
||||||
) { hasSignedHashes, isReadyToShowRating, isNeedToBackup, maybeMissedAddressCurrencies, isShowSwapPromo ->
|
|
||||||
readyForRateAppNotification = true
|
readyForRateAppNotification = true
|
||||||
buildList {
|
buildList {
|
||||||
addSwapPromoNotification(isShowSwapPromo, cardTypesResolver)
|
|
||||||
|
|
||||||
addCriticalNotifications(cardTypesResolver)
|
addCriticalNotifications(cardTypesResolver)
|
||||||
|
|
||||||
addInformationalNotifications(cardTypesResolver, maybeMissedAddressCurrencies)
|
addInformationalNotifications(cardTypesResolver, maybeMissedAddressCurrencies)
|
||||||
|
|
@ -86,18 +81,6 @@ internal class WalletNotificationsListFactory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addSwapPromoNotification(
|
|
||||||
showSwapPromo: Boolean,
|
|
||||||
cardTypesResolver: CardTypesResolver,
|
|
||||||
) {
|
|
||||||
addIf(
|
|
||||||
element = WalletNotification.SwapPromo(
|
|
||||||
clickIntents::onCloseSwapPromoNotificationClick,
|
|
||||||
),
|
|
||||||
condition = showSwapPromo && cardTypesResolver.isMultiwalletAllowed(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
||||||
addIf(
|
addIf(
|
||||||
element = WalletNotification.Critical.DevCard,
|
element = WalletNotification.Critical.DevCard,
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,6 @@ internal class WalletViewModel @Inject constructor(
|
||||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||||
private val scanCardToUnlockWalletUseCase: ScanCardToUnlockWalletClickHandler,
|
private val scanCardToUnlockWalletUseCase: ScanCardToUnlockWalletClickHandler,
|
||||||
private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase,
|
|
||||||
isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||||
isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||||
getMissedAddressesCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
getMissedAddressesCryptoCurrenciesUseCase: GetMissedAddressesCryptoCurrenciesUseCase,
|
||||||
|
|
@ -148,7 +147,6 @@ internal class WalletViewModel @Inject constructor(
|
||||||
isNeedToBackupUseCase = isNeedToBackupUseCase,
|
isNeedToBackupUseCase = isNeedToBackupUseCase,
|
||||||
getMissedAddressCryptoCurrenciesUseCase = getMissedAddressesCryptoCurrenciesUseCase,
|
getMissedAddressCryptoCurrenciesUseCase = getMissedAddressesCryptoCurrenciesUseCase,
|
||||||
hasSingleWalletSignedHashesUseCase = hasSingleWalletSignedHashesUseCase,
|
hasSingleWalletSignedHashesUseCase = hasSingleWalletSignedHashesUseCase,
|
||||||
shouldShowSwapPromoWalletUseCase = shouldShowSwapPromoWalletUseCase,
|
|
||||||
clickIntents = this,
|
clickIntents = this,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -795,12 +793,6 @@ internal class WalletViewModel @Inject constructor(
|
||||||
refreshSingleCurrencyContent(selectedWalletIndex)
|
refreshSingleCurrencyContent(selectedWalletIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCloseSwapPromoNotificationClick() {
|
|
||||||
viewModelScope.launch(dispatchers.main) {
|
|
||||||
shouldShowSwapPromoWalletUseCase.neverToShow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: refreshSingleCurrencyContent mustn't update the TxHistory and Buttons. It only must fetch primary
|
// FIXME: refreshSingleCurrencyContent mustn't update the TxHistory and Buttons. It only must fetch primary
|
||||||
// currency. Now it not works because GetPrimaryCurrency's subscriber uses .distinctUntilChanged()
|
// currency. Now it not works because GetPrimaryCurrency's subscriber uses .distinctUntilChanged()
|
||||||
private fun refreshSingleCurrencyContent(walletIndex: Int) {
|
private fun refreshSingleCurrencyContent(walletIndex: Int) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import com.tangem.domain.redux.LegacyAction
|
||||||
import com.tangem.domain.redux.ReduxStateHolder
|
import com.tangem.domain.redux.ReduxStateHolder
|
||||||
import com.tangem.domain.settings.NeverToSuggestRateAppUseCase
|
import com.tangem.domain.settings.NeverToSuggestRateAppUseCase
|
||||||
import com.tangem.domain.settings.RemindToRateAppLaterUseCase
|
import com.tangem.domain.settings.RemindToRateAppLaterUseCase
|
||||||
|
import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase
|
||||||
import com.tangem.domain.tokens.FetchTokenListUseCase
|
import com.tangem.domain.tokens.FetchTokenListUseCase
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||||
import com.tangem.domain.wallets.models.UnlockWalletsError
|
import com.tangem.domain.wallets.models.UnlockWalletsError
|
||||||
|
|
@ -62,6 +63,8 @@ internal interface WalletWarningsClickIntents {
|
||||||
fun onDislikeAppClick()
|
fun onDislikeAppClick()
|
||||||
|
|
||||||
fun onCloseRateAppWarningClick()
|
fun onCloseRateAppWarningClick()
|
||||||
|
|
||||||
|
fun onCloseSwapPromoClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
|
@ -82,6 +85,7 @@ internal class WalletWarningsClickIntentsImplementer @Inject constructor(
|
||||||
private val reduxStateHolder: ReduxStateHolder,
|
private val reduxStateHolder: ReduxStateHolder,
|
||||||
private val testerFeatureToggles: TesterFeatureToggles,
|
private val testerFeatureToggles: TesterFeatureToggles,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
|
private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase,
|
||||||
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
||||||
|
|
||||||
override fun onAddBackupCardClick() {
|
override fun onAddBackupCardClick() {
|
||||||
|
|
@ -302,4 +306,10 @@ internal class WalletWarningsClickIntentsImplementer @Inject constructor(
|
||||||
remindToRateAppLaterUseCase()
|
remindToRateAppLaterUseCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCloseSwapPromoClick() {
|
||||||
|
viewModelScope.launch(dispatchers.main) {
|
||||||
|
shouldShowSwapPromoWalletUseCase.neverToShow()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,4 +152,5 @@ include(":data:wallets")
|
||||||
include(":data:analytics")
|
include(":data:analytics")
|
||||||
include(":data:transaction")
|
include(":data:transaction")
|
||||||
include(":data:visa")
|
include(":data:visa")
|
||||||
|
include(":data:promo")
|
||||||
// endregion Data modules
|
// endregion Data modules
|
||||||
Loading…
Add table
Add a link
Reference in a new issue