diff --git a/app/src/main/assets/dev_config_values.json b/app/src/main/assets/dev_config_values.json new file mode 100644 index 0000000000..532adfd5c1 --- /dev/null +++ b/app/src/main/assets/dev_config_values.json @@ -0,0 +1,16 @@ +{ + "configValues": [ + { + "name": "coinMarketCapKey", + "value": "f6622117-c043-47a0-8975-9d673ce484de" + }, + { + "name": "moonPayApiKey", + "value": "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE" + }, + { + "name": "moonPayApiSecretKey", + "value": "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C" + } + ] +} \ No newline at end of file diff --git a/app/src/main/assets/dev_features.json b/app/src/main/assets/dev_features.json new file mode 100644 index 0000000000..aa3fd4c598 --- /dev/null +++ b/app/src/main/assets/dev_features.json @@ -0,0 +1,20 @@ +{ + "features": [ + { + "name": "payIdCreationEnabled", + "value": false + }, + { + "name": "usePayId", + "value": false + }, + { + "name": "showWelcomeMessageAtStart", + "value": false + }, + { + "name": "useTopUp", + "value": false + } + ] +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt b/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt new file mode 100644 index 0000000000..b684bdfbb3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/Conditions.kt @@ -0,0 +1,27 @@ +package com.tangem.tap.domain.config + +import com.tangem.commands.Card +import java.util.* + +/** +[REDACTED_AUTHOR] + */ +interface Condition { + fun isMet(): Boolean +} + +class CardIsStart2CoinCondition(private val card: Card?) : Condition { + + override fun isMet(): Boolean = card?.cardData?.issuerName?.toLowerCase(Locale.US) == "start2coin" +} + +class ConditionsFactory { + companion object { + fun create(name: String): Condition? { + return when (name) { + Feature.payIdIsEnabled -> CardIsStart2CoinCondition(null) + else -> null + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt new file mode 100644 index 0000000000..372bf5e807 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/ConfigLoader.kt @@ -0,0 +1,68 @@ +package com.tangem.tap.domain.config + +import android.content.Context +import com.squareup.moshi.JsonAdapter +import com.tangem.wallet.BuildConfig +import timber.log.Timber + +/** +[REDACTED_AUTHOR] + */ +interface ConfigLoader { + suspend fun loadConfig(onComplete: (Config) -> Unit) +} + + +interface NameResolver { + fun getFeaturesName(): String + fun getConfigValuesName(): String +} + +class ConfigNameResolver { + companion object { + fun get(): NameResolver = if (BuildConfig.DEBUG) dev() else prod() + + private fun dev(): NameResolver { + return object : NameResolver { + override fun getFeaturesName(): String = "dev_features" + override fun getConfigValuesName(): String = "dev_config_values" + } + } + + private fun prod(): NameResolver { + return object : NameResolver { + override fun getFeaturesName(): String = "prod_features" + override fun getConfigValuesName(): String = "prod_config_values" + + } + } + } +} + +class LocalLoader( + private val context: Context, + private val nameResolver: NameResolver, + private val adapter: JsonAdapter +) : ConfigLoader { + + override suspend fun loadConfig(onComplete: (Config) -> Unit) { + val config = try { + val jsonFeatures = readAssetAsString(nameResolver.getFeaturesName()) + var configModel = adapter.fromJson(jsonFeatures) + val features = configModel?.toFeatures(ConfigType.Local) ?: mutableMapOf() + + val jsonConfigValues = readAssetAsString(nameResolver.getConfigValuesName()) + configModel = adapter.fromJson(jsonConfigValues) + val configValues = configModel?.toConfigValues() ?: mutableMapOf() + Config(features, configValues) + } catch (ex: Exception) { + Timber.e(ex) + Config.empty() + } + onComplete(config) + } + + private fun readAssetAsString(fileName: String): String { + return context.assets.open("$fileName.json").bufferedReader().readText() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt new file mode 100644 index 0000000000..18e1e80766 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/JsonModels.kt @@ -0,0 +1,36 @@ +package com.tangem.tap.domain.config + +/** +[REDACTED_AUTHOR] + */ + +interface BaseConfigModel { + val name: String + val value: V? +} + +class FeatureModel( + override val name: String, + override val value: Boolean? +) : BaseConfigModel + +class ConfigValueModel( + override val name: String, + override val value: String? +) : BaseConfigModel + +class ConfigModel(val features: List?, val configValues: List?) + +fun ConfigModel.toFeatures(type: ConfigType): MutableMap { + return features?.map { AppFeature(type, it, ConditionsFactory.create(it.name)) } + ?.associateBy { it.name } + ?.toMutableMap() + ?: mutableMapOf() +} + +fun ConfigModel.toConfigValues(): MutableMap { + return configValues?.map { ConfigurationValue(it.name, it.value) } + ?.associateBy { it.name } + ?.toMutableMap() ?: mutableMapOf() +} + diff --git a/app/src/main/java/com/tangem/tap/domain/config/Models.kt b/app/src/main/java/com/tangem/tap/domain/config/Models.kt new file mode 100644 index 0000000000..07a3bf28bb --- /dev/null +++ b/app/src/main/java/com/tangem/tap/domain/config/Models.kt @@ -0,0 +1,45 @@ +package com.tangem.tap.domain.config + +/** +[REDACTED_AUTHOR] + */ + +interface Feature { + val name: String + val type: ConfigType + fun isActive(): Boolean + fun reset() + fun updateCondition(condition: Condition?) + fun hasCondition(): Boolean + + companion object { + val payIdIsEnabled = "payIdIsEnabled" + } +} + +class AppFeature( + override val type: ConfigType, + private val featureModel: FeatureModel, + private var condition: Condition? +) : Feature { + override val name: String = featureModel.name + + override fun isActive(): Boolean { + return if (condition == null) featureModel.value ?: false + else condition!!.isMet() + } + + override fun reset() { + condition = null + } + + override fun updateCondition(condition: Condition?) { + if (type == ConfigType.Local) this.condition = condition + } + + override fun hasCondition(): Boolean { + return condition != null + } +} + +data class ConfigurationValue(val name: String, val value: String?) \ No newline at end of file