Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-08 18:29:44 +03:00
parent c500f45307
commit a25cbc8d24
5 changed files with 209 additions and 0 deletions

View file

@ -0,0 +1,43 @@
package com.tangem.datasource.api.common
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.Response
import okio.IOException
/**
* Switch base url [Interceptor]
*
* @property id api config id [ApiConfig.ID]
* @property apiConfigsManager api configs manager
*
[REDACTED_AUTHOR]
*/
internal class SwitchBaseUrlInterceptor(
private val id: ApiConfig.ID,
private val apiConfigsManager: ApiConfigsManager,
) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val builder = request.newBuilder()
request = builder
.url(url = request.url.adjustBaseUrl())
.build()
return chain.proceed(request)
}
private fun HttpUrl.adjustBaseUrl(): HttpUrl {
val host = apiConfigsManager.getBaseUrl(id).toHttpUrl().host
return this.newBuilder()
.host(host)
.build()
}
}

View file

@ -0,0 +1,69 @@
package com.tangem.datasource.api.common.config.managers
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.ApiEnvironment
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectMap
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
/**
* Implementation of [ApiConfigsManager] in DEV environment
*
* @property appPreferencesStore app preferences store
* @property dispatchers coroutine dispatcher provider
*/
internal class DevApiConfigsManager(
private val appPreferencesStore: AppPreferencesStore,
private val dispatchers: CoroutineDispatcherProvider,
) : MutableApiConfigsManager {
override val configs: Flow<List<ApiConfig>> get() = _apiConfigs
private val _apiConfigs = MutableStateFlow(value = ApiConfig.values())
override suspend fun initialize() {
// We can't use appPreferencesStore.getObjectMap as base flow,
// because we should keep possibility to work with configs synchronous.
// See [getBaseUrl]
appPreferencesStore.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
.onEach { savedEnvironments ->
_apiConfigs.value = _apiConfigs.value.map { config ->
val savedEnvironment = savedEnvironments[config.id.name]
if (savedEnvironment != null) {
config.copySealed(currentEnvironment = savedEnvironment)
} else {
config
}
}
}
.launchIn(CoroutineScope(dispatchers.main))
}
override fun getBaseUrl(id: ApiConfig.ID): String {
val config = _apiConfigs.value.firstOrNull { it.id == id }
?: error("Api config with id [$id] not found. Check ApiConfig implementations")
return config.environments[config.currentEnvironment]
?: error(
"Api config with id [$id] doesn't contain environment [${config.currentEnvironment}]. " +
"Check ApiConfig implementations",
)
}
override suspend fun changeEnvironment(id: String, environment: ApiEnvironment) {
appPreferencesStore.editData { mutablePreferences ->
val updatedMap = mutablePreferences.getObjectMap<ApiEnvironment>(PreferencesKeys.apiConfigsEnvironmentKey)
.toMutableMap()
.apply { put(id, environment) }
mutablePreferences.setObjectMap(PreferencesKeys.apiConfigsEnvironmentKey, updatedMap)
}
}
}

View file

@ -0,0 +1,18 @@
package com.tangem.datasource.api.common.config.managers
import com.tangem.datasource.api.common.config.ApiConfig
/** Implementation of [ApiConfigsManager] in PROD environment */
internal class ProdApiConfigsManager : ApiConfigsManager {
override fun getBaseUrl(id: ApiConfig.ID): String {
val config = ApiConfig.values().firstOrNull { it.id == id }
?: error("Api config with id [$id] not found. Check ApiConfig implementations")
return config.environments[config.currentEnvironment]
?: error(
"Api config with id [$id] doesn't contain " +
"environment [${config.currentEnvironment}]. Check ApiConfig implementations",
)
}
}

View file

@ -95,6 +95,8 @@ object PreferencesKeys {
booleanPreferencesKey(name = "isTokenSwapPromoOkxShown")
}
val apiConfigsEnvironmentKey by lazy { stringPreferencesKey(name = "apiConfigsEnvironment") }
// region Permission
fun getShouldShowPermission(permission: String) = booleanPreferencesKey("shouldShowPushPermission_$permission")