Loading app/src/main/java/foundation/e/apps/data/application/search/SearchRepositoryImpl.kt +19 −21 Original line number Diff line number Diff line Loading @@ -74,13 +74,8 @@ class SearchRepositoryImpl @Inject constructor( ): SearchResult { return ResultSupreme.Success( Pair( filterWithKeywordSearch( keywordSpecificResults, packageSpecificResults, "" // Query string no longer needed ), // Add loading indication for Play Store if enabled stores.isStoreEnabled(Source.PLAY_STORE) filterWithKeywordSearch(keywordSpecificResults, packageSpecificResults), stores.isStoreEnabled(Source.PLAY_STORE) // Add loading indication for Play Store if enabled ) ) } Loading @@ -100,7 +95,7 @@ class SearchRepositoryImpl @Inject constructor( return if (result.isSuccess()) { result.data.orEmpty().map { updatePwa(it) } .apply { filterWithKeywordSearch(this, packageSpecificResults, query) } .apply { filterWithKeywordSearch(this, packageSpecificResults) } } else { emptyList() } Loading Loading @@ -128,7 +123,7 @@ class SearchRepositoryImpl @Inject constructor( return if (result.isSuccess()) { result.data.orEmpty().apply { filterWithKeywordSearch(this, packageSpecificResults, query) filterWithKeywordSearch(this, packageSpecificResults) } } else { emptyList() Loading Loading @@ -170,29 +165,32 @@ class SearchRepositoryImpl @Inject constructor( return ResultSupreme.create(resultStatus, Pair(apps.mapNotNull { it }, true)) } /* * The list packageSpecificResults may contain apps with duplicate package names. * Example, "org.telegram.messenger" will result in "Telegram" app from Play Store * and "Telegram FOSS" from F-droid. We show both of them at the top. /** * Filters and combines search results to prevent duplicates while preserving package-specific matches. * * Package-specific results may contain multiple variants from different sources. * These are displayed at the top as-is. * * But for the other keyword related search results, we do not allow duplicate package names. * We also filter out apps which are already present in packageSpecificResults list. * Keyword search results are deduplicated by package name and exclude any apps * already present in package-specific results. */ private fun filterWithKeywordSearch( list: List<Application>, packageSpecificResults: List<Application>, query: String ): List<Application> { val packageNames = packageSpecificResults.map { it.package_name }.toSet() val filteredResults = list.distinctBy { it.package_name } .filter { packageSpecificResults.isEmpty() || it.package_name != query } .filter { it.package_name !in packageNames } val apps = (packageSpecificResults + filteredResults).toMutableList() apps.removeIf { it.isPlaceHolder } val finalList = (packageSpecificResults + filteredResults).toMutableList() finalList.removeIf { it.isPlaceHolder } if (stores.isStoreEnabled(Source.PLAY_STORE)) { finalList.add(Application(isPlaceHolder = true)) apps.add(Application(isPlaceHolder = true)) } return finalList return apps.toList() } private suspend fun getCleanApkApp(query: String): Application? { Loading Loading
app/src/main/java/foundation/e/apps/data/application/search/SearchRepositoryImpl.kt +19 −21 Original line number Diff line number Diff line Loading @@ -74,13 +74,8 @@ class SearchRepositoryImpl @Inject constructor( ): SearchResult { return ResultSupreme.Success( Pair( filterWithKeywordSearch( keywordSpecificResults, packageSpecificResults, "" // Query string no longer needed ), // Add loading indication for Play Store if enabled stores.isStoreEnabled(Source.PLAY_STORE) filterWithKeywordSearch(keywordSpecificResults, packageSpecificResults), stores.isStoreEnabled(Source.PLAY_STORE) // Add loading indication for Play Store if enabled ) ) } Loading @@ -100,7 +95,7 @@ class SearchRepositoryImpl @Inject constructor( return if (result.isSuccess()) { result.data.orEmpty().map { updatePwa(it) } .apply { filterWithKeywordSearch(this, packageSpecificResults, query) } .apply { filterWithKeywordSearch(this, packageSpecificResults) } } else { emptyList() } Loading Loading @@ -128,7 +123,7 @@ class SearchRepositoryImpl @Inject constructor( return if (result.isSuccess()) { result.data.orEmpty().apply { filterWithKeywordSearch(this, packageSpecificResults, query) filterWithKeywordSearch(this, packageSpecificResults) } } else { emptyList() Loading Loading @@ -170,29 +165,32 @@ class SearchRepositoryImpl @Inject constructor( return ResultSupreme.create(resultStatus, Pair(apps.mapNotNull { it }, true)) } /* * The list packageSpecificResults may contain apps with duplicate package names. * Example, "org.telegram.messenger" will result in "Telegram" app from Play Store * and "Telegram FOSS" from F-droid. We show both of them at the top. /** * Filters and combines search results to prevent duplicates while preserving package-specific matches. * * Package-specific results may contain multiple variants from different sources. * These are displayed at the top as-is. * * But for the other keyword related search results, we do not allow duplicate package names. * We also filter out apps which are already present in packageSpecificResults list. * Keyword search results are deduplicated by package name and exclude any apps * already present in package-specific results. */ private fun filterWithKeywordSearch( list: List<Application>, packageSpecificResults: List<Application>, query: String ): List<Application> { val packageNames = packageSpecificResults.map { it.package_name }.toSet() val filteredResults = list.distinctBy { it.package_name } .filter { packageSpecificResults.isEmpty() || it.package_name != query } .filter { it.package_name !in packageNames } val apps = (packageSpecificResults + filteredResults).toMutableList() apps.removeIf { it.isPlaceHolder } val finalList = (packageSpecificResults + filteredResults).toMutableList() finalList.removeIf { it.isPlaceHolder } if (stores.isStoreEnabled(Source.PLAY_STORE)) { finalList.add(Application(isPlaceHolder = true)) apps.add(Application(isPlaceHolder = true)) } return finalList return apps.toList() } private suspend fun getCleanApkApp(query: String): Application? { Loading