Run file search providers in parallel

This commit is contained in:
MM20 2024-07-26 20:54:00 +02:00
parent 8593758f41
commit 87f91aee74
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389

View File

@ -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<ImmutableList<File>> {
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<File>()
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<File>())
for (provider in providers) {
launch {
val r = provider.search(
query,
allowNetwork,
)
result.update {
(it + r).toPersistentList()
}
}
}
emitAll(result)
}
}
}
}