Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6854bcb3 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

chore: remove useless HomeApi abstraction

parent 2bd04e44
Loading
Loading
Loading
Loading
+90 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
package foundation.e.apps.data.application

import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.Stores
import foundation.e.apps.data.application.apps.AppsApi
@@ -27,19 +28,20 @@ import foundation.e.apps.data.application.category.CategoryApi
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.application.downloadInfo.DownloadInfoApi
import foundation.e.apps.data.application.home.HomeApi
import foundation.e.apps.data.application.utils.CategoryType
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.ResultStatus
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.handleNetworkResult
import foundation.e.apps.data.install.models.AppInstall
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ApplicationRepository @Inject constructor(
    private val homeApi: HomeApi,
    private val categoryApi: CategoryApi,
    private val appsApi: AppsApi,
    private val downloadInfoApi: DownloadInfoApi,
@@ -51,8 +53,86 @@ class ApplicationRepository @Inject constructor(
        const val APP_TYPE_PWA = "pwa"
    }

    suspend fun getHomeScreenData(): LiveData<ResultSupreme<List<Home>>> {
        return homeApi.fetchHomeScreenData()
    private enum class AppSourceWeight {
        GPLAY,
        OPEN_SOURCE,
        PWA
    }

    fun getHomeScreenData(): LiveData<ResultSupreme<List<Home>>> {
        return liveData {
            suspend fun emitResult(
                result: ResultSupreme<List<Home>>,
                resultsBySource: Map<Source, ResultSupreme<List<Home>>>
            ) {
                val merged = mergeResults(resultsBySource.values)
                emit(
                    ResultSupreme.create(
                        result.getResultStatus(),
                        merged,
                        result.message,
                        result.exception,
                    )
                )
            }

            coroutineScope {
                val resultsBySource = mutableMapOf<Source, ResultSupreme<List<Home>>>()
                val sources = stores.getStores().keys
                val deferredResults = sources.associateWith { source ->
                    async { loadHomeData(source) }
                }

                sources.forEach { source ->
                    val result = deferredResults.getValue(source).await()
                    resultsBySource[source] = result
                    emitResult(result, resultsBySource)
                }
            }
        }
    }

    private suspend fun loadHomeData(source: Source): ResultSupreme<List<Home>> {
        val list = mutableListOf<Home>()
        val result = handleNetworkResult {
            val homeDataBuilder = stores.getStore(source)
            checkNotNull(homeDataBuilder) { "Could not find store for $source" }
            homeDataBuilder.getHomeScreenData(list)
        }

        setHomeErrorMessage(result.getResultStatus(), source)
        list.sortBy {
            when (it.source) {
                APP_TYPE_OPEN -> AppSourceWeight.OPEN_SOURCE.ordinal
                APP_TYPE_PWA -> AppSourceWeight.PWA.ordinal
                else -> AppSourceWeight.GPLAY.ordinal
            }
        }

        return ResultSupreme.create(result.getResultStatus(), list)
    }

    private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) {
        if (apiStatus != ResultStatus.OK) {
            apiStatus.message = when (source) {
                Source.PLAY_STORE -> ("GPlay home loading error\n" + apiStatus.message).trim()
                Source.SYSTEM_APP -> ("Gitlab home not allowed\n" + apiStatus.message).trim()
                Source.OPEN_SOURCE -> ("Open Source home loading error\n" + apiStatus.message).trim()
                Source.PWA -> ("PWA home loading error\n" + apiStatus.message).trim()
            }
        }
    }

    private fun mergeResults(results: Collection<ResultSupreme<List<Home>>>): List<Home> {
        val merged = results.flatMap { it.data.orEmpty() }.toMutableList()
        merged.sortBy {
            when (it.source) {
                APP_TYPE_OPEN -> AppSourceWeight.OPEN_SOURCE.ordinal
                APP_TYPE_PWA -> AppSourceWeight.PWA.ordinal
                else -> AppSourceWeight.GPLAY.ordinal
            }
        }
        return merged
    }

    fun getSelectedAppTypes(): List<String> {
+0 −27
Original line number Diff line number Diff line
/*
 * Copyright MURENA SAS 2023
 * Apps  Quickly and easily install Android apps onto your device!
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps.data.application.home

import androidx.lifecycle.LiveData
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.application.data.Home

interface HomeApi {
    suspend fun fetchHomeScreenData(): LiveData<ResultSupreme<List<Home>>>
}
+0 −124
Original line number Diff line number Diff line
/*
 * Copyright MURENA SAS 2023
 * Apps  Quickly and easily install Android apps onto your device!
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps.data.application.home

import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.Stores
import foundation.e.apps.data.application.ApplicationRepository
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.enums.ResultStatus
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.handleNetworkResult
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import javax.inject.Inject

class HomeApiImpl @Inject constructor(
    private val stores: Stores
) : HomeApi {
    private enum class AppSourceWeight {
        GPLAY,
        OPEN_SOURCE,
        PWA
    }

    override suspend fun fetchHomeScreenData(): LiveData<ResultSupreme<List<Home>>> {
        return liveData {
            suspend fun emitResult(
                result: ResultSupreme<List<Home>>,
                resultsBySource: Map<Source, ResultSupreme<List<Home>>>
            ) {
                val merged = mergeResults(resultsBySource.values)
                emit(
                    ResultSupreme.create(
                        result.getResultStatus(),
                        merged,
                        result.message,
                        result.exception,
                    )
                )
            }

            coroutineScope {
                val resultsBySource = mutableMapOf<Source, ResultSupreme<List<Home>>>()
                val sources = stores.getStores().keys
                val deferredResults = sources.associateWith { source ->
                    async { loadHomeData(source) }
                }

                val playStoreResult = deferredResults[Source.PLAY_STORE]?.await()
                playStoreResult?.let {
                    resultsBySource[Source.PLAY_STORE] = it
                    emitResult(it, resultsBySource)
                }

                sources.filter { it != Source.PLAY_STORE }.forEach { source ->
                    val result = deferredResults.getValue(source).await()
                    resultsBySource[source] = result
                    emitResult(result, resultsBySource)
                }
            }
        }
    }

    private suspend fun loadHomeData(source: Source): ResultSupreme<List<Home>> {
        val list = mutableListOf<Home>()
        val result = handleNetworkResult {
            val homeDataBuilder = stores.getStore(source)
            homeDataBuilder?.getHomeScreenData(list)
                ?: throw IllegalStateException("Could not find store for $source")
        }

        setHomeErrorMessage(result.getResultStatus(), source)
        list.sortBy {
            when (it.source) {
                ApplicationRepository.APP_TYPE_OPEN -> AppSourceWeight.OPEN_SOURCE.ordinal
                ApplicationRepository.APP_TYPE_PWA -> AppSourceWeight.PWA.ordinal
                else -> AppSourceWeight.GPLAY.ordinal
            }
        }

        return ResultSupreme.create(result.getResultStatus(), list)
    }

    private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) {
        if (apiStatus != ResultStatus.OK) {
            apiStatus.message = when (source) {
                Source.PLAY_STORE -> ("GPlay home loading error\n" + apiStatus.message).trim()
                Source.SYSTEM_APP -> ("Gitlab home not allowed\n" + apiStatus.message).trim()
                Source.OPEN_SOURCE -> ("Open Source home loading error\n" + apiStatus.message).trim()
                Source.PWA -> ("PWA home loading error\n" + apiStatus.message).trim()
            }
        }
    }

    private fun mergeResults(results: Collection<ResultSupreme<List<Home>>>): List<Home> {
        val merged = results.flatMap { it.data.orEmpty() }.toMutableList()
        merged.sortBy {
            when (it.source) {
                ApplicationRepository.APP_TYPE_OPEN -> AppSourceWeight.OPEN_SOURCE.ordinal
                ApplicationRepository.APP_TYPE_PWA -> AppSourceWeight.PWA.ordinal
                else -> AppSourceWeight.GPLAY.ordinal
            }
        }
        return merged
    }
}
+0 −6
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ import foundation.e.apps.data.application.category.CategoryApi
import foundation.e.apps.data.application.category.CategoryApiImpl
import foundation.e.apps.data.application.downloadInfo.DownloadInfoApi
import foundation.e.apps.data.application.downloadInfo.DownloadInfoApiImpl
import foundation.e.apps.data.application.home.HomeApi
import foundation.e.apps.data.application.home.HomeApiImpl
import foundation.e.apps.data.application.search.SearchRepository
import foundation.e.apps.data.application.search.SearchRepositoryImpl
import javax.inject.Singleton
@@ -38,10 +36,6 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
interface DataModule {

    @Singleton
    @Binds
    fun getHomeApi(homeApiImpl: HomeApiImpl): HomeApi

    @Singleton
    @Binds
    fun getCategoryApi(categoryApiImpl: CategoryApiImpl): CategoryApi
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import javax.inject.Inject
class FetchHomeScreenDataUseCase @Inject constructor(
    private val applicationRepository: ApplicationRepository,
) {
    suspend operator fun invoke(): LiveData<HomeScreenResult> {
    operator fun invoke(): LiveData<HomeScreenResult> {
        return applicationRepository.getHomeScreenData().map { result ->
            val homeSections = result.data?.map { it.toDomain() }.orEmpty()
            when (result) {
Loading