diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 0db8c6d7c9..ac3eeb6f5d 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -13,6 +13,9 @@
+
+
+
diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt
index 1e2a24f068..acc39a41db 100644
--- a/app/src/main/java/com/tangem/tap/TapApplication.kt
+++ b/app/src/main/java/com/tangem/tap/TapApplication.kt
@@ -200,6 +200,8 @@ class TapApplication : Application(), ImageLoaderFactory {
appStateHolder.userTokensRepository = userTokensRepository
appStateHolder.walletStoresManager = walletStoresManager
+ // TODO: Try to performance and user experience.
+ // [REDACTED_JIRA]
runBlocking {
featureTogglesManager.init()
learn2ernInteractor.init()
diff --git a/app/src/main/java/com/tangem/tap/network/auth/TangemBasicAuthProvider.kt b/app/src/main/java/com/tangem/tap/network/auth/TangemBasicAuthProvider.kt
index 0db94f45ab..32b29fa4f9 100644
--- a/app/src/main/java/com/tangem/tap/network/auth/TangemBasicAuthProvider.kt
+++ b/app/src/main/java/com/tangem/tap/network/auth/TangemBasicAuthProvider.kt
@@ -3,5 +3,10 @@ package com.tangem.tap.network.auth
import com.tangem.lib.auth.BasicAuthProvider
class TangemBasicAuthProvider(private val credentials: String?) : BasicAuthProvider {
- override fun getCredentials(): String? = credentials
+
+ override fun getCredentials(): Map = if (credentials == null) {
+ mapOf()
+ } else {
+ mapOf("Authorization" to "Basic $credentials")
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt
index ebd04d5b97..6ccf6b29b1 100644
--- a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt
+++ b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt
@@ -2,6 +2,7 @@ package com.tangem.tap.network.auth.di
import com.tangem.datasource.config.ConfigManager
import com.tangem.lib.auth.AuthProvider
+import com.tangem.lib.auth.BasicAuthProvider
import com.tangem.tap.network.auth.AuthProviderImpl
import com.tangem.tap.network.auth.TangemBasicAuthProvider
import com.tangem.tap.proxy.AppStateHolder
@@ -23,7 +24,7 @@ class AuthModule {
@Provides
@Singleton
- fun provideTangemBasicAuthProvider(configManager: ConfigManager): com.tangem.lib.auth.BasicAuthProvider {
+ fun provideTangemBasicAuthProvider(configManager: ConfigManager): BasicAuthProvider {
return TangemBasicAuthProvider(configManager.config.tangemComAuthorization)
}
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt
index 4c6dab75bc..dce9e044b7 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/PromotionApi.kt
@@ -4,35 +4,26 @@ import com.tangem.datasource.api.promotion.models.*
import retrofit2.http.*
/**
+ *
+ * Promotion API
+ * @see Documentation
[REDACTED_AUTHOR]
- * Api details
- * https://www.notion.so/tangem/Promotion-Program-API-0907159c3fdb4975aac761be632f44da
*/
interface PromotionApi {
-
- @Headers("Cache-Control: max-age=$CACHE_CONTROL_SECONDS")
+ @Headers("Cache-Control: max-age=3600")
@GET("promotion")
suspend fun getPromotionInfo(@Query("programName") name: String): PromotionInfoResponse
-
@POST("promotion/code/validate")
- suspend fun codeValidate(@Body request: CodeValidateRequestBody): CodeValidateResponse
+ suspend fun validateCode(@Body request: CodeValidateRequestBody): CodeValidateResponse
-
@POST("promotion/code/award")
- suspend fun codeAward(@Body request: CodeAwardRequestBody): CodeAwardResponse
+ suspend fun requestAwardByCode(@Body request: CodeAwardRequestBody): CodeAwardResponse
-
@POST("promotion/validate")
suspend fun validate(@Body request: ValidateRequestBody): ValidateResponse
-
@GET("promotion/award")
- suspend fun award(@Body request: AwardRequestBody): AwardResponse
-
- companion object {
- const val ONE_INCH_TIMEOUT_MS = 5000L
- const val CACHE_CONTROL_SECONDS = 3600
- }
+ suspend fun requestAward(@Body request: AwardRequestBody): AwardResponse
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt
index 7cf6126c2c..064dc71a96 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/AbstractPromotionResponse.kt
@@ -14,7 +14,5 @@ abstract class AbstractPromotionResponse {
data class Error(
@Json(name = "code") val code: Int,
@Json(name = "description") val description: String,
- ) {
- companion object
- }
+ )
}
\ No newline at end of file
diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
index f0dbc8d7db..905d1373d9 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/di/NetworkModule.kt
@@ -66,10 +66,10 @@ class NetworkModule {
AuthenticationHeader(authProvider),
)
.allowLogging()
- .callTimeout(PromotionApi.ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
- .connectTimeout(PromotionApi.ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
- .readTimeout(PromotionApi.ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
- .writeTimeout(PromotionApi.ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ .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)
}
@@ -90,5 +90,6 @@ class NetworkModule {
const val PROMOTION_BASE_URL = "https://tangem.com/v1/"
const val PAYMENTOLOGY_BASE_URL: String = "https://paymentologygate.oa.r.appspot.com/"
+ const val API_ONE_INCH_TIMEOUT_MS = 5000L
}
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
index 8443d28b82..3275265a73 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultLearn2earnRepository.kt
@@ -6,6 +6,8 @@ import com.tangem.datasource.api.promotion.models.*
import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
import com.tangem.feature.learn2earn.data.api.UsedCardsPreferenceStorage
+import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
+import kotlinx.coroutines.withContext
import timber.log.Timber
/**
@@ -16,6 +18,7 @@ internal class DefaultLearn2earnRepository(
private val usedCardsPreferenceStorage: UsedCardsPreferenceStorage,
private val moshi: Moshi,
private val api: PromotionApi,
+ private val dispatchers: AppCoroutineDispatcherProvider,
) : Learn2earnRepository {
private val promotionInfoAdapter = moshi.adapter(PromotionInfoResponse::class.java)
@@ -40,50 +43,47 @@ internal class DefaultLearn2earnRepository(
return preferencesStorage.alreadyReceivedAward
}
- override suspend fun requestAwardByCode(walletId: String, address: String): Result {
- return runCatching {
- api.codeAward(CodeAwardRequestBody(walletId, address, getPromoCode()))
- }.fold(
- onSuccess = { response ->
- val alreadyReceived = response.status ?: false
- preferencesStorage.alreadyReceivedAward = alreadyReceived
- Result.success(alreadyReceived)
- },
- onFailure = { exception -> Result.failure(exception) },
- )
- }
-
override suspend fun getPromotionInfo(): Result {
- val info = restorePromotionInfo()
+ return withContext(dispatchers.io) {
+ val info = restorePromotionInfo()
- return if (info?.status == PromotionInfoResponse.Status.FINISHED) {
- Result.success(info)
- } else {
- runCatching { api.getPromotionInfo(getProgramName()) }
- .fold(
- onSuccess = { infoResponse ->
- savePromotionInfo(infoResponse)
- Result.success(infoResponse)
- },
- onFailure = { exception -> Result.failure(exception) },
- )
+ if (info?.status == PromotionInfoResponse.Status.FINISHED) {
+ Result.success(info)
+ } else {
+ runCatching { api.getPromotionInfo(getProgramName()) }
+ .fold(
+ onSuccess = { infoResponse ->
+ savePromotionInfo(infoResponse)
+ Result.success(infoResponse)
+ },
+ onFailure = { exception -> Result.failure(exception) },
+ )
+ }
}
}
override suspend fun validate(walletId: String): ValidateResponse {
- return api.validate(ValidateRequestBody(walletId, getProgramName()))
+ return withContext(dispatchers.io) {
+ api.validate(ValidateRequestBody(walletId, getProgramName()))
+ }
}
- override suspend fun award(walletId: String): AwardResponse {
- return api.award(AwardRequestBody(walletId, getProgramName()))
+ override suspend fun requestAward(walletId: String): AwardResponse {
+ return withContext(dispatchers.io) {
+ api.requestAward(AwardRequestBody(walletId, getProgramName()))
+ }
}
- override suspend fun codeValidate(walletId: String, code: String?): CodeValidateResponse {
- return api.codeValidate(CodeValidateRequestBody(walletId, code))
+ override suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse {
+ return withContext(dispatchers.io) {
+ api.validateCode(CodeValidateRequestBody(walletId, code))
+ }
}
- override suspend fun codeAward(walletId: String, address: String, code: String?): CodeAwardResponse {
- return api.codeAward(CodeAwardRequestBody(walletId, address, code))
+ override suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse {
+ return withContext(dispatchers.io) {
+ api.requestAwardByCode(CodeAwardRequestBody(walletId, address, code))
+ }
}
private fun restorePromotionInfo(): PromotionInfoResponse? {
@@ -101,7 +101,6 @@ internal class DefaultLearn2earnRepository(
preferencesStorage.promotionInfo = promotionInfoAdapter.toJson(infoResponse)
} catch (ex: Exception) {
Timber.e(ex)
- preferencesStorage.promotionInfo = null
}
}
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
index 92f5d7da83..1df706746e 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/DefaultPreferenceStorage.kt
@@ -15,6 +15,8 @@ internal class DefaultPreferenceStorage(
) : SimpleKrate(context = context, name = "Lear2earnPromotion"), Learn2earnPreferenceStorage {
override var promoCode: String? by stringPref().withDefault(null)
+
override var promotionInfo: String? by stringPref().withDefault(null)
+
override var alreadyReceivedAward: Boolean by booleanPref().withDefault(false)
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
index 78f548febc..b1a251712c 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnPreferenceStorage.kt
@@ -4,7 +4,10 @@ package com.tangem.feature.learn2earn.data.api
[REDACTED_AUTHOR]
*/
interface Learn2earnPreferenceStorage {
+
var promoCode: String?
+
var promotionInfo: String?
+
var alreadyReceivedAward: Boolean
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
index 6641bc36c8..2a8d8811dd 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/api/Learn2earnRepository.kt
@@ -6,15 +6,24 @@ import com.tangem.datasource.api.promotion.models.*
[REDACTED_AUTHOR]
*/
interface Learn2earnRepository {
+
fun isHadActivatedCards(): Boolean
+
fun getPromoCode(): String?
+
fun savePromoCode(code: String)
+
fun getProgramName(): String
+
fun isAlreadyReceivedAward(): Boolean
- suspend fun requestAwardByCode(walletId: String, address: String): Result
+
suspend fun getPromotionInfo(): Result
+
suspend fun validate(walletId: String): ValidateResponse
- suspend fun award(walletId: String): AwardResponse
- suspend fun codeValidate(walletId: String, code: String?): CodeValidateResponse
- suspend fun codeAward(walletId: String, address: String, code: String?): CodeAwardResponse
+
+ suspend fun requestAward(walletId: String): AwardResponse
+
+ suspend fun validateCode(walletId: String, code: String?): CodeValidateResponse
+
+ suspend fun requestAwardByCode(walletId: String, address: String, code: String?): CodeAwardResponse
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
index 9d6e5a0507..b6b32a203b 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/data/di/Learn2earnDataModule.kt
@@ -12,6 +12,7 @@ import com.tangem.feature.learn2earn.data.DefaultUsedCardsPreferenceStorage
import com.tangem.feature.learn2earn.data.api.Learn2earnPreferenceStorage
import com.tangem.feature.learn2earn.data.api.Learn2earnRepository
import com.tangem.feature.learn2earn.data.api.UsedCardsPreferenceStorage
+import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -44,12 +45,14 @@ class Learn2earnDataModule {
usedCardsPreferenceStorage: UsedCardsPreferenceStorage,
@NetworkMoshi moshi: Moshi,
@PromotionOneInch promotionApi: PromotionApi,
+ dispatchers: AppCoroutineDispatcherProvider,
): Learn2earnRepository {
return DefaultLearn2earnRepository(
preferencesStorage = preferenceStorage,
usedCardsPreferenceStorage = usedCardsPreferenceStorage,
moshi = moshi,
api = promotionApi,
+ dispatchers = dispatchers,
)
}
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
index fcb7c48add..e6446305d0 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/DefaultLearn2earnInteractor.kt
@@ -89,8 +89,6 @@ class DefaultLearn2earnInteractor(
}
private suspend fun initPromotionInfo() {
- // return Promotion.dummyActive()
-
promotion = repository.getPromotionInfo()
.fold(
onSuccess = { response ->
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/WebViewUriBuilder.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/WebViewUriBuilder.kt
index c70e983a15..17361859ea 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/WebViewUriBuilder.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/WebViewUriBuilder.kt
@@ -42,9 +42,7 @@ class WebViewUriBuilder(
}
fun getBasicAuthHeaders(): Map {
- return basicAuthProvider.getCredentials()?.let {
- mapOf("Authorization" to "Basic $it")
- } ?: mapOf()
+ return basicAuthProvider.getCredentials()
}
fun isPromoCodeRedirect(uri: Uri): Boolean {
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/api/Learn2earnInteractor.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/api/Learn2earnInteractor.kt
index 4aa046c5e3..432d4b001f 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/api/Learn2earnInteractor.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/api/Learn2earnInteractor.kt
@@ -9,10 +9,16 @@ import com.tangem.feature.learn2earn.domain.models.RedirectConsequences
interface Learn2earnInteractor {
suspend fun init()
+
fun isNeedToShowViewOnStoriesScreen(): Boolean
+
suspend fun isNeedToShowViewOnWalletScreen(walletId: String): Boolean
+
fun getBasicAuthHeaders(): Map
+
fun buildUriForStories(): Uri
+
fun buildUriForMainPage(walletId: String, cardId: String, cardPubKey: String): Uri
+
fun handleWebViewRedirect(uri: Uri): RedirectConsequences
}
\ No newline at end of file
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/di/Learn2earnDomainModule.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/di/Learn2earnDomainModule.kt
index d33f81422f..07d5687c5d 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/di/Learn2earnDomainModule.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/domain/di/Learn2earnDomainModule.kt
@@ -6,7 +6,6 @@ import com.tangem.feature.learn2earn.domain.DefaultLearn2earnInteractor
import com.tangem.feature.learn2earn.domain.api.Learn2earnInteractor
import com.tangem.feature.learn2earn.presentation.Learn2earnRouter
import com.tangem.lib.auth.BasicAuthProvider
-import com.tangem.utils.extensions.toWeakReference
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -21,7 +20,7 @@ class Learn2earnDomainModule {
@Provides
@Singleton
fun provideRouter(@ApplicationContext context: Context): Learn2earnRouter {
- return Learn2earnRouter(context.toWeakReference())
+ return Learn2earnRouter(context)
}
@Provides
@@ -33,6 +32,7 @@ class Learn2earnDomainModule {
return DefaultLearn2earnInteractor(
repository = repository,
basicAuthProvider = basicAuthProvider,
+ // TODO: 1inch: paste locale provider instead of hardcode
userCountryCodeProvider = { "ru" },
)
}
diff --git a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/presentation/Learn2earnRouter.kt b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/presentation/Learn2earnRouter.kt
index 0c6c1a7e34..a02d4be651 100644
--- a/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/presentation/Learn2earnRouter.kt
+++ b/features/learn2earn/impl/src/main/java/com/tangem/feature/learn2earn/presentation/Learn2earnRouter.kt
@@ -2,22 +2,15 @@ package com.tangem.feature.learn2earn.presentation
import android.content.Context
import android.content.Intent
-import timber.log.Timber
-import java.lang.ref.WeakReference
/**
[REDACTED_AUTHOR]
*/
class Learn2earnRouter(
- private val wContext: WeakReference,
+ private val context: Context,
) {
fun openWebView() {
- val context = wContext.get()
- if (context == null) {
- Timber.e("Can't open the Learn2earnWebViewActivity")
- } else {
- context.startActivity(Intent(context, Learn2earnWebViewActivity::class.java))
- }
+ context.startActivity(Intent(context, Learn2earnWebViewActivity::class.java))
}
}
\ No newline at end of file
diff --git a/libs/auth/src/main/java/com/tangem/lib/auth/BasicAuthProvider.kt b/libs/auth/src/main/java/com/tangem/lib/auth/BasicAuthProvider.kt
index 09dcf8f302..1d4a6c7e14 100644
--- a/libs/auth/src/main/java/com/tangem/lib/auth/BasicAuthProvider.kt
+++ b/libs/auth/src/main/java/com/tangem/lib/auth/BasicAuthProvider.kt
@@ -5,5 +5,5 @@ package com.tangem.lib.auth
*/
interface BasicAuthProvider {
- fun getCredentials(): String?
+ fun getCredentials(): Map
}
\ No newline at end of file