From 87f91aee741a9f856da737969f8c5c322b790b2b Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Fri, 26 Jul 2024 20:54:00 +0200 Subject: [PATCH] Run file search providers in parallel --- .../mm20/launcher2/files/FilesRepository.kt | 73 +++++++++++++------ 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/data/files/src/main/java/de/mm20/launcher2/files/FilesRepository.kt b/data/files/src/main/java/de/mm20/launcher2/files/FilesRepository.kt index 7be86ad8..b77512b8 100644 --- a/data/files/src/main/java/de/mm20/launcher2/files/FilesRepository.kt +++ b/data/files/src/main/java/de/mm20/launcher2/files/FilesRepository.kt @@ -8,14 +8,25 @@ import de.mm20.launcher2.files.providers.OwncloudFileProvider import de.mm20.launcher2.files.providers.PluginFileProvider import de.mm20.launcher2.nextcloud.NextcloudApiHelper import de.mm20.launcher2.owncloud.OwncloudClient +import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.preferences.search.FileSearchSettings import de.mm20.launcher2.search.File +import de.mm20.launcher2.search.Location import de.mm20.launcher2.search.SearchableRepository +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.flow.channelFlow +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combineTransform +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope internal class FileRepository( private val context: Context, @@ -33,32 +44,50 @@ internal class FileRepository( override fun search( query: String, allowNetwork: Boolean, - ) = channelFlow { + ): Flow> { if (query.isBlank()) { - send(persistentListOf()) - return@channelFlow + return flowOf(persistentListOf()) } - settings.enabledProviders.collectLatest { providerIds -> - val providers = providerIds.map { - when (it) { - "local" -> LocalFileProvider(context, permissionsManager) - "gdrive" -> GDriveFileProvider(context) - "nextcloud" -> NextcloudFileProvider(nextcloudClient) - "owncloud" -> OwncloudFileProvider(owncloudClient) - else -> PluginFileProvider(context, it) - } - } + val hasPermission = permissionsManager.hasPermission(PermissionGroup.ExternalStorage) - if (providers.isEmpty()) { - send(persistentListOf()) - return@collectLatest - } - val results = mutableListOf() - for (provider in providers) { - results.addAll(provider.search(query, allowNetwork)) - send(results.toImmutableList()) + + return combineTransform(settings.enabledProviders, hasPermission) { providerIds, permission -> + emit(persistentListOf()) + if (providerIds.isEmpty()) { + return@combineTransform + } + val providers = providerIds.mapNotNull { + when (it) { + "local" -> if (permission) LocalFileProvider( + context, + permissionsManager + ) else null + + "gdrive" -> GDriveFileProvider(context) + "nextcloud" -> NextcloudFileProvider(nextcloudClient) + "owncloud" -> OwncloudFileProvider(owncloudClient) + else -> PluginFileProvider(context, it) } } + + supervisorScope { + val result = MutableStateFlow(persistentListOf()) + + for (provider in providers) { + launch { + val r = provider.search( + query, + allowNetwork, + ) + result.update { + (it + r).toPersistentList() + } + } + } + emitAll(result) + } + + } } } \ No newline at end of file