Updated on 2026-08-14
This commit is contained in:
commit
f6a56e1657
64 changed files with 388 additions and 226 deletions
|
|
@ -81,7 +81,7 @@ dependencies {
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.res)
|
implementation(projects.core.res)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.datasource)
|
implementation(projects.core.datasource)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||||
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
|
import com.tangem.blockchainsdk.signer.TransactionSignerFactory
|
||||||
import com.tangem.common.routing.AppRouter
|
import com.tangem.common.routing.AppRouter
|
||||||
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.core.navigation.share.ShareManager
|
import com.tangem.core.navigation.share.ShareManager
|
||||||
import com.tangem.core.navigation.url.UrlOpener
|
import com.tangem.core.navigation.url.UrlOpener
|
||||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||||
|
|
@ -34,6 +35,7 @@ import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
||||||
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
|
||||||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||||
import com.tangem.tap.proxy.AppStateHolder
|
import com.tangem.tap.proxy.AppStateHolder
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.hilt.EntryPoint
|
import dagger.hilt.EntryPoint
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
@ -52,6 +54,8 @@ interface ApplicationEntryPoint {
|
||||||
|
|
||||||
fun getFeatureTogglesManager(): FeatureTogglesManager
|
fun getFeatureTogglesManager(): FeatureTogglesManager
|
||||||
|
|
||||||
|
fun getExcludedBlockchainsManager(): ExcludedBlockchainsManager
|
||||||
|
|
||||||
fun getNetworkConnectionManager(): NetworkConnectionManager
|
fun getNetworkConnectionManager(): NetworkConnectionManager
|
||||||
|
|
||||||
fun getCardScanningFeatureToggles(): CardScanningFeatureToggles
|
fun getCardScanningFeatureToggles(): CardScanningFeatureToggles
|
||||||
|
|
@ -113,4 +117,6 @@ interface ApplicationEntryPoint {
|
||||||
fun getOnrampFeatureToggles(): OnrampFeatureToggles
|
fun getOnrampFeatureToggles(): OnrampFeatureToggles
|
||||||
|
|
||||||
fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles
|
fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles
|
||||||
|
|
||||||
|
fun getCoroutineDispatcherProvider(): CoroutineDispatcherProvider
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +17,8 @@ import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
import com.tangem.core.analytics.models.Basic
|
import com.tangem.core.analytics.models.Basic
|
||||||
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.datasource.api.common.MoshiConverter
|
import com.tangem.datasource.api.common.MoshiConverter
|
||||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||||
import com.tangem.datasource.connection.NetworkConnectionManager
|
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||||
|
|
@ -57,9 +58,11 @@ import com.tangem.tap.domain.tasks.product.DerivationsFinder
|
||||||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||||
import com.tangem.tap.proxy.AppStateHolder
|
import com.tangem.tap.proxy.AppStateHolder
|
||||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.wallet.BuildConfig
|
import com.tangem.wallet.BuildConfig
|
||||||
import dagger.hilt.EntryPoints
|
import dagger.hilt.EntryPoints
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.rekotlin.Store
|
import org.rekotlin.Store
|
||||||
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
|
import com.tangem.tap.domain.walletconnect2.domain.LegacyWalletConnectRepository as WalletConnect2Repository
|
||||||
|
|
@ -88,6 +91,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
||||||
private val featureTogglesManager: FeatureTogglesManager
|
private val featureTogglesManager: FeatureTogglesManager
|
||||||
get() = entryPoint.getFeatureTogglesManager()
|
get() = entryPoint.getFeatureTogglesManager()
|
||||||
|
|
||||||
|
private val excludedBlockchainsManager: ExcludedBlockchainsManager
|
||||||
|
get() = entryPoint.getExcludedBlockchainsManager()
|
||||||
|
|
||||||
private val networkConnectionManager: NetworkConnectionManager
|
private val networkConnectionManager: NetworkConnectionManager
|
||||||
get() = entryPoint.getNetworkConnectionManager()
|
get() = entryPoint.getNetworkConnectionManager()
|
||||||
|
|
||||||
|
|
@ -180,6 +186,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
||||||
|
|
||||||
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
||||||
get() = entryPoint.getOnboardingV2FeatureToggles()
|
get() = entryPoint.getOnboardingV2FeatureToggles()
|
||||||
|
|
||||||
|
private val dispatchers: CoroutineDispatcherProvider
|
||||||
|
get() = entryPoint.getCoroutineDispatcherProvider()
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
|
@ -200,9 +209,11 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
||||||
// TODO: Try to performance and user experience.
|
// TODO: Try to performance and user experience.
|
||||||
// [REDACTED_JIRA]
|
// [REDACTED_JIRA]
|
||||||
runBlocking {
|
runBlocking {
|
||||||
featureTogglesManager.init()
|
awaitAll(
|
||||||
|
async { featureTogglesManager.init() },
|
||||||
initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize())
|
async { excludedBlockchainsManager.init() },
|
||||||
|
async { initWithConfigDependency(environmentConfig = environmentConfigStorage.initialize()) },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadNativeLibraries()
|
loadNativeLibraries()
|
||||||
|
|
@ -216,7 +227,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
||||||
|
|
||||||
derivationsFinder = DerivationsFinder(
|
derivationsFinder = DerivationsFinder(
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
dispatchers = AppCoroutineDispatcherProvider(),
|
dispatchers = dispatchers,
|
||||||
)
|
)
|
||||||
appStateHolder.mainStore = store
|
appStateHolder.mainStore = store
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package com.tangem.tap.common.extensions
|
|
||||||
|
|
||||||
import com.tangem.blockchain.common.Blockchain
|
|
||||||
import com.tangem.common.extensions.remove
|
|
||||||
|
|
||||||
fun Blockchain.getNetworkStandardName(): String {
|
|
||||||
return when (this) {
|
|
||||||
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
|
|
||||||
Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
|
|
||||||
Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
|
|
||||||
Blockchain.Tron, Blockchain.TronTestnet -> "TRC20"
|
|
||||||
Blockchain.TON -> "TON"
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val Blockchain.networkNameWithoutTestnet
|
|
||||||
get() = this.getNetworkName().remove(" Testnet")
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.tap.di.domain
|
package com.tangem.tap.di.domain
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.domain.card.ScanCardProcessor
|
import com.tangem.domain.card.ScanCardProcessor
|
||||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.tap.domain.scanCard
|
package com.tangem.tap.domain.scanCard
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add custom token feature toggles
|
* Add custom token feature toggles
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.tangem.tap.domain.walletconnect2.di
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.datasource.di.SdkMoshi
|
import com.tangem.datasource.di.SdkMoshi
|
||||||
import com.tangem.datasource.files.FileReader
|
import com.tangem.datasource.files.FileReader
|
||||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.tap.domain.walletconnect2.toggles
|
package com.tangem.tap.domain.walletconnect2.toggles
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
|
|
||||||
internal class WalletConnectFeatureToggles(
|
internal class WalletConnectFeatureToggles(
|
||||||
private val featureTogglesManager: FeatureTogglesManager,
|
private val featureTogglesManager: FeatureTogglesManager,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.tap.features.home.featuretoggles
|
package com.tangem.tap.features.home.featuretoggles
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeFeatureToggles @Inject constructor(
|
class HomeFeatureToggles @Inject constructor(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.tangem.core.featuretoggles"
|
namespace = "com.tangem.core.configtoggle"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"version": "undefined"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NEXA",
|
||||||
|
"version": "undefined"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.tangem.core.configtoggle.blockchain
|
||||||
|
|
||||||
|
interface ExcludedBlockchainsManager {
|
||||||
|
|
||||||
|
val excludedBlockchainsIds: Set<String>
|
||||||
|
|
||||||
|
suspend fun init()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.tangem.core.configtoggle.blockchain
|
||||||
|
|
||||||
|
interface MutableExcludedBlockchainsManager : ExcludedBlockchainsManager {
|
||||||
|
|
||||||
|
suspend fun excludeBlockchain(mainnetId: String, isExcluded: Boolean)
|
||||||
|
|
||||||
|
fun isMatchLocalConfig(): Boolean
|
||||||
|
|
||||||
|
suspend fun recoverLocalConfig()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.tangem.core.configtoggle.blockchain.impl
|
||||||
|
|
||||||
|
import com.tangem.core.configtoggle.blockchain.MutableExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||||
|
import com.tangem.core.configtoggle.utils.associateToggles
|
||||||
|
import com.tangem.core.configtoggle.version.VersionProvider
|
||||||
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
|
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||||
|
import com.tangem.datasource.local.preferences.utils.store
|
||||||
|
|
||||||
|
internal class DefaultExcludedBlockchainsManager(
|
||||||
|
private val localTogglesStorage: TogglesStorage,
|
||||||
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
|
private val versionProvider: VersionProvider,
|
||||||
|
) : MutableExcludedBlockchainsManager {
|
||||||
|
|
||||||
|
private var isInitialized: Boolean = false
|
||||||
|
|
||||||
|
private lateinit var currentExcludedBlockchainsIds: Set<String>
|
||||||
|
private lateinit var localExcludedBlockchainsIds: Set<String>
|
||||||
|
|
||||||
|
override val excludedBlockchainsIds: Set<String>
|
||||||
|
get() {
|
||||||
|
if (!isInitialized) error("ExcludedBlockchainsManager is not initialized")
|
||||||
|
|
||||||
|
return currentExcludedBlockchainsIds
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun init() {
|
||||||
|
localTogglesStorage.populate(path = "configs/excluded_blockchains_config")
|
||||||
|
|
||||||
|
val storedExcludedBlockchainsIds = appPreferencesStore.getSyncOrDefault(
|
||||||
|
key = PreferencesKeys.EXCLUDED_BLOCKCHAINS_KEY,
|
||||||
|
default = emptySet(),
|
||||||
|
)
|
||||||
|
|
||||||
|
localExcludedBlockchainsIds = localTogglesStorage.toggles
|
||||||
|
.associateToggles(currentVersion = versionProvider.get().orEmpty())
|
||||||
|
.filterValues { isIncluded -> !isIncluded }
|
||||||
|
.keys
|
||||||
|
|
||||||
|
currentExcludedBlockchainsIds = localExcludedBlockchainsIds + storedExcludedBlockchainsIds
|
||||||
|
|
||||||
|
isInitialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun excludeBlockchain(mainnetId: String, isExcluded: Boolean) {
|
||||||
|
if (isExcluded) {
|
||||||
|
currentExcludedBlockchainsIds += mainnetId
|
||||||
|
} else {
|
||||||
|
currentExcludedBlockchainsIds -= mainnetId
|
||||||
|
}
|
||||||
|
|
||||||
|
storeCurrent()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isMatchLocalConfig(): Boolean {
|
||||||
|
return currentExcludedBlockchainsIds == localExcludedBlockchainsIds
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun recoverLocalConfig() {
|
||||||
|
currentExcludedBlockchainsIds = localExcludedBlockchainsIds
|
||||||
|
|
||||||
|
storeCurrent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun storeCurrent() {
|
||||||
|
appPreferencesStore.store(
|
||||||
|
PreferencesKeys.EXCLUDED_BLOCKCHAINS_KEY,
|
||||||
|
currentExcludedBlockchainsIds,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.tangem.core.configtoggle.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.tangem.core.configtoggle.BuildConfig
|
||||||
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.blockchain.MutableExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.blockchain.impl.DefaultExcludedBlockchainsManager
|
||||||
|
import com.tangem.core.configtoggle.storage.LocalTogglesStorage
|
||||||
|
import com.tangem.core.configtoggle.version.DefaultVersionProvider
|
||||||
|
import com.tangem.datasource.asset.loader.AssetLoader
|
||||||
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object ExcludedBlockchainsManagerModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideExcludedBlockchainsManager(
|
||||||
|
@ApplicationContext context: Context,
|
||||||
|
assetLoader: AssetLoader,
|
||||||
|
appPreferencesStore: AppPreferencesStore,
|
||||||
|
): ExcludedBlockchainsManager {
|
||||||
|
val localTogglesStorage = LocalTogglesStorage(assetLoader)
|
||||||
|
val versionProvider = DefaultVersionProvider(context)
|
||||||
|
|
||||||
|
return DefaultExcludedBlockchainsManager(
|
||||||
|
localTogglesStorage,
|
||||||
|
appPreferencesStore,
|
||||||
|
versionProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideMutableExcludedBlockchainsManager(
|
||||||
|
manager: ExcludedBlockchainsManager,
|
||||||
|
): MutableExcludedBlockchainsManager? {
|
||||||
|
if (!BuildConfig.TESTER_MENU_ENABLED) return null
|
||||||
|
|
||||||
|
return manager as MutableExcludedBlockchainsManager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package com.tangem.core.featuretoggle.di
|
package com.tangem.core.configtoggle.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.tangem.core.featuretoggle.manager.DevFeatureTogglesManager
|
import com.tangem.core.configtoggle.BuildConfig
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.manager.ProdFeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.impl.DevFeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage
|
import com.tangem.core.configtoggle.feature.impl.ProdFeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.version.DefaultVersionProvider
|
import com.tangem.core.configtoggle.storage.LocalTogglesStorage
|
||||||
import com.tangem.core.featuretoggles.BuildConfig
|
import com.tangem.core.configtoggle.version.DefaultVersionProvider
|
||||||
import com.tangem.datasource.asset.loader.AssetLoader
|
import com.tangem.datasource.asset.loader.AssetLoader
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
|
|
@ -27,18 +27,18 @@ internal object FeatureTogglesManagerModule {
|
||||||
assetLoader: AssetLoader,
|
assetLoader: AssetLoader,
|
||||||
appPreferencesStore: AppPreferencesStore,
|
appPreferencesStore: AppPreferencesStore,
|
||||||
): FeatureTogglesManager {
|
): FeatureTogglesManager {
|
||||||
val localFeatureTogglesStorage = LocalFeatureTogglesStorage(assetLoader)
|
val localTogglesStorage = LocalTogglesStorage(assetLoader)
|
||||||
val versionProvider = DefaultVersionProvider(context)
|
val versionProvider = DefaultVersionProvider(context)
|
||||||
|
|
||||||
return if (BuildConfig.TESTER_MENU_ENABLED) {
|
return if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||||
DevFeatureTogglesManager(
|
DevFeatureTogglesManager(
|
||||||
localFeatureTogglesStorage = localFeatureTogglesStorage,
|
localTogglesStorage = localTogglesStorage,
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
versionProvider = versionProvider,
|
versionProvider = versionProvider,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ProdFeatureTogglesManager(
|
ProdFeatureTogglesManager(
|
||||||
localFeatureTogglesStorage = localFeatureTogglesStorage,
|
localTogglesStorage = localTogglesStorage,
|
||||||
versionProvider = versionProvider,
|
versionProvider = versionProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.feature
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component for getting information about the availability of feature toggles
|
* Component for getting information about the availability of feature toggles
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.feature
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component for change information about the availability of feature toggles
|
* Component for change information about the availability of feature toggles
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.feature.impl
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
import com.tangem.core.configtoggle.feature.MutableFeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
import com.tangem.core.configtoggle.utils.associateToggles
|
||||||
|
import com.tangem.core.configtoggle.version.VersionProvider
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||||
|
|
@ -13,12 +14,12 @@ import kotlin.properties.Delegates
|
||||||
/**
|
/**
|
||||||
* Feature toggles manager implementation in DEV build
|
* Feature toggles manager implementation in DEV build
|
||||||
*
|
*
|
||||||
* @property localFeatureTogglesStorage local feature toggles storage
|
* @property localTogglesStorage local feature toggles storage
|
||||||
* @property appPreferencesStore application local store
|
* @property appPreferencesStore application local store
|
||||||
* @property versionProvider application version provider
|
* @property versionProvider application version provider
|
||||||
*/
|
*/
|
||||||
internal class DevFeatureTogglesManager(
|
internal class DevFeatureTogglesManager(
|
||||||
private val localFeatureTogglesStorage: FeatureTogglesStorage,
|
private val localTogglesStorage: TogglesStorage,
|
||||||
private val appPreferencesStore: AppPreferencesStore,
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
private val versionProvider: VersionProvider,
|
private val versionProvider: VersionProvider,
|
||||||
) : MutableFeatureTogglesManager {
|
) : MutableFeatureTogglesManager {
|
||||||
|
|
@ -27,13 +28,13 @@ internal class DevFeatureTogglesManager(
|
||||||
private var localFeatureTogglesMap: Map<String, Boolean> by Delegates.notNull()
|
private var localFeatureTogglesMap: Map<String, Boolean> by Delegates.notNull()
|
||||||
|
|
||||||
override suspend fun init() {
|
override suspend fun init() {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
|
|
||||||
val savedFeatureToggles = appPreferencesStore.getObjectSyncOrNull<Map<String, Boolean>>(
|
val savedFeatureToggles = appPreferencesStore.getObjectSyncOrNull<Map<String, Boolean>>(
|
||||||
key = PreferencesKeys.FEATURE_TOGGLES_KEY,
|
key = PreferencesKeys.FEATURE_TOGGLES_KEY,
|
||||||
) ?: emptyMap()
|
) ?: emptyMap()
|
||||||
|
|
||||||
val localFeatureToggles = localFeatureTogglesStorage.featureToggles
|
val localFeatureToggles = localTogglesStorage.toggles
|
||||||
.associateToggles(currentVersion = versionProvider.get().orEmpty())
|
.associateToggles(currentVersion = versionProvider.get().orEmpty())
|
||||||
|
|
||||||
localFeatureTogglesMap = localFeatureToggles
|
localFeatureTogglesMap = localFeatureToggles
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.tangem.core.configtoggle.feature.impl
|
||||||
|
|
||||||
|
internal object FeatureTogglesConstants {
|
||||||
|
|
||||||
|
const val LOCAL_CONFIG_PATH: String = "configs/feature_toggles_config"
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,28 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.feature.impl
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
import com.tangem.core.configtoggle.utils.associateToggles
|
||||||
|
import com.tangem.core.configtoggle.version.VersionProvider
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feature toggles manager implementation in PROD build
|
* Feature toggles manager implementation in PROD build
|
||||||
*
|
*
|
||||||
* @property localFeatureTogglesStorage local feature toggles storage
|
* @property localTogglesStorage local feature toggles storage
|
||||||
* @property versionProvider application version provider
|
* @property versionProvider application version provider
|
||||||
*/
|
*/
|
||||||
internal class ProdFeatureTogglesManager(
|
internal class ProdFeatureTogglesManager(
|
||||||
private val localFeatureTogglesStorage: FeatureTogglesStorage,
|
private val localTogglesStorage: TogglesStorage,
|
||||||
private val versionProvider: VersionProvider,
|
private val versionProvider: VersionProvider,
|
||||||
) : FeatureTogglesManager {
|
) : FeatureTogglesManager {
|
||||||
|
|
||||||
private var featureToggles: Map<String, Boolean> by Delegates.notNull()
|
private var featureToggles: Map<String, Boolean> by Delegates.notNull()
|
||||||
|
|
||||||
override suspend fun init() {
|
override suspend fun init() {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
featureToggles = localFeatureTogglesStorage.featureToggles
|
featureToggles = localTogglesStorage.toggles
|
||||||
.associateToggles(currentVersion = versionProvider.get() ?: "")
|
.associateToggles(currentVersion = versionProvider.get() ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.tangem.core.configtoggle.storage
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data model with information about config toggle
|
||||||
|
*
|
||||||
|
* @property name toggle name
|
||||||
|
* @property version version in which the toggle will be enabled
|
||||||
|
*
|
||||||
|
* IMPORTANT: if the version is "undefined", it means that toggle is disabled!
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
internal data class ConfigToggle(
|
||||||
|
@Json(name = "name") val name: String,
|
||||||
|
@Json(name = "version") val version: String,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.tangem.core.configtoggle.storage
|
||||||
|
|
||||||
|
import com.tangem.datasource.asset.loader.AssetLoader
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage implementation for storing local feature toggles.
|
||||||
|
* Feature toggles are declared in file [LOCAL_CONFIG_PATH].
|
||||||
|
*
|
||||||
|
* @property assetLoader asset loader
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
internal class LocalTogglesStorage(
|
||||||
|
private val assetLoader: AssetLoader,
|
||||||
|
) : TogglesStorage {
|
||||||
|
|
||||||
|
override var toggles: List<ConfigToggle> by Delegates.notNull()
|
||||||
|
private set
|
||||||
|
|
||||||
|
override suspend fun populate(path: String) {
|
||||||
|
toggles = assetLoader.loadList<ConfigToggle>(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.tangem.core.configtoggle.storage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component that initializes and stores a list of feature toggles
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
internal interface TogglesStorage {
|
||||||
|
|
||||||
|
/** List of feature toggles */
|
||||||
|
val toggles: List<ConfigToggle>
|
||||||
|
|
||||||
|
/** Populate the storage with toggles */
|
||||||
|
suspend fun populate(path: String)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.tangem.core.configtoggle.utils
|
||||||
|
|
||||||
|
import com.tangem.core.configtoggle.storage.ConfigToggle
|
||||||
|
import com.tangem.core.configtoggle.version.VersionAvailabilityContract
|
||||||
|
|
||||||
|
internal fun List<ConfigToggle>.associateToggles(currentVersion: String): Map<String, Boolean> {
|
||||||
|
return associate { localToggle ->
|
||||||
|
Pair(
|
||||||
|
first = localToggle.name,
|
||||||
|
second = VersionAvailabilityContract(currentVersion, localToggle.version),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.version
|
package com.tangem.core.configtoggle.version
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.contract
|
package com.tangem.core.configtoggle.version
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.contract
|
package com.tangem.core.configtoggle.version
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version contract to evaluate availability of feature toggle
|
* Version contract to evaluate availability of feature toggle
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.tangem.core.featuretoggle.version
|
package com.tangem.core.configtoggle.version
|
||||||
|
|
||||||
/** Application version provider */
|
/** Application version provider */
|
||||||
internal interface VersionProvider {
|
internal interface VersionProvider {
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.core.featuretoggle.contract
|
package com.tangem.core.configtoggle.contract
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.core.configtoggle.version.VersionAvailabilityContract
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.core.featuretoggle.contract
|
package com.tangem.core.configtoggle.contract
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
|
import com.tangem.core.configtoggle.version.Version
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.manager
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureToggle
|
import com.tangem.core.configtoggle.feature.impl.DevFeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
import com.tangem.core.configtoggle.feature.impl.FeatureTogglesConstants
|
||||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
import com.tangem.core.configtoggle.storage.ConfigToggle
|
||||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||||
|
import com.tangem.core.configtoggle.utils.associateToggles
|
||||||
|
import com.tangem.core.configtoggle.version.VersionProvider
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||||
|
|
@ -19,13 +21,13 @@ import kotlin.collections.set
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
internal class DevFeatureTogglesManagerTest {
|
internal class DevTogglesManagerTest {
|
||||||
|
|
||||||
private val localFeatureTogglesStorage = mockk<FeatureTogglesStorage>()
|
private val localTogglesStorage = mockk<TogglesStorage>()
|
||||||
private val appPreferenceStore = mockk<AppPreferencesStore>(relaxed = true)
|
private val appPreferenceStore = mockk<AppPreferencesStore>(relaxed = true)
|
||||||
private val versionProvider = mockk<VersionProvider>()
|
private val versionProvider = mockk<VersionProvider>()
|
||||||
private val manager = DevFeatureTogglesManager(
|
private val manager = DevFeatureTogglesManager(
|
||||||
localFeatureTogglesStorage = localFeatureTogglesStorage,
|
localTogglesStorage = localTogglesStorage,
|
||||||
appPreferencesStore = appPreferenceStore,
|
appPreferencesStore = appPreferenceStore,
|
||||||
versionProvider = versionProvider,
|
versionProvider = versionProvider,
|
||||||
)
|
)
|
||||||
|
|
@ -34,17 +36,17 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
fun `successfully initialize storage if shared prefs kept feature toggles`() = runTest {
|
fun `successfully initialize storage if shared prefs kept feature toggles`() = runTest {
|
||||||
val currentVersion = "0.1.0"
|
val currentVersion = "0.1.0"
|
||||||
|
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
coEvery {
|
coEvery {
|
||||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||||
} returns savedFeatureTogglesMap
|
} returns savedFeatureTogglesMap
|
||||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
coEvery { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
coEvery { versionProvider.get() } returns currentVersion
|
coEvery { versionProvider.get() } returns currentVersion
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,17 +63,17 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
fun `successfully initialize storage if shared prefs kept empty list`() = runTest {
|
fun `successfully initialize storage if shared prefs kept empty list`() = runTest {
|
||||||
val currentVersion = "0.1.0"
|
val currentVersion = "0.1.0"
|
||||||
|
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
coEvery {
|
coEvery {
|
||||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||||
} returns emptyMap()
|
} returns emptyMap()
|
||||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
coEvery { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
coEvery { versionProvider.get() } returns currentVersion
|
coEvery { versionProvider.get() } returns currentVersion
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,17 +90,17 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
fun `successfully initialize storage if shared prefs didn't keep feature toggles`() = runTest {
|
fun `successfully initialize storage if shared prefs didn't keep feature toggles`() = runTest {
|
||||||
val currentVersion = "0.1.0"
|
val currentVersion = "0.1.0"
|
||||||
|
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
coEvery {
|
coEvery {
|
||||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||||
} returns null
|
} returns null
|
||||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
coEvery { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
coEvery { versionProvider.get() } returns currentVersion
|
coEvery { versionProvider.get() } returns currentVersion
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,15 +113,15 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `successfully initialize storage if versionProvider returns null`() = runTest {
|
fun `successfully initialize storage if versionProvider returns null`() = runTest {
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
coEvery { appPreferenceStore.getSyncOrNull(PreferencesKeys.FEATURE_TOGGLES_KEY) } returns savedFeatureToggles
|
coEvery { appPreferenceStore.getSyncOrNull(PreferencesKeys.FEATURE_TOGGLES_KEY) } returns savedFeatureToggles
|
||||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
coEvery { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
coEvery { versionProvider.get() } returns null
|
coEvery { versionProvider.get() } returns null
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,8 +224,8 @@ internal class DevFeatureTogglesManagerTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
val localFeatureToggles = listOf(
|
val localFeatureToggles = listOf(
|
||||||
FeatureToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
ConfigToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
||||||
FeatureToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
ConfigToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package com.tangem.core.featuretoggle.manager
|
package com.tangem.core.configtoggle.manager
|
||||||
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureToggle
|
import com.tangem.core.configtoggle.feature.impl.FeatureTogglesConstants
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
import com.tangem.core.configtoggle.feature.impl.ProdFeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
import com.tangem.core.configtoggle.storage.ConfigToggle
|
||||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
import com.tangem.core.configtoggle.storage.TogglesStorage
|
||||||
|
import com.tangem.core.configtoggle.utils.associateToggles
|
||||||
|
import com.tangem.core.configtoggle.version.VersionProvider
|
||||||
import io.mockk.*
|
import io.mockk.*
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -13,24 +15,24 @@ import org.junit.Test
|
||||||
/**
|
/**
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
internal class ProdFeatureTogglesManagerTest {
|
internal class ProdTogglesManagerTest {
|
||||||
|
|
||||||
private val localFeatureTogglesStorage = mockk<FeatureTogglesStorage>()
|
private val localTogglesStorage = mockk<TogglesStorage>()
|
||||||
private val versionProvider = mockk<VersionProvider>()
|
private val versionProvider = mockk<VersionProvider>()
|
||||||
private val manager = ProdFeatureTogglesManager(localFeatureTogglesStorage, versionProvider)
|
private val manager = ProdFeatureTogglesManager(localTogglesStorage, versionProvider)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `successfully initialize storage`() = runTest {
|
fun `successfully initialize storage`() = runTest {
|
||||||
val currentVersion = "1.0.0"
|
val currentVersion = "1.0.0"
|
||||||
|
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
every { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
every { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
every { versionProvider.get() } returns currentVersion
|
every { versionProvider.get() } returns currentVersion
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,14 +42,14 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `successfully initialize storage if versionProvider returns null`() = runTest {
|
fun `successfully initialize storage if versionProvider returns null`() = runTest {
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
every { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
every { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
every { versionProvider.get() } returns null
|
every { versionProvider.get() } returns null
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,8 +58,8 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `failure initialize storage if localFeatureTogglesStorage throws exception`() = runTest {
|
fun `failure initialize storage if localFeatureTogglesStorage throws exception`() = runTest {
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
every { localFeatureTogglesStorage.featureToggles } throws IllegalStateException(
|
every { localTogglesStorage.toggles } throws IllegalStateException(
|
||||||
"Property featureToggles should be initialized before get.",
|
"Property featureToggles should be initialized before get.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -72,14 +74,14 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
Truth.assertThat(it).isInstanceOf(IllegalStateException::class.java)
|
Truth.assertThat(it).isInstanceOf(IllegalStateException::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
coVerifyOrder { localFeatureTogglesStorage.init() }
|
coVerifyOrder { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) }
|
||||||
verifyAll(inverse = true) { versionProvider.get() }
|
verifyAll(inverse = true) { versionProvider.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `failure initialize storage if versionProvider throws exception`() = runTest {
|
fun `failure initialize storage if versionProvider throws exception`() = runTest {
|
||||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
coEvery { localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH) } just Runs
|
||||||
every { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
every { localTogglesStorage.toggles } returns localFeatureToggles
|
||||||
every { versionProvider.get() } throws PackageManager.NameNotFoundException()
|
every { versionProvider.get() } throws PackageManager.NameNotFoundException()
|
||||||
|
|
||||||
runCatching { manager.init() }
|
runCatching { manager.init() }
|
||||||
|
|
@ -89,7 +91,7 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
localFeatureTogglesStorage.init()
|
localTogglesStorage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
versionProvider.get()
|
versionProvider.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,8 +124,8 @@ internal class ProdFeatureTogglesManagerTest {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val localFeatureToggles = listOf(
|
val localFeatureToggles = listOf(
|
||||||
FeatureToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
ConfigToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
||||||
FeatureToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
ConfigToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
||||||
)
|
)
|
||||||
|
|
||||||
val disabledFeatureToggles = mapOf(
|
val disabledFeatureToggles = mapOf(
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
package com.tangem.core.featuretoggle.storage
|
package com.tangem.core.configtoggle.storage
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.squareup.moshi.JsonAdapter
|
import com.squareup.moshi.JsonAdapter
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.squareup.moshi.Types
|
import com.squareup.moshi.Types
|
||||||
|
import com.tangem.core.configtoggle.feature.impl.FeatureTogglesConstants
|
||||||
import com.tangem.datasource.asset.loader.AssetLoader
|
import com.tangem.datasource.asset.loader.AssetLoader
|
||||||
import com.tangem.datasource.asset.reader.AssetReader
|
import com.tangem.datasource.asset.reader.AssetReader
|
||||||
import io.mockk.*
|
import io.mockk.*
|
||||||
|
|
@ -16,16 +17,16 @@ import java.io.IOException
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
*/
|
*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
internal class LocalFeatureTogglesStorageTest {
|
internal class LocalTogglesStorageTest {
|
||||||
|
|
||||||
private val assetReader = mockk<AssetReader>()
|
private val assetReader = mockk<AssetReader>()
|
||||||
private val moshi = mockk<Moshi>()
|
private val moshi = mockk<Moshi>()
|
||||||
private val jsonAdapter = mockk<JsonAdapter<List<FeatureToggle>>>()
|
private val jsonAdapter = mockk<JsonAdapter<List<ConfigToggle>>>()
|
||||||
|
|
||||||
// Impossible to mockk AssetLoader because it implement inline functions
|
// Impossible to mockk AssetLoader because it implement inline functions
|
||||||
private val assetLoader = AssetLoader(assetReader = assetReader, moshi = moshi)
|
private val assetLoader = AssetLoader(assetReader = assetReader, moshi = moshi)
|
||||||
|
|
||||||
private val storage = LocalFeatureTogglesStorage(assetLoader)
|
private val storage = LocalTogglesStorage(assetLoader)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `successfully initialize storage`() = runTest {
|
fun `successfully initialize storage`() = runTest {
|
||||||
|
|
@ -33,14 +34,14 @@ internal class LocalFeatureTogglesStorageTest {
|
||||||
everyCreatingMoshiAdapter() returns jsonAdapter
|
everyCreatingMoshiAdapter() returns jsonAdapter
|
||||||
everyMappingJson() returns featureToggles
|
everyMappingJson() returns featureToggles
|
||||||
|
|
||||||
storage.init()
|
storage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
assetReader.read(CONFIG_FILE_NAME)
|
assetReader.read(CONFIG_FILE_NAME)
|
||||||
jsonAdapter.fromJson(json)
|
jsonAdapter.fromJson(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(featureToggles)
|
Truth.assertThat(storage.toggles).containsExactlyElementsIn(featureToggles)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -49,33 +50,33 @@ internal class LocalFeatureTogglesStorageTest {
|
||||||
everyCreatingMoshiAdapter() returns jsonAdapter
|
everyCreatingMoshiAdapter() returns jsonAdapter
|
||||||
everyMappingJson() throws IOException()
|
everyMappingJson() throws IOException()
|
||||||
|
|
||||||
storage.init()
|
storage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
|
|
||||||
coVerifyOrder {
|
coVerifyOrder {
|
||||||
assetReader.read(CONFIG_FILE_NAME)
|
assetReader.read(CONFIG_FILE_NAME)
|
||||||
jsonAdapter.fromJson(json)
|
jsonAdapter.fromJson(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(emptyList<FeatureToggle>())
|
Truth.assertThat(storage.toggles).containsExactlyElementsIn(emptyList<ConfigToggle>())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `failure initialize storage if jsonAdapter throws exception`() = runTest {
|
fun `failure initialize storage if jsonAdapter throws exception`() = runTest {
|
||||||
everyReadingJson() throws IOException()
|
everyReadingJson() throws IOException()
|
||||||
|
|
||||||
storage.init()
|
storage.populate(FeatureTogglesConstants.LOCAL_CONFIG_PATH)
|
||||||
|
|
||||||
coVerifyOrder { assetReader.read(CONFIG_FILE_NAME) }
|
coVerifyOrder { assetReader.read(CONFIG_FILE_NAME) }
|
||||||
verifyAll(inverse = true) { jsonAdapter.fromJson(any<String>()) }
|
verifyAll(inverse = true) { jsonAdapter.fromJson(any<String>()) }
|
||||||
|
|
||||||
Truth.assertThat(storage.featureToggles).containsExactlyElementsIn(emptyList<FeatureToggle>())
|
Truth.assertThat(storage.toggles).containsExactlyElementsIn(emptyList<ConfigToggle>())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun everyReadingJson() = coEvery { assetReader.read(CONFIG_FILE_NAME) }
|
private fun everyReadingJson() = coEvery { assetReader.read(CONFIG_FILE_NAME) }
|
||||||
|
|
||||||
private fun everyCreatingMoshiAdapter() = every {
|
private fun everyCreatingMoshiAdapter() = every {
|
||||||
val types = Types.newParameterizedType(List::class.java, FeatureToggle::class.java)
|
val types = Types.newParameterizedType(List::class.java, ConfigToggle::class.java)
|
||||||
moshi.adapter<List<FeatureToggle>>(types)
|
moshi.adapter<List<ConfigToggle>>(types)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun everyMappingJson() = every { jsonAdapter.fromJson(json) }
|
private fun everyMappingJson() = every { jsonAdapter.fromJson(json) }
|
||||||
|
|
@ -97,8 +98,8 @@ internal class LocalFeatureTogglesStorageTest {
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
val featureToggles = listOf(
|
val featureToggles = listOf(
|
||||||
FeatureToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
ConfigToggle(name = "INACTIVE_TEST_FEATURE_ENABLED", version = "undefined"),
|
||||||
FeatureToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
ConfigToggle(name = "ACTIVE2_TEST_FEATURE_ENABLED", version = "1.0.0"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -55,6 +55,8 @@ object PreferencesKeys {
|
||||||
|
|
||||||
val FEATURE_TOGGLES_KEY by lazy { stringPreferencesKey(name = "featureToggles") }
|
val FEATURE_TOGGLES_KEY by lazy { stringPreferencesKey(name = "featureToggles") }
|
||||||
|
|
||||||
|
val EXCLUDED_BLOCKCHAINS_KEY by lazy { stringSetPreferencesKey(name = "excludedBlockchains") }
|
||||||
|
|
||||||
val WAS_TWINS_ONBOARDING_SHOWN by lazy { booleanPreferencesKey(name = "twinsOnboardingShown") }
|
val WAS_TWINS_ONBOARDING_SHOWN by lazy { booleanPreferencesKey(name = "twinsOnboardingShown") }
|
||||||
|
|
||||||
val IS_TANGEM_TOS_ACCEPTED_KEY by lazy { booleanPreferencesKey(name = "tangem_tos_accepted") }
|
val IS_TANGEM_TOS_ACCEPTED_KEY by lazy { booleanPreferencesKey(name = "tangem_tos_accepted") }
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.tangem.core.featuretoggle.storage
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
import com.squareup.moshi.JsonClass
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data model with information about feature toggle
|
|
||||||
*
|
|
||||||
* @property name feature toggle name
|
|
||||||
* @property version version number in which the feature will be included
|
|
||||||
*
|
|
||||||
* IMPORTANT: if the version is "undefined", it means that feature toggle is disabled!
|
|
||||||
*
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
@JsonClass(generateAdapter = true)
|
|
||||||
internal data class FeatureToggle(
|
|
||||||
@Json(name = "name") val name: String,
|
|
||||||
@Json(name = "version") val version: String,
|
|
||||||
)
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package com.tangem.core.featuretoggle.storage
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component that initializes and stores a list of feature toggles
|
|
||||||
*
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
internal interface FeatureTogglesStorage {
|
|
||||||
|
|
||||||
/** List of feature toggles */
|
|
||||||
val featureToggles: List<FeatureToggle>
|
|
||||||
|
|
||||||
/** Initialize storage */
|
|
||||||
suspend fun init()
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package com.tangem.core.featuretoggle.storage
|
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage.Companion.LOCAL_CONFIG_PATH
|
|
||||||
import com.tangem.datasource.asset.loader.AssetLoader
|
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage implementation for storing local feature toggles.
|
|
||||||
* Feature toggles are declared in file [LOCAL_CONFIG_PATH].
|
|
||||||
*
|
|
||||||
* @property assetLoader asset loader
|
|
||||||
*
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
internal class LocalFeatureTogglesStorage(
|
|
||||||
private val assetLoader: AssetLoader,
|
|
||||||
) : FeatureTogglesStorage {
|
|
||||||
|
|
||||||
override var featureToggles: List<FeatureToggle> by Delegates.notNull()
|
|
||||||
private set
|
|
||||||
|
|
||||||
override suspend fun init() {
|
|
||||||
featureToggles = assetLoader.loadList<FeatureToggle>(LOCAL_CONFIG_PATH)
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
const val LOCAL_CONFIG_PATH: String = "configs/feature_toggles_config"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package com.tangem.core.featuretoggle.utils
|
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.contract.VersionAvailabilityContract
|
|
||||||
import com.tangem.core.featuretoggle.storage.FeatureToggle
|
|
||||||
|
|
||||||
internal fun List<FeatureToggle>.associateToggles(currentVersion: String): Map<String, Boolean> {
|
|
||||||
return associate { localToggle ->
|
|
||||||
Pair(
|
|
||||||
first = localToggle.name,
|
|
||||||
second = VersionAvailabilityContract(currentVersion, localToggle.version),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,7 @@ dependencies {
|
||||||
/* Project - Core */
|
/* Project - Core */
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ dependencies {
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.common.routing)
|
implementation(projects.common.routing)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ dependencies {
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.common.routing)
|
implementation(projects.common.routing)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
|
|
||||||
/* Project - Domain */
|
/* Project - Domain */
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ dependencies {
|
||||||
/* Core */
|
/* Core */
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ dependencies {
|
||||||
implementation(projects.features.manageTokens.api)
|
implementation(projects.features.manageTokens.api)
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.features.onboarding.v2
|
package com.tangem.features.onboarding.v2
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class DefaultOnboardingV2FeatureToggles @Inject constructor(
|
internal class DefaultOnboardingV2FeatureToggles @Inject constructor(
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ dependencies {
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(project(":common"))
|
implementation(project(":common"))
|
||||||
implementation(project(":domain:models"))
|
implementation(project(":domain:models"))
|
||||||
implementation(project(":core:featuretoggles"))
|
implementation(project(":core:config-toggles"))
|
||||||
implementation(project(":core:datasource"))
|
implementation(project(":core:datasource"))
|
||||||
implementation(project(":core:analytics"))
|
implementation(project(":core:analytics"))
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ dependencies {
|
||||||
/** Project - Core */
|
/** Project - Core */
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
|
|
||||||
/** Project - Common */
|
/** Project - Common */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.features.onramp
|
package com.tangem.features.onramp
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
|
|
||||||
internal class DefaultOnrampFeatureToggles(
|
internal class DefaultOnrampFeatureToggles(
|
||||||
private val featureTogglesManager: FeatureTogglesManager,
|
private val featureTogglesManager: FeatureTogglesManager,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.features.onramp
|
package com.tangem.features.onramp
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ dependencies {
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ dependencies {
|
||||||
implementation(deps.tangem.blockchain)
|
implementation(deps.tangem.blockchain)
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ dependencies {
|
||||||
implementation(deps.tangem.blockchain)
|
implementation(deps.tangem.blockchain)
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ dependencies {
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ dependencies {
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.datasource)
|
implementation(projects.core.datasource)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.core.featuretoggle.manager.MutableFeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.MutableFeatureTogglesManager
|
||||||
import com.tangem.core.navigation.finisher.AppFinisher
|
import com.tangem.core.navigation.finisher.AppFinisher
|
||||||
import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
|
import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
|
||||||
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState
|
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ dependencies {
|
||||||
implementation(projects.core.datasource)
|
implementation(projects.core.datasource)
|
||||||
implementation(projects.core.deepLinks)
|
implementation(projects.core.deepLinks)
|
||||||
implementation(projects.core.deepLinks.global)
|
implementation(projects.core.deepLinks.global)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.common.ui)
|
implementation(projects.common.ui)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ dependencies {
|
||||||
/* Project - Core */
|
/* Project - Core */
|
||||||
implementation(projects.core.decompose)
|
implementation(projects.core.decompose)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
implementation(projects.core.analytics.models)
|
implementation(projects.core.analytics.models)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ dependencies {
|
||||||
kapt(deps.hilt.kapt)
|
kapt(deps.hilt.kapt)
|
||||||
|
|
||||||
/** Core modules */
|
/** Core modules */
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.navigation)
|
implementation(projects.core.navigation)
|
||||||
implementation(projects.core.ui)
|
implementation(projects.core.ui)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.feature.wallet.featuretoggles
|
package com.tangem.feature.wallet.featuretoggles
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ dependencies {
|
||||||
|
|
||||||
// region Core modules
|
// region Core modules
|
||||||
implementation(projects.core.datasource)
|
implementation(projects.core.datasource)
|
||||||
implementation(projects.core.featuretoggles)
|
implementation(projects.core.configToggles)
|
||||||
implementation(projects.core.utils)
|
implementation(projects.core.utils)
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import com.tangem.blockchainsdk.datastorage.DefaultBlockchainDataStorage
|
||||||
import com.tangem.blockchainsdk.featuretoggles.DefaultBlockchainSDKFeatureToggles
|
import com.tangem.blockchainsdk.featuretoggles.DefaultBlockchainSDKFeatureToggles
|
||||||
import com.tangem.blockchainsdk.loader.BlockchainProvidersResponseLoader
|
import com.tangem.blockchainsdk.loader.BlockchainProvidersResponseLoader
|
||||||
import com.tangem.blockchainsdk.store.DefaultRuntimeStore
|
import com.tangem.blockchainsdk.store.DefaultRuntimeStore
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.tangem.blockchainsdk.featuretoggles
|
package com.tangem.blockchainsdk.featuretoggles
|
||||||
|
|
||||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
|
|
||||||
internal class DefaultBlockchainSDKFeatureToggles(
|
internal class DefaultBlockchainSDKFeatureToggles(
|
||||||
private val featureTogglesManager: FeatureTogglesManager,
|
private val featureTogglesManager: FeatureTogglesManager,
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ include(":common:routing")
|
||||||
include(":core:analytics")
|
include(":core:analytics")
|
||||||
include(":core:analytics:models")
|
include(":core:analytics:models")
|
||||||
include(":core:datasource")
|
include(":core:datasource")
|
||||||
include(":core:featuretoggles")
|
include(":core:config-toggles")
|
||||||
include(":core:navigation")
|
include(":core:navigation")
|
||||||
include(":core:res")
|
include(":core:res")
|
||||||
include(":core:ui")
|
include(":core:ui")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue