ViewModel refactor so Preview work.
This commit is contained in:
parent
45d2fe1336
commit
903d1973c2
16 changed files with 404 additions and 302 deletions
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue