Separate Hilt and Koin into their own product flavours

This commit is contained in:
Gergely Hegedus 2021-09-18 21:10:35 +03:00
parent 682fd71c2d
commit 1b8d0e836c
56 changed files with 496 additions and 72 deletions

View file

@ -6,24 +6,13 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".TestShowcaseApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".TestShowcaseApplication"
android:theme="@style/Theme.TestShowCase"
tools:ignore="AllowBackup">
<activity android:name=".ui.splash.SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.home.MainActivity"/>
<activity android:name=".ui.auth.AuthActivity"/>
</application>
tools:ignore="AllowBackup"/>
</manifest>

View file

@ -1,18 +0,0 @@
package org.fnives.test.showcase
import android.app.Application
import org.fnives.test.showcase.di.BaseUrlProvider
import org.fnives.test.showcase.di.createAppModules
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
class TestShowcaseApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidContext(this@TestShowcaseApplication)
modules(createAppModules(BaseUrlProvider.get()))
}
}
}

View file

@ -1,55 +0,0 @@
package org.fnives.test.showcase.di
import org.fnives.test.showcase.core.di.createCoreModule
import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.session.SessionExpirationListenerImpl
import org.fnives.test.showcase.storage.LocalDatabase
import org.fnives.test.showcase.storage.SharedPreferencesManagerImpl
import org.fnives.test.showcase.storage.database.DatabaseInitialization
import org.fnives.test.showcase.storage.favourite.FavouriteContentLocalStorageImpl
import org.fnives.test.showcase.ui.auth.AuthViewModel
import org.fnives.test.showcase.ui.home.MainViewModel
import org.fnives.test.showcase.ui.splash.SplashViewModel
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.Module
import org.koin.dsl.module
fun createAppModules(baseUrl: BaseUrl): List<Module> {
return createCoreModule(
baseUrl = baseUrl,
true,
userDataLocalStorageProvider = { get<SharedPreferencesManagerImpl>() },
sessionExpirationListenerProvider = { get<SessionExpirationListenerImpl>() },
favouriteContentLocalStorageProvider = { get<FavouriteContentLocalStorageImpl>() }
)
.plus(storageModule())
.plus(authModule())
.plus(appModule())
.plus(favouriteModule())
.plus(splashModule())
.toList()
}
fun storageModule() = module {
single { SharedPreferencesManagerImpl.create(androidContext()) }
single { DatabaseInitialization.create(androidContext()) }
}
fun authModule() = module {
viewModel { AuthViewModel(get()) }
}
fun appModule() = module {
single { SessionExpirationListenerImpl(androidContext()) }
}
fun splashModule() = module {
viewModel { SplashViewModel(get()) }
}
fun favouriteModule() = module {
single { get<LocalDatabase>().favouriteDao }
viewModel { MainViewModel(get(), get(), get(), get(), get()) }
single { FavouriteContentLocalStorageImpl(get()) }
}

View file

