Loading app/src/main/java/foundation/e/apps/MainActivity.kt +9 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.fusedDownload.models.FusedDownload import foundation.e.apps.data.login.LoginSourceGPlay import foundation.e.apps.data.preference.PreferenceManagerModule import foundation.e.apps.databinding.ActivityMainBinding import foundation.e.apps.domain.errors.RetryMechanism Loading Loading @@ -73,6 +72,10 @@ class MainActivity : AppCompatActivity() { @Inject lateinit var preferenceManagerModule: PreferenceManagerModule companion object { private const val STATUS_TOO_MANY_REQUESTS = "Status: 429" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading Loading @@ -301,6 +304,10 @@ class MainActivity : AppCompatActivity() { EventBus.events.filter { appEvent -> appEvent is AppEvent.DataLoadError<*> }.collectLatest { if (it.data is ResultSupreme<*> && it.data.message.contains(STATUS_TOO_MANY_REQUESTS)) { return@collectLatest } retryMechanism.wrapWithRetry( { loginViewModel.checkLogin() }, { Loading Loading @@ -328,7 +335,7 @@ class MainActivity : AppCompatActivity() { binding.sessionErrorLayout.visibility = View.VISIBLE binding.retrySessionButton.setOnClickListener { binding.sessionErrorLayout.visibility = View.GONE loginViewModel.startLoginFlow(listOf(LoginSourceGPlay::class.java.simpleName)) loginViewModel.getNewToken() } } } Loading app/src/main/java/foundation/e/apps/domain/main/usecase/MainActivityUseCase.kt +8 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package foundation.e.apps.domain.main.usecase import com.aurora.gplayapi.data.models.AuthData import foundation.e.apps.domain.common.repository.CacheRepository import javax.inject.Inject Loading @@ -26,5 +27,11 @@ class MainActivityUseCase @Inject constructor( ) { fun currentUser() = cacheRepository.currentUser() fun currentAuthData() = cacheRepository.cacheAuthData() fun currentAuthData(): AuthData { return try { cacheRepository.cacheAuthData() } catch (e: RuntimeException) { AuthData("", "") } } } app/src/main/java/foundation/e/apps/presentation/login/LoginViewModel.kt +4 −3 Original line number Diff line number Diff line Loading @@ -68,7 +68,9 @@ class LoginViewModel @Inject constructor( fun startLoginFlow(clearList: List<String> = listOf()) { viewModelScope.launch { val authObjectsLocal = loginSourceRepository.getAuthObjects(clearList) authObjects.postValue(authObjectsLocal) if (authObjectsLocal.isNotEmpty()) { _loginState.postValue(LoginState(isLoggedIn = authObjectsLocal[0].result.isSuccess())) } } } Loading Loading @@ -235,8 +237,7 @@ class LoginViewModel @Inject constructor( is Resource.Loading -> _loginState.value = LoginState(isLoading = true) is Resource.Success -> { // TODO it.data?.let { it1 -> updateAuthObjectForAnonymousUser(it1) } it.data?.let { authData -> updateAuthObjectForAnonymousUser(authData) } _loginState.value = LoginState(isLoggedIn = true, authData = it.data, user = User.ANONYMOUS) } Loading app/src/main/java/foundation/e/apps/ui/applicationlist/ApplicationListViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ class ApplicationListViewModel @Inject constructor( return } this.nextPageUrl = null viewModelScope.launch(Dispatchers.IO) { isLoading = true val result = fusedAPIRepository.getAppsListBasedOnCategory( Loading @@ -74,6 +75,10 @@ class ApplicationListViewModel @Inject constructor( updateNextPageUrl(it.second) } if (result.isSuccess()) { loadMore(authData, category) } if (!result.isSuccess()) EventBus.invokeEvent(AppEvent.DataLoadError(result)) } } Loading app/src/main/java/foundation/e/apps/ui/search/SearchFragment.kt +21 −22 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.aurora.gplayapi.SearchSuggestEntry import com.aurora.gplayapi.data.models.AuthData import com.facebook.shimmer.ShimmerFrameLayout import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.R Loading Loading @@ -87,8 +86,6 @@ class SearchFragment : ViewModelProvider(requireActivity())[LoginViewModel::class.java] } private var authData: AuthData? = null private val SUGGESTION_KEY = "suggestion" private var lastSearch = "" Loading @@ -104,6 +101,24 @@ class SearchFragment : */ private var searchText = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mainActivityViewModel.internetConnection.loadDataOnce(this) { observeLoginState() } } private fun observeLoginState() { loginViewModel.loginState.observe(viewLifecycleOwner) { if (it.authData == null || !it.isLoggedIn) { return@observe } searchViewModel.authData = it.authData loadData() } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentSearchBinding.bind(view) Loading @@ -122,26 +137,10 @@ class SearchFragment : observeSearchResult(listAdapter) mainActivityViewModel.internetConnection.loadDataOnce(this) { loginViewModel.loginState.observe(viewLifecycleOwner) { val currentQuery = searchView?.query?.toString() ?: "" if ((!it.isLoggedIn || (currentQuery.isNotEmpty() && lastSearch == currentQuery)) && !searchViewModel.isLoginStateChanged(it) ) { return@observe } this.authData = it.authData loadData() } } binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (!recyclerView.canScrollVertically(1)) { if (!requireContext().isNetworkAvailable()) { return } if (!recyclerView.canScrollVertically(1) && requireContext().isNetworkAvailable()) { searchViewModel.loadMore(searchText) } } Loading Loading @@ -288,7 +287,7 @@ class SearchFragment : private fun loadData() { showLoadingUI() searchViewModel.loadData(searchText, viewLifecycleOwner, authData) searchViewModel.loadData(searchText, viewLifecycleOwner) } private fun showLoadingUI() { Loading Loading @@ -379,7 +378,7 @@ class SearchFragment : override fun onQueryTextChange(newText: String?): Boolean { newText?.let { text -> searchViewModel.getSearchSuggestions(text, authData) searchViewModel.getSearchSuggestions(text) } return true } Loading Loading
app/src/main/java/foundation/e/apps/MainActivity.kt +9 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.fusedDownload.models.FusedDownload import foundation.e.apps.data.login.LoginSourceGPlay import foundation.e.apps.data.preference.PreferenceManagerModule import foundation.e.apps.databinding.ActivityMainBinding import foundation.e.apps.domain.errors.RetryMechanism Loading Loading @@ -73,6 +72,10 @@ class MainActivity : AppCompatActivity() { @Inject lateinit var preferenceManagerModule: PreferenceManagerModule companion object { private const val STATUS_TOO_MANY_REQUESTS = "Status: 429" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading Loading @@ -301,6 +304,10 @@ class MainActivity : AppCompatActivity() { EventBus.events.filter { appEvent -> appEvent is AppEvent.DataLoadError<*> }.collectLatest { if (it.data is ResultSupreme<*> && it.data.message.contains(STATUS_TOO_MANY_REQUESTS)) { return@collectLatest } retryMechanism.wrapWithRetry( { loginViewModel.checkLogin() }, { Loading Loading @@ -328,7 +335,7 @@ class MainActivity : AppCompatActivity() { binding.sessionErrorLayout.visibility = View.VISIBLE binding.retrySessionButton.setOnClickListener { binding.sessionErrorLayout.visibility = View.GONE loginViewModel.startLoginFlow(listOf(LoginSourceGPlay::class.java.simpleName)) loginViewModel.getNewToken() } } } Loading
app/src/main/java/foundation/e/apps/domain/main/usecase/MainActivityUseCase.kt +8 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package foundation.e.apps.domain.main.usecase import com.aurora.gplayapi.data.models.AuthData import foundation.e.apps.domain.common.repository.CacheRepository import javax.inject.Inject Loading @@ -26,5 +27,11 @@ class MainActivityUseCase @Inject constructor( ) { fun currentUser() = cacheRepository.currentUser() fun currentAuthData() = cacheRepository.cacheAuthData() fun currentAuthData(): AuthData { return try { cacheRepository.cacheAuthData() } catch (e: RuntimeException) { AuthData("", "") } } }
app/src/main/java/foundation/e/apps/presentation/login/LoginViewModel.kt +4 −3 Original line number Diff line number Diff line Loading @@ -68,7 +68,9 @@ class LoginViewModel @Inject constructor( fun startLoginFlow(clearList: List<String> = listOf()) { viewModelScope.launch { val authObjectsLocal = loginSourceRepository.getAuthObjects(clearList) authObjects.postValue(authObjectsLocal) if (authObjectsLocal.isNotEmpty()) { _loginState.postValue(LoginState(isLoggedIn = authObjectsLocal[0].result.isSuccess())) } } } Loading Loading @@ -235,8 +237,7 @@ class LoginViewModel @Inject constructor( is Resource.Loading -> _loginState.value = LoginState(isLoading = true) is Resource.Success -> { // TODO it.data?.let { it1 -> updateAuthObjectForAnonymousUser(it1) } it.data?.let { authData -> updateAuthObjectForAnonymousUser(authData) } _loginState.value = LoginState(isLoggedIn = true, authData = it.data, user = User.ANONYMOUS) } Loading
app/src/main/java/foundation/e/apps/ui/applicationlist/ApplicationListViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ class ApplicationListViewModel @Inject constructor( return } this.nextPageUrl = null viewModelScope.launch(Dispatchers.IO) { isLoading = true val result = fusedAPIRepository.getAppsListBasedOnCategory( Loading @@ -74,6 +75,10 @@ class ApplicationListViewModel @Inject constructor( updateNextPageUrl(it.second) } if (result.isSuccess()) { loadMore(authData, category) } if (!result.isSuccess()) EventBus.invokeEvent(AppEvent.DataLoadError(result)) } } Loading
app/src/main/java/foundation/e/apps/ui/search/SearchFragment.kt +21 −22 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.aurora.gplayapi.SearchSuggestEntry import com.aurora.gplayapi.data.models.AuthData import com.facebook.shimmer.ShimmerFrameLayout import dagger.hilt.android.AndroidEntryPoint import foundation.e.apps.R Loading Loading @@ -87,8 +86,6 @@ class SearchFragment : ViewModelProvider(requireActivity())[LoginViewModel::class.java] } private var authData: AuthData? = null private val SUGGESTION_KEY = "suggestion" private var lastSearch = "" Loading @@ -104,6 +101,24 @@ class SearchFragment : */ private var searchText = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mainActivityViewModel.internetConnection.loadDataOnce(this) { observeLoginState() } } private fun observeLoginState() { loginViewModel.loginState.observe(viewLifecycleOwner) { if (it.authData == null || !it.isLoggedIn) { return@observe } searchViewModel.authData = it.authData loadData() } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) _binding = FragmentSearchBinding.bind(view) Loading @@ -122,26 +137,10 @@ class SearchFragment : observeSearchResult(listAdapter) mainActivityViewModel.internetConnection.loadDataOnce(this) { loginViewModel.loginState.observe(viewLifecycleOwner) { val currentQuery = searchView?.query?.toString() ?: "" if ((!it.isLoggedIn || (currentQuery.isNotEmpty() && lastSearch == currentQuery)) && !searchViewModel.isLoginStateChanged(it) ) { return@observe } this.authData = it.authData loadData() } } binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (!recyclerView.canScrollVertically(1)) { if (!requireContext().isNetworkAvailable()) { return } if (!recyclerView.canScrollVertically(1) && requireContext().isNetworkAvailable()) { searchViewModel.loadMore(searchText) } } Loading Loading @@ -288,7 +287,7 @@ class SearchFragment : private fun loadData() { showLoadingUI() searchViewModel.loadData(searchText, viewLifecycleOwner, authData) searchViewModel.loadData(searchText, viewLifecycleOwner) } private fun showLoadingUI() { Loading Loading @@ -379,7 +378,7 @@ class SearchFragment : override fun onQueryTextChange(newText: String?): Boolean { newText?.let { text -> searchViewModel.getSearchSuggestions(text, authData) searchViewModel.getSearchSuggestions(text) } return true } Loading