diff --git a/app/src/main/java/com/aurora/store/data/model/State.kt b/app/src/main/java/com/aurora/store/data/model/State.kt index 219d97342..bca70557a 100644 --- a/app/src/main/java/com/aurora/store/data/model/State.kt +++ b/app/src/main/java/com/aurora/store/data/model/State.kt @@ -33,6 +33,7 @@ sealed class ViewState { } sealed class AuthState { + data object Init: AuthState() data object Available : AuthState() data object Unavailable : AuthState() data object SignedIn : AuthState() diff --git a/app/src/main/java/com/aurora/store/view/ui/splash/SplashFragment.kt b/app/src/main/java/com/aurora/store/view/ui/splash/SplashFragment.kt index 601d69ead..acc1db20d 100644 --- a/app/src/main/java/com/aurora/store/view/ui/splash/SplashFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/splash/SplashFragment.kt @@ -24,6 +24,7 @@ import android.net.UrlQuerySanitizer import android.os.Bundle import android.view.View import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import com.aurora.extensions.hide import com.aurora.extensions.show @@ -36,6 +37,8 @@ import com.aurora.store.util.Preferences.PREFERENCE_INTRO import com.aurora.store.view.ui.commons.BaseFragment import com.aurora.store.viewmodel.auth.AuthViewModel import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch @AndroidEntryPoint class SplashFragment : BaseFragment() { @@ -83,72 +86,70 @@ class SplashFragment : BaseFragment() { binding.btnAnonymous.visibility = View.VISIBLE } - //Initial status - updateStatus(getString(R.string.session_init)) + viewLifecycleOwner.lifecycleScope.launch { + viewModel.authState.collectLatest { + when (it) { + AuthState.Init -> updateStatus(getString(R.string.session_init)) - viewModel.liveData.observe(viewLifecycleOwner) { - when (it) { - AuthState.Fetching -> { - updateStatus(getString(R.string.requesting_new_session)) - } - - AuthState.Valid -> { - val packageName = getPackageName() - if (packageName.isBlank()) { - navigateToDefaultTab() - } else { - requireArguments().remove("packageName") - findNavController().navigate( - SplashFragmentDirections.actionSplashFragmentToAppDetailsFragment( - packageName - ) - ) + AuthState.Fetching -> { + updateStatus(getString(R.string.requesting_new_session)) } - } - AuthState.Available -> { - updateStatus(getString(R.string.session_verifying)) - updateActionLayout(false) - } - - AuthState.Unavailable -> { - updateStatus(getString(R.string.session_login)) - updateActionLayout(true) - } - - AuthState.SignedIn -> { - val packageName = getPackageName() - if (packageName.isBlank()) { - navigateToDefaultTab() - } else { - requireArguments().remove("packageName") - findNavController().navigate( - SplashFragmentDirections.actionSplashFragmentToAppDetailsFragment( - packageName + AuthState.Valid -> { + val packageName = getPackageName() + if (packageName.isBlank()) { + navigateToDefaultTab() + } else { + requireArguments().remove("packageName") + findNavController().navigate( + SplashFragmentDirections.actionSplashFragmentToAppDetailsFragment( + packageName + ) ) - ) + } } - } - AuthState.SignedOut -> { - updateStatus(getString(R.string.session_scrapped)) - updateActionLayout(true) - } + AuthState.Available -> { + updateStatus(getString(R.string.session_verifying)) + updateActionLayout(false) + } - AuthState.Verifying -> { - updateStatus(getString(R.string.verifying_new_session)) - } + AuthState.Unavailable -> { + updateStatus(getString(R.string.session_login)) + updateActionLayout(true) + } - is AuthState.Failed -> { - updateStatus(it.status) - updateActionLayout(true) - resetActions() + AuthState.SignedIn -> { + val packageName = getPackageName() + if (packageName.isBlank()) { + navigateToDefaultTab() + } else { + requireArguments().remove("packageName") + findNavController().navigate( + SplashFragmentDirections.actionSplashFragmentToAppDetailsFragment( + packageName + ) + ) + } + } + + AuthState.SignedOut -> { + updateStatus(getString(R.string.session_scrapped)) + updateActionLayout(true) + } + + AuthState.Verifying -> { + updateStatus(getString(R.string.verifying_new_session)) + } + + is AuthState.Failed -> { + updateStatus(it.status) + updateActionLayout(true) + resetActions() + } } } } - - // Check authentication status - viewModel.observe() } private fun updateStatus(string: String?) { @@ -167,14 +168,14 @@ class SplashFragment : BaseFragment() { private fun attachActions() { binding.btnAnonymous.addOnClickListener { - if (viewModel.liveData.value != AuthState.Fetching) { + if (viewModel.authState.value != AuthState.Fetching) { binding.btnAnonymous.updateProgress(true) viewModel.buildAnonymousAuthData() } } binding.btnGoogle.addOnClickListener { - if (viewModel.liveData.value != AuthState.Fetching) { + if (viewModel.authState.value != AuthState.Fetching) { binding.btnGoogle.updateProgress(true) findNavController().navigate(R.id.googleFragment) } diff --git a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt index 1a1c49abc..bbde0a9cc 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt @@ -22,7 +22,6 @@ package com.aurora.store.viewmodel.auth import android.annotation.SuppressLint import android.content.Context import android.util.Log -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.aurora.Constants @@ -40,6 +39,8 @@ import com.aurora.store.util.Preferences import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import java.net.ConnectException import java.net.UnknownHostException @@ -55,21 +56,15 @@ class AuthViewModel @Inject constructor( private val TAG = AuthViewModel::class.java.simpleName - val liveData: MutableLiveData = MutableLiveData() + private val _authState: MutableStateFlow = MutableStateFlow(AuthState.Init) + val authState = _authState.asStateFlow() - fun observe() { - if (liveData.value != AuthState.Fetching) { - if (AccountProvider.isLoggedIn(context)) { - liveData.postValue(AuthState.Available) - buildSavedAuthData() - } else { - liveData.postValue(AuthState.Unavailable) - } - } + init { + updateAuthState() } fun buildGoogleAuthData(email: String, token: String, tokenType: AuthHelper.Token) { - liveData.postValue(AuthState.Fetching) + _authState.value = AuthState.Fetching viewModelScope.launch(Dispatchers.IO) { try { verifyAndSaveAuth( @@ -77,16 +72,15 @@ class AuthViewModel @Inject constructor( AccountType.GOOGLE ) } catch (exception: Exception) { - liveData.postValue( + _authState.value = AuthState.Failed(context.getString(R.string.failed_to_generate_session)) - ) Log.e(TAG, "Failed to generate Session", exception) } } } fun buildAnonymousAuthData() { - liveData.postValue(AuthState.Fetching) + _authState.value = AuthState.Fetching viewModelScope.launch(Dispatchers.IO) { try { verifyAndSaveAuth( @@ -95,7 +89,7 @@ class AuthViewModel @Inject constructor( ) } catch (exception: Exception) { Log.e(TAG, "Failed to generate Session", exception) - liveData.postValue(AuthState.Failed(exception.message.toString())) + _authState.value = AuthState.Failed(exception.message.toString()) } } } @@ -125,11 +119,22 @@ class AuthViewModel @Inject constructor( } } + private fun updateAuthState() { + if (_authState.value != AuthState.Fetching) { + if (AccountProvider.isLoggedIn(context)) { + _authState.value = AuthState.Available + buildSavedAuthData() + } else { + _authState.value = AuthState.Unavailable + } + } + } + private fun buildSavedAuthData() { viewModelScope.launch(Dispatchers.IO) { try { if (authProvider.isSavedAuthDataValid()) { - liveData.postValue(AuthState.Valid) + _authState.value = AuthState.Valid } else { // Generate and validate new auth when (AccountProvider.getAccountType(context)) { @@ -152,13 +157,13 @@ class AuthViewModel @Inject constructor( is ConnectException -> context.getString(R.string.server_unreachable) else -> context.getString(R.string.bad_request) } - liveData.postValue(AuthState.Failed(error)) + _authState.value = AuthState.Failed(error) } } } private fun verifyAndSaveAuth(authData: AuthData, accountType: AccountType) { - liveData.postValue(AuthState.Verifying) + _authState.value = AuthState.Verifying if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) { authProvider.saveAuthData(authData) AccountProvider.login( @@ -168,13 +173,12 @@ class AuthViewModel @Inject constructor( if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS, accountType ) - liveData.postValue(AuthState.SignedIn) + _authState.value = AuthState.SignedIn } else { authProvider.removeAuthData(context) AccountProvider.logout(context) - liveData.postValue( + _authState.value = AuthState.Failed(context.getString(R.string.failed_to_generate_session)) - ) } } }