@ -4,15 +4,20 @@ import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import dagger.hilt.android.qualifiers.ApplicationContext
import org.fnives.test.showcase.core.session.SessionExpirationListener
import org.fnives.test.showcase.ui.auth.AuthActivity
import org.fnives.test.showcase.ui.IntentCoordinator
import javax.inject.Inject
class SessionExpirationListenerImpl(private val context: Context) : SessionExpirationListener {
class SessionExpirationListenerImpl @Inject constructor(
@ApplicationContext
private val context: Context
) : SessionExpirationListener {
override fun onSessionExpired() {
Handler(Looper.getMainLooper()).post {
context.startActivity(
AuthActivity.getStartIntent(context)
IntentCoordinator.authActivitygetStartIntent(context)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)

View file

@ -7,7 +7,7 @@ import org.fnives.test.showcase.model.session.Session
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class SharedPreferencesManagerImpl(private val sharedPreferences: SharedPreferences) : UserDataLocalStorage {
class SharedPreferencesManagerImpl constructor(private val sharedPreferences: SharedPreferences) : UserDataLocalStorage {
override var session: Session? by SessionDelegate(SESSION_KEY)

View file

@ -4,8 +4,9 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
import org.fnives.test.showcase.model.content.ContentId
import javax.inject.Inject
class FavouriteContentLocalStorageImpl(private val favouriteDao: FavouriteDao) : FavouriteContentLocalStorage {
class FavouriteContentLocalStorageImpl @Inject constructor(private val favouriteDao: FavouriteDao) : FavouriteContentLocalStorage {
override fun observeFavourites(): Flow<List<ContentId>> =
favouriteDao.get().map { it.map(FavouriteEntity::contentId).map(::ContentId) }

View file

@ -9,12 +9,12 @@ import androidx.core.widget.doAfterTextChanged
import com.google.android.material.snackbar.Snackbar
import org.fnives.test.showcase.R
import org.fnives.test.showcase.databinding.ActivityAuthenticationBinding
import org.fnives.test.showcase.ui.home.MainActivity
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.fnives.test.showcase.ui.IntentCoordinator
import org.fnives.test.showcase.ui.viewModels
class AuthActivity : AppCompatActivity() {
open class AuthActivity : AppCompatActivity() {
private val viewModel by viewModel<AuthViewModel>()
private val viewModel by viewModels<AuthViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -35,7 +35,7 @@ class AuthActivity : AppCompatActivity() {
}
viewModel.navigateToHome.observe(this) {
it.consume() ?: return@observe
startActivity(MainActivity.getStartIntent(this))
startActivity(IntentCoordinator.mainActivitygetStartIntent(this))
finishAffinity()
}
setContentView(binding.root)

View file

@ -4,14 +4,17 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import org.fnives.test.showcase.core.login.LoginUseCase
import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.model.auth.LoginStatus
import org.fnives.test.showcase.model.shared.Answer
import org.fnives.test.showcase.ui.shared.Event
import javax.inject.Inject
class AuthViewModel(private val loginUseCase: LoginUseCase) : ViewModel() {
@HiltViewModel
class AuthViewModel @Inject constructor(private val loginUseCase: LoginUseCase) : ViewModel() {
private val _username = MutableLiveData<String>()
val username: LiveData<String> = _username

View file

@ -6,17 +6,18 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import org.fnives.test.showcase.R
import org.fnives.test.showcase.databinding.ActivityMainBinding
import org.fnives.test.showcase.model.content.ContentId
import org.fnives.test.showcase.ui.auth.AuthActivity
import org.fnives.test.showcase.ui.IntentCoordinator
import org.fnives.test.showcase.ui.shared.VerticalSpaceItemDecoration
import org.fnives.test.showcase.ui.shared.getThemePrimaryColor
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.fnives.test.showcase.ui.viewModels
class MainActivity : AppCompatActivity() {
open class MainActivity : AppCompatActivity() {
private val viewModel by viewModel<MainViewModel>()
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -45,7 +46,7 @@ class MainActivity : AppCompatActivity() {
}
viewModel.navigateToAuth.observe(this) {
it.consume() ?: return@observe
startActivity(AuthActivity.getStartIntent(this))
startActivity(IntentCoordinator.authActivitygetStartIntent(this))
finishAffinity()
}
viewModel.loading.observe(this) {

View file

@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.fnives.test.showcase.core.content.AddContentToFavouriteUseCase
@ -16,8 +17,10 @@ import org.fnives.test.showcase.model.content.ContentId
import org.fnives.test.showcase.model.content.FavouriteContent
import org.fnives.test.showcase.model.shared.Resource
import org.fnives.test.showcase.ui.shared.Event
import javax.inject.Inject
class MainViewModel(
@HiltViewModel
class MainViewModel @Inject constructor(
private val getAllContentUseCase: GetAllContentUseCase,
private val logoutUseCase: LogoutUseCase,
private val fetchContentUseCase: FetchContentUseCase,

View file

@ -3,21 +3,20 @@ package org.fnives.test.showcase.ui.splash
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.fnives.test.showcase.R
import org.fnives.test.showcase.ui.auth.AuthActivity
import org.fnives.test.showcase.ui.home.MainActivity
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.fnives.test.showcase.ui.IntentCoordinator
import org.fnives.test.showcase.ui.viewModels
class SplashActivity : AppCompatActivity() {
open class SplashActivity : AppCompatActivity() {
private val viewModel by viewModel<SplashViewModel>()
private val viewModel by viewModels<SplashViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
viewModel.navigateTo.observe(this) {
val intent = when (it.consume()) {
SplashViewModel.NavigateTo.HOME -> MainActivity.getStartIntent(this)
SplashViewModel.NavigateTo.AUTHENTICATION -> AuthActivity.getStartIntent(this)
SplashViewModel.NavigateTo.HOME -> IntentCoordinator.mainActivitygetStartIntent(this)
SplashViewModel.NavigateTo.AUTHENTICATION -> IntentCoordinator.authActivitygetStartIntent(this)
null -> return@observe
}
startActivity(intent)

View file

@ -4,12 +4,15 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
import org.fnives.test.showcase.ui.shared.Event
import javax.inject.Inject
class SplashViewModel(isUserLoggedInUseCase: IsUserLoggedInUseCase) : ViewModel() {
@HiltViewModel
class SplashViewModel @Inject constructor(isUserLoggedInUseCase: IsUserLoggedInUseCase) : ViewModel() {
private val _navigateTo = MutableLiveData<Event<NavigateTo>>()
val navigateTo: LiveData<Event<NavigateTo>> = _navigateTo