Updated on 2026-08-14
This commit is contained in:
parent
946d60c1c6
commit
11ad540d12
14 changed files with 77 additions and 126 deletions
|
|
@ -33,7 +33,6 @@ dependencies {
|
|||
implementation(deps.timber)
|
||||
|
||||
/** Network */
|
||||
implementation(deps.krateSharedPref)
|
||||
implementation(deps.moshi)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.okHttp)
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.AppPreferenceStorage
|
||||
import com.tangem.datasource.local.AppPreferenceStorageImpl
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface AppPreferenceStorageModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindAppPreferenceStorage(appPreferenceStorageImpl: AppPreferenceStorageImpl): AppPreferenceStorage
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package com.tangem.datasource.local
|
||||
|
||||
/**
|
||||
* Application local storage
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Deprecated(message = "Use AppPreferencesStore", level = DeprecationLevel.WARNING)
|
||||
interface AppPreferenceStorage {
|
||||
|
||||
/** Json config with feature toggles 'ToggleName: String - Availability: Boolean' */
|
||||
var featureToggles: String
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package com.tangem.datasource.local
|
||||
|
||||
import android.content.Context
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import hu.autsoft.krate.SimpleKrate
|
||||
import hu.autsoft.krate.default.withDefault
|
||||
import hu.autsoft.krate.stringPref
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Implementation of application local storage
|
||||
*
|
||||
* @param context application context
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Singleton
|
||||
internal class AppPreferenceStorageImpl @Inject constructor(
|
||||
@ApplicationContext context: Context,
|
||||
) : SimpleKrate(context = context), AppPreferenceStorage {
|
||||
|
||||
override var featureToggles: String by stringPref().withDefault("")
|
||||
}
|
||||
|
|
@ -48,6 +48,8 @@ object PreferencesKeys {
|
|||
val IS_WALLET_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isWalletSwapPromoShown") }
|
||||
|
||||
val IS_TOKEN_SWAP_PROMO_SHOW_KEY by lazy { booleanPreferencesKey(name = "isTokenSwapPromoShown") }
|
||||
|
||||
val FEATURE_TOGGLES_KEY by lazy { stringPreferencesKey(name = "featureToggles") }
|
||||
}
|
||||
|
||||
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
||||
|
|
|
|||
|
|
@ -7,14 +7,22 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core:datasource"))
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
|
||||
/** Local storages */
|
||||
implementation(deps.androidx.datastore)
|
||||
|
||||
/** Other libraries */
|
||||
implementation(deps.moshi)
|
||||
implementation(deps.moshi.kotlin)
|
||||
implementation(deps.timber)
|
||||
|
||||
/** Core modules */
|
||||
implementation(projects.core.datasource)
|
||||
|
||||
testImplementation(deps.test.coroutine)
|
||||
testImplementation(deps.test.junit)
|
||||
testImplementation(deps.test.mockk)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import com.tangem.core.featuretoggle.storage.LocalFeatureTogglesStorage
|
|||
import com.tangem.core.featuretoggle.version.DefaultVersionProvider
|
||||
import com.tangem.core.featuretoggles.BuildConfig
|
||||
import com.tangem.datasource.asset.AssetReader
|
||||
import com.tangem.datasource.local.AppPreferenceStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -29,7 +29,7 @@ internal object FeatureTogglesManagerModule {
|
|||
fun provideFeatureTogglesManager(
|
||||
@ApplicationContext context: Context,
|
||||
assetReader: AssetReader,
|
||||
appPreferenceStorage: AppPreferenceStorage,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
): FeatureTogglesManager {
|
||||
val moshi = Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
|
||||
val localFeatureTogglesStorage = LocalFeatureTogglesStorage(
|
||||
|
|
@ -41,8 +41,7 @@ internal object FeatureTogglesManagerModule {
|
|||
return if (BuildConfig.TESTER_MENU_ENABLED) {
|
||||
DevFeatureTogglesManager(
|
||||
localFeatureTogglesStorage = localFeatureTogglesStorage,
|
||||
appPreferenceStorage = appPreferenceStorage,
|
||||
jsonAdapter = moshi.adapter(),
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
versionProvider = versionProvider,
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
package com.tangem.core.featuretoggle.manager
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
||||
import com.tangem.datasource.local.AppPreferenceStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* Feature toggles manager implementation in DEV build
|
||||
*
|
||||
* @property localFeatureTogglesStorage local feature toggles storage
|
||||
* @property appPreferenceStorage application local storage
|
||||
* @property jsonAdapter adapter for parsing json
|
||||
* @property appPreferencesStore application local store
|
||||
* @property versionProvider application version provider
|
||||
*/
|
||||
internal class DevFeatureTogglesManager(
|
||||
private val localFeatureTogglesStorage: FeatureTogglesStorage,
|
||||
private val appPreferenceStorage: AppPreferenceStorage,
|
||||
private val jsonAdapter: JsonAdapter<Map<String, Boolean>>,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val versionProvider: VersionProvider,
|
||||
) : MutableFeatureTogglesManager {
|
||||
|
||||
|
|
@ -28,11 +28,9 @@ internal class DevFeatureTogglesManager(
|
|||
override suspend fun init() {
|
||||
localFeatureTogglesStorage.init()
|
||||
|
||||
val savedFeatureToggles = if (appPreferenceStorage.featureToggles.isNotEmpty()) {
|
||||
jsonAdapter.fromJson(appPreferenceStorage.featureToggles).orEmpty()
|
||||
} else {
|
||||
emptyMap()
|
||||
}
|
||||
val savedFeatureToggles = appPreferencesStore.getObjectSyncOrNull<Map<String, Boolean>>(
|
||||
key = PreferencesKeys.FEATURE_TOGGLES_KEY,
|
||||
) ?: emptyMap()
|
||||
|
||||
featureTogglesMap = localFeatureTogglesStorage.featureToggles
|
||||
.associateToggles(currentVersion = versionProvider.get().orEmpty())
|
||||
|
|
@ -46,10 +44,10 @@ internal class DevFeatureTogglesManager(
|
|||
|
||||
override fun getFeatureToggles(): Map<String, Boolean> = featureTogglesMap
|
||||
|
||||
override fun changeToggle(name: String, isEnabled: Boolean) {
|
||||
override suspend fun changeToggle(name: String, isEnabled: Boolean) {
|
||||
featureTogglesMap[name] ?: return
|
||||
featureTogglesMap[name] = isEnabled
|
||||
appPreferenceStorage.featureToggles = jsonAdapter.toJson(featureTogglesMap)
|
||||
appPreferencesStore.storeObject(PreferencesKeys.FEATURE_TOGGLES_KEY, featureTogglesMap)
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ interface MutableFeatureTogglesManager : FeatureTogglesManager {
|
|||
fun getFeatureToggles(): Map<String, Boolean>
|
||||
|
||||
/** Change availability [isEnabled] of toggle with name [name] */
|
||||
fun changeToggle(name: String, isEnabled: Boolean)
|
||||
suspend fun changeToggle(name: String, isEnabled: Boolean)
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.core.featuretoggle.storage
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Data model with information about feature toggle
|
||||
*
|
||||
|
|
@ -10,4 +13,8 @@ package com.tangem.core.featuretoggle.storage
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal data class FeatureToggle(val name: String, val version: String)
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class FeatureToggle(
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "version") val version: String,
|
||||
)
|
||||
|
|
@ -2,48 +2,42 @@ package com.tangem.core.featuretoggle.manager
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import com.google.common.truth.Truth
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.core.featuretoggle.storage.FeatureToggle
|
||||
import com.tangem.core.featuretoggle.storage.FeatureTogglesStorage
|
||||
import com.tangem.core.featuretoggle.utils.associateToggles
|
||||
import com.tangem.core.featuretoggle.version.VersionProvider
|
||||
import com.tangem.datasource.local.AppPreferenceStorage
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerifyOrder
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verifyAll
|
||||
import io.mockk.verifyOrder
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrNull
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import kotlin.collections.set
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SuppressLint("CheckResult")
|
||||
internal class DevFeatureTogglesManagerTest {
|
||||
|
||||
private val localFeatureTogglesStorage = mockk<FeatureTogglesStorage>()
|
||||
private val appPreferenceStorage = mockk<AppPreferenceStorage>(relaxed = true)
|
||||
private val jsonAdapter = mockk<JsonAdapter<Map<String, Boolean>>>()
|
||||
private val appPreferenceStore = mockk<AppPreferencesStore>(relaxed = true)
|
||||
private val versionProvider = mockk<VersionProvider>()
|
||||
private val manager = DevFeatureTogglesManager(
|
||||
localFeatureTogglesStorage = localFeatureTogglesStorage,
|
||||
appPreferenceStorage = appPreferenceStorage,
|
||||
jsonAdapter = jsonAdapter,
|
||||
appPreferencesStore = appPreferenceStore,
|
||||
versionProvider = versionProvider,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `successfully initialize storage if shared prefs kept feature toggles`() = runTest {
|
||||
val currentVersion = "1.0.0"
|
||||
val currentVersion = "0.1.0"
|
||||
|
||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
||||
coEvery { appPreferenceStorage.featureToggles } returns savedFeatureToggles
|
||||
coEvery { jsonAdapter.fromJson(savedFeatureToggles) } returns savedFeatureTogglesMap
|
||||
coEvery {
|
||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||
} returns savedFeatureTogglesMap
|
||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
||||
coEvery { versionProvider.get() } returns currentVersion
|
||||
|
||||
|
|
@ -51,7 +45,6 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
coVerifyOrder {
|
||||
localFeatureTogglesStorage.init()
|
||||
jsonAdapter.fromJson(savedFeatureToggles)
|
||||
versionProvider.get()
|
||||
}
|
||||
|
||||
|
|
@ -66,12 +59,12 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
@Test
|
||||
fun `successfully initialize storage if shared prefs kept empty list`() = runTest {
|
||||
val currentVersion = "1.0.0"
|
||||
val sharedPrefFeatureToggles = "[]"
|
||||
val currentVersion = "0.1.0"
|
||||
|
||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
||||
coEvery { appPreferenceStorage.featureToggles } returns sharedPrefFeatureToggles
|
||||
coEvery { jsonAdapter.fromJson(sharedPrefFeatureToggles) } returns savedFeatureTogglesMap
|
||||
coEvery {
|
||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||
} returns emptyMap()
|
||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
||||
coEvery { versionProvider.get() } returns currentVersion
|
||||
|
||||
|
|
@ -79,7 +72,6 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
coVerifyOrder {
|
||||
localFeatureTogglesStorage.init()
|
||||
jsonAdapter.fromJson(sharedPrefFeatureToggles)
|
||||
versionProvider.get()
|
||||
}
|
||||
|
||||
|
|
@ -94,10 +86,12 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
@Test
|
||||
fun `successfully initialize storage if shared prefs didn't keep feature toggles`() = runTest {
|
||||
val currentVersion = "1.0.0"
|
||||
val currentVersion = "0.1.0"
|
||||
|
||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
||||
coEvery { appPreferenceStorage.featureToggles } returns ""
|
||||
coEvery {
|
||||
appPreferenceStore.getObjectSyncOrNull<Map<String, Boolean>>(PreferencesKeys.FEATURE_TOGGLES_KEY)
|
||||
} returns null
|
||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
||||
coEvery { versionProvider.get() } returns currentVersion
|
||||
|
||||
|
|
@ -107,7 +101,6 @@ internal class DevFeatureTogglesManagerTest {
|
|||
localFeatureTogglesStorage.init()
|
||||
versionProvider.get()
|
||||
}
|
||||
verifyAll(inverse = true) { jsonAdapter.fromJson(any<String>()) }
|
||||
|
||||
val expected = localFeatureToggles
|
||||
.associateToggles(currentVersion)
|
||||
|
|
@ -119,8 +112,7 @@ internal class DevFeatureTogglesManagerTest {
|
|||
@Test
|
||||
fun `successfully initialize storage if versionProvider returns null`() = runTest {
|
||||
coEvery { localFeatureTogglesStorage.init() } just Runs
|
||||
coEvery { appPreferenceStorage.featureToggles } returns savedFeatureToggles
|
||||
coEvery { jsonAdapter.fromJson(savedFeatureToggles) } returns savedFeatureTogglesMap
|
||||
coEvery { appPreferenceStore.getSyncOrNull(PreferencesKeys.FEATURE_TOGGLES_KEY) } returns savedFeatureToggles
|
||||
coEvery { localFeatureTogglesStorage.featureToggles } returns localFeatureToggles
|
||||
coEvery { versionProvider.get() } returns null
|
||||
|
||||
|
|
@ -128,7 +120,6 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
coVerifyOrder {
|
||||
localFeatureTogglesStorage.init()
|
||||
jsonAdapter.fromJson(savedFeatureToggles)
|
||||
versionProvider.get()
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +171,7 @@ internal class DevFeatureTogglesManagerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `change toggle that contains in map`() {
|
||||
fun `change toggle that contains in map`() = runTest {
|
||||
val changeableToggleName = "INACTIVE_TEST_FEATURE_ENABLED"
|
||||
val resultMap = mutableMapOf(
|
||||
changeableToggleName to false,
|
||||
|
|
@ -188,18 +179,16 @@ internal class DevFeatureTogglesManagerTest {
|
|||
)
|
||||
|
||||
manager.setFeatureToggles(resultMap)
|
||||
coEvery { jsonAdapter.toJson(resultMap) } returns ""
|
||||
|
||||
manager.changeToggle(changeableToggleName, true)
|
||||
|
||||
resultMap[changeableToggleName] = true
|
||||
verifyOrder { jsonAdapter.toJson(resultMap) }
|
||||
|
||||
Truth.assertThat(manager.getFeatureToggles()).containsExactlyEntriesIn(resultMap)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `change toggle that doesn't contains in map`() {
|
||||
fun `change toggle that doesn't contains in map`() = runTest {
|
||||
val resultMap = mutableMapOf(
|
||||
"INACTIVE_TEST_FEATURE_ENABLED" to false,
|
||||
"ACTIVE2_TEST_FEATURE_ENABLED" to false,
|
||||
|
|
@ -209,8 +198,6 @@ internal class DevFeatureTogglesManagerTest {
|
|||
|
||||
manager.changeToggle("FEATURE_TOGGLE", true)
|
||||
|
||||
verifyAll(inverse = true) { jsonAdapter.toJson(any()) }
|
||||
|
||||
Truth.assertThat(manager.getFeatureToggles()).containsExactlyEntriesIn(resultMap)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,17 +27,18 @@ dependencies {
|
|||
implementation(projects.domain.appTheme)
|
||||
implementation(projects.domain.appTheme.models)
|
||||
|
||||
/** Core modules */
|
||||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:ui"))
|
||||
|
||||
/** Feature Apis */
|
||||
implementation(project(":features:tester:api"))
|
||||
|
||||
/** Other modules */
|
||||
implementation(project(":libs:crypto"))
|
||||
|
||||
/** Other libraries */
|
||||
implementation(deps.arrow.core)
|
||||
implementation(deps.timber)
|
||||
|
||||
/** Core modules */
|
||||
implementation(projects.core.featuretoggles)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.utils)
|
||||
|
||||
/** Feature Apis */
|
||||
implementation(projects.features.tester.api)
|
||||
|
||||
/** Other modules */
|
||||
implementation(projects.libs.crypto)
|
||||
}
|
||||
|
|
@ -4,24 +4,29 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.core.featuretoggle.manager.MutableFeatureTogglesManager
|
||||
import com.tangem.feature.tester.presentation.featuretoggles.models.TesterFeatureToggle
|
||||
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesContentState
|
||||
import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* ViewModel for screen with list of feature toggles
|
||||
*
|
||||
* @property featureTogglesManager manager for getting information about the availability of feature toggles
|
||||
* @property dispatchers coroutine dispatchers provider
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@HiltViewModel
|
||||
internal class FeatureTogglesViewModel @Inject constructor(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ViewModel() {
|
||||
|
||||
/** Current ui state */
|
||||
|
|
@ -47,9 +52,11 @@ internal class FeatureTogglesViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onToggleValueChange(name: String, isEnabled: Boolean) {
|
||||
mutableFeatureTogglesManager.changeToggle(name = name, isEnabled = isEnabled)
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
mutableFeatureTogglesManager.changeToggle(name = name, isEnabled = isEnabled)
|
||||
|
||||
uiState = uiState.copy(featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles())
|
||||
uiState = uiState.copy(featureToggles = mutableFeatureTogglesManager.getTesterFeatureToggles())
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableFeatureTogglesManager.getTesterFeatureToggles(): List<TesterFeatureToggle> {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ googlePlayServicesWallet = "19.1.0"
|
|||
hilt = "2.44"
|
||||
hilt-navigation = "1.0.0"
|
||||
jodatime = "2.12.1"
|
||||
krateSharedPref = "2.0.0"
|
||||
kotlin-immutable-collections = "0.3.5"
|
||||
kotsonGsonExt = "2.5.0"
|
||||
lottie = "3.4.0"
|
||||
|
|
@ -206,7 +205,6 @@ hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "hilt" }
|
|||
hilt-kapt = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
||||
hilt-navigation = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
||||
jodatime = { module = "joda-time:joda-time", version.ref = "jodatime" }
|
||||
krateSharedPref = { module = "hu.autsoft:krate", version.ref = "krateSharedPref" }
|
||||
kotsonGson = { module = "com.github.salomonbrys.kotson:kotson", version.ref = "kotsonGsonExt" }
|
||||
lottie = { module = "com.airbnb.android:lottie", version.ref = "lottie" }
|
||||
material = { module = "com.google.android.material:material", version.ref = "googleMaterialComponent" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue