Loading app/src/main/java/foundation/e/apps/api/ResultSupreme.kt +1 −1 Original line number Diff line number Diff line Loading @@ -140,7 +140,7 @@ sealed class ResultSupreme<T> { if (isUnknownError()) { this.data = data } else { this.message = message this.message = message.ifBlank { status.message } this.exception = exception } } Loading app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +49 −30 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ package foundation.e.apps.api.fused import android.content.Context import android.text.format.Formatter import androidx.lifecycle.LiveData import androidx.lifecycle.LiveDataScope import androidx.lifecycle.liveData import androidx.lifecycle.map import com.aurora.gplayapi.Constants Loading Loading @@ -54,6 +55,7 @@ import foundation.e.apps.utils.enums.AppTag import foundation.e.apps.utils.enums.FilterLevel import foundation.e.apps.utils.enums.Origin import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.Source import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.enums.Type import foundation.e.apps.utils.enums.isUnFiltered Loading Loading @@ -93,19 +95,6 @@ class FusedAPIImpl @Inject constructor( private var TAG = FusedAPIImpl::class.java.simpleName /** * Pass list of FusedHome and status. * Second argument can be of [ResultStatus.TIMEOUT] to indicate timeout. * * Issue: * https://gitlab.e.foundation/e/backlog/-/issues/5404 * https://gitlab.e.foundation/e/backlog/-/issues/5413 */ suspend fun getHomeScreenData(authData: AuthData): Pair<List<FusedHome>, ResultStatus> { val preferredApplicationType = preferenceManagerModule.preferredApplicationType() return getHomeScreenDataBasedOnApplicationType(authData, preferredApplicationType) } /** * Check if list in all the FusedHome is empty. * If any list is not empty, send false. Loading @@ -122,44 +111,74 @@ class FusedAPIImpl @Inject constructor( return preferenceManagerModule.preferredApplicationType() } /* * Offload fetching application to a different method to dynamically fallback to a different * app source if the user selected app source times out. * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5404 */ private suspend fun getHomeScreenDataBasedOnApplicationType( suspend fun getHomeScreenData( authData: AuthData, applicationType: String ): Pair<List<FusedHome>, ResultStatus> { ): LiveData<ResultSupreme<List<FusedHome>>> { val list = mutableListOf<FusedHome>() val apiStatus = runCodeBlockWithTimeout({ return liveData { if (preferenceManagerModule.isGplaySelected()) { list.addAll(fetchGPlayHome(authData)) loadHomeData(list, Source.GPLAY, authData, this) } if (preferenceManagerModule.isOpenSourceSelected()) { loadHomeData(list, Source.OPEN, authData, this) } if (preferenceManagerModule.isPWASelected()) { loadHomeData(list, Source.PWA, authData, this) } } } private suspend fun loadHomeData( priorList: MutableList<FusedHome>, source: Source, authData: AuthData, scope: LiveDataScope<ResultSupreme<List<FusedHome>>>, ) { val apiStatus = when (source) { Source.GPLAY -> runCodeBlockWithTimeout({ priorList.addAll(fetchGPlayHome(authData)) }) Source.OPEN -> runCodeBlockWithTimeout({ val response = cleanAPKRepository.getHomeScreenData( CleanAPKInterface.APP_TYPE_ANY, CleanAPKInterface.APP_SOURCE_FOSS ).body() response?.home?.let { list.addAll(generateCleanAPKHome(it, APP_TYPE_OPEN)) } priorList.addAll(generateCleanAPKHome(it, APP_TYPE_OPEN)) } }) if (preferenceManagerModule.isPWASelected()) { Source.PWA -> runCodeBlockWithTimeout({ val response = cleanAPKRepository.getHomeScreenData( CleanAPKInterface.APP_TYPE_PWA, CleanAPKInterface.APP_SOURCE_ANY ).body() response?.home?.let { list.addAll(generateCleanAPKHome(it, APP_TYPE_PWA)) } priorList.addAll(generateCleanAPKHome(it, APP_TYPE_PWA)) } }) return Pair(list, apiStatus) } setHomeErrorMessage(apiStatus, source) scope.emit(ResultSupreme.create(apiStatus, priorList)) } private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) { if (apiStatus != ResultStatus.OK) { apiStatus.message = when (source) { Source.GPLAY -> ("GPlay home loading error\n" + apiStatus.message).trim() Source.OPEN -> ("Open Source home loading error\n" + apiStatus.message).trim() Source.PWA -> ("PWA home loading error\n" + apiStatus.message).trim() } } } /* Loading app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedAPII var hasNextStreamCluster = false private set suspend fun getHomeScreenData(authData: AuthData): Pair<List<FusedHome>, ResultStatus> { suspend fun getHomeScreenData(authData: AuthData): LiveData<ResultSupreme<List<FusedHome>>> { return fusedAPIImpl.getHomeScreenData(authData) } Loading app/src/main/java/foundation/e/apps/home/HomeFragment.kt +6 −6 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import foundation.e.apps.AppInfoFetchViewModel import foundation.e.apps.AppProgressViewModel import foundation.e.apps.MainActivityViewModel import foundation.e.apps.R import foundation.e.apps.api.ResultSupreme import foundation.e.apps.api.fused.FusedAPIInterface import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome Loading @@ -43,7 +44,6 @@ import foundation.e.apps.home.model.HomeParentRVAdapter import foundation.e.apps.login.AuthObject import foundation.e.apps.manager.download.data.DownloadProgress import foundation.e.apps.manager.pkg.PkgManagerModule import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException Loading Loading @@ -94,7 +94,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface private fun observeHomeScreenData() { homeViewModel.homeScreenData.observe(viewLifecycleOwner) { stopLoadingUI() if (it.second != ResultStatus.OK) { if (!it.isSuccess()) { return@observe } Loading @@ -102,7 +102,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface return@observe } homeParentRVAdapter?.setData(it.first) homeParentRVAdapter?.setData(it.data!!) } } Loading Loading @@ -147,9 +147,9 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface ).show(childFragmentManager, "HomeFragment") } private fun isHomeDataUpdated(homeScreenResult: Pair<List<FusedHome>, ResultStatus>) = private fun isHomeDataUpdated(homeScreenResult: ResultSupreme<List<FusedHome>>) = homeParentRVAdapter?.currentList?.isEmpty() == true || homeViewModel.isHomeDataUpdated( homeScreenResult.first, homeScreenResult.data!!, homeParentRVAdapter?.currentList as List<FusedHome> ) Loading Loading @@ -195,7 +195,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface } override fun loadData(authObjectList: List<AuthObject>) { homeViewModel.loadData(authObjectList) { _ -> homeViewModel.loadData(authObjectList, viewLifecycleOwner) { _ -> clearAndRestartGPlayLogin() true } Loading app/src/main/java/foundation/e/apps/home/HomeViewModel.kt +18 −14 Original line number Diff line number Diff line Loading @@ -18,15 +18,16 @@ package foundation.e.apps.home import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.aurora.gplayapi.data.models.AuthData import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.api.ResultSupreme import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.parentFragment.LoadingViewModel Loading @@ -44,43 +45,46 @@ class HomeViewModel @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5404 */ var homeScreenData: MutableLiveData<Pair<List<FusedHome>, ResultStatus>> = MutableLiveData() var homeScreenData: MutableLiveData<ResultSupreme<List<FusedHome>>> = MutableLiveData() fun loadData( authObjectList: List<AuthObject>, lifecycleOwner: LifecycleOwner, retryBlock: (failedObjects: List<AuthObject>) -> Boolean, ) { super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getHomeScreenData(result.data!! as AuthData) getHomeScreenData(result.data!! as AuthData, lifecycleOwner) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getHomeScreenData(AuthData("", "")) getHomeScreenData(AuthData("", ""), lifecycleOwner) return@onLoadData } }, retryBlock) } fun getHomeScreenData(authData: AuthData) { fun getHomeScreenData( authData: AuthData, lifecycleOwner: LifecycleOwner, ) { viewModelScope.launch { val screenData = fusedAPIRepository.getHomeScreenData(authData) homeScreenData.postValue(screenData) fusedAPIRepository.getHomeScreenData(authData).observe(lifecycleOwner) { homeScreenData.postValue(it) val status = screenData.second if (it.isSuccess()) return@observe if (status != ResultStatus.OK) { val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) GPlayException( screenData.second == ResultStatus.TIMEOUT, status.message.ifBlank { "Data load error" } it.isTimeout(), it.message.ifBlank { "Data load error" } ) else CleanApkException( screenData.second == ResultStatus.TIMEOUT, status.message.ifBlank { "Data load error" } it.isTimeout(), it.message.ifBlank { "Data load error" } ) exceptionsList.add(exception) Loading @@ -94,7 +98,7 @@ class HomeViewModel @Inject constructor( } fun isFusedHomesEmpty(): Boolean { return homeScreenData.value?.first?.let { return homeScreenData.value?.data?.let { fusedAPIRepository.isFusedHomesEmpty(it) } ?: true } Loading Loading
app/src/main/java/foundation/e/apps/api/ResultSupreme.kt +1 −1 Original line number Diff line number Diff line Loading @@ -140,7 +140,7 @@ sealed class ResultSupreme<T> { if (isUnknownError()) { this.data = data } else { this.message = message this.message = message.ifBlank { status.message } this.exception = exception } } Loading
app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +49 −30 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ package foundation.e.apps.api.fused import android.content.Context import android.text.format.Formatter import androidx.lifecycle.LiveData import androidx.lifecycle.LiveDataScope import androidx.lifecycle.liveData import androidx.lifecycle.map import com.aurora.gplayapi.Constants Loading Loading @@ -54,6 +55,7 @@ import foundation.e.apps.utils.enums.AppTag import foundation.e.apps.utils.enums.FilterLevel import foundation.e.apps.utils.enums.Origin import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.Source import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.enums.Type import foundation.e.apps.utils.enums.isUnFiltered Loading Loading @@ -93,19 +95,6 @@ class FusedAPIImpl @Inject constructor( private var TAG = FusedAPIImpl::class.java.simpleName /** * Pass list of FusedHome and status. * Second argument can be of [ResultStatus.TIMEOUT] to indicate timeout. * * Issue: * https://gitlab.e.foundation/e/backlog/-/issues/5404 * https://gitlab.e.foundation/e/backlog/-/issues/5413 */ suspend fun getHomeScreenData(authData: AuthData): Pair<List<FusedHome>, ResultStatus> { val preferredApplicationType = preferenceManagerModule.preferredApplicationType() return getHomeScreenDataBasedOnApplicationType(authData, preferredApplicationType) } /** * Check if list in all the FusedHome is empty. * If any list is not empty, send false. Loading @@ -122,44 +111,74 @@ class FusedAPIImpl @Inject constructor( return preferenceManagerModule.preferredApplicationType() } /* * Offload fetching application to a different method to dynamically fallback to a different * app source if the user selected app source times out. * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5404 */ private suspend fun getHomeScreenDataBasedOnApplicationType( suspend fun getHomeScreenData( authData: AuthData, applicationType: String ): Pair<List<FusedHome>, ResultStatus> { ): LiveData<ResultSupreme<List<FusedHome>>> { val list = mutableListOf<FusedHome>() val apiStatus = runCodeBlockWithTimeout({ return liveData { if (preferenceManagerModule.isGplaySelected()) { list.addAll(fetchGPlayHome(authData)) loadHomeData(list, Source.GPLAY, authData, this) } if (preferenceManagerModule.isOpenSourceSelected()) { loadHomeData(list, Source.OPEN, authData, this) } if (preferenceManagerModule.isPWASelected()) { loadHomeData(list, Source.PWA, authData, this) } } } private suspend fun loadHomeData( priorList: MutableList<FusedHome>, source: Source, authData: AuthData, scope: LiveDataScope<ResultSupreme<List<FusedHome>>>, ) { val apiStatus = when (source) { Source.GPLAY -> runCodeBlockWithTimeout({ priorList.addAll(fetchGPlayHome(authData)) }) Source.OPEN -> runCodeBlockWithTimeout({ val response = cleanAPKRepository.getHomeScreenData( CleanAPKInterface.APP_TYPE_ANY, CleanAPKInterface.APP_SOURCE_FOSS ).body() response?.home?.let { list.addAll(generateCleanAPKHome(it, APP_TYPE_OPEN)) } priorList.addAll(generateCleanAPKHome(it, APP_TYPE_OPEN)) } }) if (preferenceManagerModule.isPWASelected()) { Source.PWA -> runCodeBlockWithTimeout({ val response = cleanAPKRepository.getHomeScreenData( CleanAPKInterface.APP_TYPE_PWA, CleanAPKInterface.APP_SOURCE_ANY ).body() response?.home?.let { list.addAll(generateCleanAPKHome(it, APP_TYPE_PWA)) } priorList.addAll(generateCleanAPKHome(it, APP_TYPE_PWA)) } }) return Pair(list, apiStatus) } setHomeErrorMessage(apiStatus, source) scope.emit(ResultSupreme.create(apiStatus, priorList)) } private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) { if (apiStatus != ResultStatus.OK) { apiStatus.message = when (source) { Source.GPLAY -> ("GPlay home loading error\n" + apiStatus.message).trim() Source.OPEN -> ("Open Source home loading error\n" + apiStatus.message).trim() Source.PWA -> ("PWA home loading error\n" + apiStatus.message).trim() } } } /* Loading
app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedAPII var hasNextStreamCluster = false private set suspend fun getHomeScreenData(authData: AuthData): Pair<List<FusedHome>, ResultStatus> { suspend fun getHomeScreenData(authData: AuthData): LiveData<ResultSupreme<List<FusedHome>>> { return fusedAPIImpl.getHomeScreenData(authData) } Loading
app/src/main/java/foundation/e/apps/home/HomeFragment.kt +6 −6 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import foundation.e.apps.AppInfoFetchViewModel import foundation.e.apps.AppProgressViewModel import foundation.e.apps.MainActivityViewModel import foundation.e.apps.R import foundation.e.apps.api.ResultSupreme import foundation.e.apps.api.fused.FusedAPIInterface import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome Loading @@ -43,7 +44,6 @@ import foundation.e.apps.home.model.HomeParentRVAdapter import foundation.e.apps.login.AuthObject import foundation.e.apps.manager.download.data.DownloadProgress import foundation.e.apps.manager.pkg.PkgManagerModule import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.Status import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException Loading Loading @@ -94,7 +94,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface private fun observeHomeScreenData() { homeViewModel.homeScreenData.observe(viewLifecycleOwner) { stopLoadingUI() if (it.second != ResultStatus.OK) { if (!it.isSuccess()) { return@observe } Loading @@ -102,7 +102,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface return@observe } homeParentRVAdapter?.setData(it.first) homeParentRVAdapter?.setData(it.data!!) } } Loading Loading @@ -147,9 +147,9 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface ).show(childFragmentManager, "HomeFragment") } private fun isHomeDataUpdated(homeScreenResult: Pair<List<FusedHome>, ResultStatus>) = private fun isHomeDataUpdated(homeScreenResult: ResultSupreme<List<FusedHome>>) = homeParentRVAdapter?.currentList?.isEmpty() == true || homeViewModel.isHomeDataUpdated( homeScreenResult.first, homeScreenResult.data!!, homeParentRVAdapter?.currentList as List<FusedHome> ) Loading Loading @@ -195,7 +195,7 @@ class HomeFragment : TimeoutFragment(R.layout.fragment_home), FusedAPIInterface } override fun loadData(authObjectList: List<AuthObject>) { homeViewModel.loadData(authObjectList) { _ -> homeViewModel.loadData(authObjectList, viewLifecycleOwner) { _ -> clearAndRestartGPlayLogin() true } Loading
app/src/main/java/foundation/e/apps/home/HomeViewModel.kt +18 −14 Original line number Diff line number Diff line Loading @@ -18,15 +18,16 @@ package foundation.e.apps.home import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.aurora.gplayapi.data.models.AuthData import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.api.ResultSupreme import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.parentFragment.LoadingViewModel Loading @@ -44,43 +45,46 @@ class HomeViewModel @Inject constructor( * * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5404 */ var homeScreenData: MutableLiveData<Pair<List<FusedHome>, ResultStatus>> = MutableLiveData() var homeScreenData: MutableLiveData<ResultSupreme<List<FusedHome>>> = MutableLiveData() fun loadData( authObjectList: List<AuthObject>, lifecycleOwner: LifecycleOwner, retryBlock: (failedObjects: List<AuthObject>) -> Boolean, ) { super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getHomeScreenData(result.data!! as AuthData) getHomeScreenData(result.data!! as AuthData, lifecycleOwner) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getHomeScreenData(AuthData("", "")) getHomeScreenData(AuthData("", ""), lifecycleOwner) return@onLoadData } }, retryBlock) } fun getHomeScreenData(authData: AuthData) { fun getHomeScreenData( authData: AuthData, lifecycleOwner: LifecycleOwner, ) { viewModelScope.launch { val screenData = fusedAPIRepository.getHomeScreenData(authData) homeScreenData.postValue(screenData) fusedAPIRepository.getHomeScreenData(authData).observe(lifecycleOwner) { homeScreenData.postValue(it) val status = screenData.second if (it.isSuccess()) return@observe if (status != ResultStatus.OK) { val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) GPlayException( screenData.second == ResultStatus.TIMEOUT, status.message.ifBlank { "Data load error" } it.isTimeout(), it.message.ifBlank { "Data load error" } ) else CleanApkException( screenData.second == ResultStatus.TIMEOUT, status.message.ifBlank { "Data load error" } it.isTimeout(), it.message.ifBlank { "Data load error" } ) exceptionsList.add(exception) Loading @@ -94,7 +98,7 @@ class HomeViewModel @Inject constructor( } fun isFusedHomesEmpty(): Boolean { return homeScreenData.value?.first?.let { return homeScreenData.value?.data?.let { fusedAPIRepository.isFusedHomesEmpty(it) } ?: true } Loading