ViewModel refactor so Preview work.

This commit is contained in:
Thomas Andres Gomez 2021-05-08 15:33:24 +02:00
parent 45d2fe1336
commit 903d1973c2
16 changed files with 404 additions and 302 deletions

View file

@ -1,53 +0,0 @@
package com.pixelized.biblib.ui.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.biblib.data.ui.BookUio
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.*
class NavigationViewModel : ViewModel() {
private val stack = Stack<Page>()
private val _screen = MutableLiveData<Screen>(Screen.SplashScreen)
val screen: LiveData<Screen> get() = _screen
private val _page = MutableLiveData<Page>(Page.HomePage)
val page: LiveData<Page> get() = _page
fun navigateTo(screen: Screen): Boolean {
_screen.postValue(screen)
return true
}
fun navigateTo(page: Page): Boolean {
_page.postValue(page)
stack.push(page)
return true
}
fun navigateBack() : Boolean {
stack.pop()
return if (stack.empty()) {
false
} else {
_page.postValue(stack.peek())
true
}
}
sealed class Screen {
object SplashScreen : Screen()
object MainScreen : Screen()
object LoginScreen : Screen()
}
sealed class Page {
object HomePage : Page()
data class Detail(val book: BookUio) : Page()
}
}

View file

@ -1,32 +1,48 @@
package com.pixelized.biblib.ui.viewmodel
package com.pixelized.biblib.ui.viewmodel.authentication
import android.content.Intent
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.Composable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.common.api.ApiException
import com.pixelized.biblib.data.network.query.AuthLoginQuery
import com.pixelized.biblib.injection.inject
import com.pixelized.biblib.network.client.IBibLibClient
import com.pixelized.biblib.repository.credential.ICredentialRepository
import com.pixelized.biblib.repository.googlesignin.IGoogleSingInRepository
import com.pixelized.biblib.ui.viewmodel.authentication.IAuthentication.State
import com.pixelized.biblib.utils.exception.MissingTokenException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class AuthenticationViewModel : ViewModel() {
class AuthenticationViewModel : ViewModel(), IAuthentication {
private val credentialRepository: ICredentialRepository by inject()
private val googleSignIn: IGoogleSingInRepository by inject()
private val client: IBibLibClient by inject()
private var launcher: ActivityResultLauncher<Intent>? = null
private val _state = MutableLiveData<State>(State.Initial)
override val state: LiveData<State> get() = _state
private val _login = MutableLiveData<String>()
val login: LiveData<String> get() = _login
override val login: LiveData<String?> get() = _login
private val _password = MutableLiveData<String>()
val password: LiveData<String> get() = _password
override val password: LiveData<String?> get() = _password
private val _rememberCredential = MutableLiveData<Boolean>()
val rememberCredential: LiveData<Boolean> get() = _rememberCredential
override val rememberCredential: LiveData<Boolean> get() = _rememberCredential
init {
viewModelScope.launch(Dispatchers.Main) {
@ -36,15 +52,15 @@ class AuthenticationViewModel : ViewModel() {
}
}
fun updateLoginField(login: String) {
override fun updateLoginField(login: String) {
_login.postValue(login)
}
fun updatePasswordField(password: String) {
override fun updatePasswordField(password: String) {
_password.postValue(password)
}
fun updateRememberCredential(rememberCredential: Boolean) {
override fun updateRememberCredential(rememberCredential: Boolean) {
_rememberCredential.postValue(rememberCredential)
viewModelScope.launch {
credentialRepository.rememberCredential = rememberCredential
@ -55,11 +71,15 @@ class AuthenticationViewModel : ViewModel() {
}
}
fun register() {
override fun register() {
viewModelScope.launch {
_state.postValue(State.Loading)
delay(3000)
_state.postValue(State.Initial)
}
}
fun login() {
override fun login() {
viewModelScope.launch(Dispatchers.IO) {
if (rememberCredential.value == true) {
credentialRepository.login = login.value
@ -77,11 +97,25 @@ class AuthenticationViewModel : ViewModel() {
}
@Composable
fun prepareLoginWithGoogle(): IGoogleSingInRepository.Request =
googleSignIn.prepareLoginWithGoogle()
override fun PrepareLoginWithGoogle() {
launcher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
try {
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
val account: GoogleSignInAccount? = task.getResult(ApiException::class.java)
val idToken = account?.idToken ?: throw MissingTokenException()
_state.postValue(State.Connect(idToken))
} catch (exception: Exception) {
_state.postValue(State.Error(exception))
}
}
}
fun loginWithGoogle(request: IGoogleSingInRepository.Request) =
googleSignIn.loginWithGoogle(request)
override fun loginWithGoogle() {
_state.postValue(State.Loading)
launcher?.launch(googleSignIn.client.signInIntent)
}
companion object {
const val SHARED_PREF = "BIB_LIB_SHARED_PREF"

View file

@ -0,0 +1,48 @@
package com.pixelized.biblib.ui.viewmodel.authentication
import androidx.compose.runtime.Composable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
interface IAuthentication {
val state: LiveData<State>
val login: LiveData<String?>
val password: LiveData<String?>
val rememberCredential: LiveData<Boolean>
fun updateLoginField(login: String)
fun updatePasswordField(password: String)
fun updateRememberCredential(rememberCredential: Boolean)
fun register()
fun login()
@Composable
fun PrepareLoginWithGoogle()
fun loginWithGoogle()
sealed class State {
object Initial : State()
object Loading : State()
data class Connect(val token: String) : State()
data class Error(val exception: Exception) : State()
}
class Mock(waiting: Boolean = false) : IAuthentication {
override val state: LiveData<State> =
MutableLiveData(if (waiting) State.Loading else State.Initial)
override val login: LiveData<String?> = MutableLiveData("")
override val password: LiveData<String?> = MutableLiveData("")
override val rememberCredential: LiveData<Boolean> = MutableLiveData(true)
override fun updateLoginField(login: String) = Unit
override fun updatePasswordField(password: String) = Unit
override fun updateRememberCredential(rememberCredential: Boolean) = Unit
override fun register() = Unit
override fun login() = Unit
@Composable
override fun PrepareLoginWithGoogle() = Unit
override fun loginWithGoogle() = Unit
}
}

View file

@ -0,0 +1,35 @@
package com.pixelized.biblib.ui.viewmodel.navigation
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.pixelized.biblib.data.ui.BookUio
interface INavigation {
val screen: LiveData<Screen>
val page: LiveData<Page>
fun navigateTo(screen: Screen): Boolean
fun navigateTo(page: Page): Boolean
fun navigateBack(): Boolean
sealed class Screen {
object SplashScreen : Screen()
object MainScreen : Screen()
object LoginScreen : Screen()
}
sealed class Page {
object HomePage : Page()
data class Detail(val book: BookUio) : Page()
}
class Mock(screen: Screen = Screen.SplashScreen, page: Page = Page.HomePage) : INavigation {
override val screen: LiveData<Screen> = MutableLiveData(screen)
override val page: LiveData<Page> = MutableLiveData(page)
override fun navigateTo(screen: Screen): Boolean = false
override fun navigateTo(page: Page): Boolean = false
override fun navigateBack(): Boolean = false
}
}

View file

@ -0,0 +1,41 @@
package com.pixelized.biblib.ui.viewmodel.navigation
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.pixelized.biblib.ui.viewmodel.navigation.INavigation
import com.pixelized.biblib.ui.viewmodel.navigation.INavigation.Page
import com.pixelized.biblib.ui.viewmodel.navigation.INavigation.Screen
import java.util.*
class NavigationViewModel : ViewModel(), INavigation {
private val stack = Stack<Page>()
private val _screen = MutableLiveData<Screen>(Screen.SplashScreen)
override val screen: LiveData<Screen> get() = _screen
private val _page = MutableLiveData<Page>(Page.HomePage)
override val page: LiveData<Page> get() = _page
override fun navigateTo(screen: Screen): Boolean {
_screen.postValue(screen)
return true
}
override fun navigateTo(page: Page): Boolean {
_page.postValue(page)
stack.push(page)
return true
}
override fun navigateBack(): Boolean {
stack.pop()
return if (stack.empty()) {
false
} else {
_page.postValue(stack.peek())
true
}
}
}