Fix global search

This commit is contained in:
Koitharu
2024-07-24 11:40:55 +03:00
parent cb4ee2dcca
commit 43c65bf95b
4 changed files with 34 additions and 31 deletions

View File

@@ -13,9 +13,6 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
import java.util.EnumSet
import java.util.Locale
/**
* This parser is just for parser development, it should not be used in releases
*/
class EmptyMangaRepository(override val source: MangaSource) : MangaRepository {
override val sortOrders: Set<SortOrder>

View File

@@ -4,6 +4,7 @@ import androidx.annotation.AnyThread
import androidx.collection.ArrayMap
import org.koitharu.kotatsu.core.cache.MemoryContentCache
import org.koitharu.kotatsu.core.model.LocalMangaSource
import org.koitharu.kotatsu.core.model.MangaSourceInfo
import org.koitharu.kotatsu.core.model.UnknownMangaSource
import org.koitharu.kotatsu.core.network.MirrorSwitchInterceptor
import org.koitharu.kotatsu.local.data.LocalMangaRepository
@@ -69,6 +70,7 @@ interface MangaRepository {
@AnyThread
fun create(source: MangaSource): MangaRepository {
when (source) {
is MangaSourceInfo -> return create(source.mangaSource)
LocalMangaSource -> return localMangaRepository
UnknownMangaSource -> return EmptyMangaRepository(source)
}

View File

@@ -14,8 +14,10 @@ import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.onEmpty
import kotlinx.coroutines.flow.runningFold
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.plus
import kotlinx.coroutines.sync.Semaphore
@@ -112,37 +114,39 @@ class MultiSearchViewModel @Inject constructor(
return@channelFlow
}
val semaphore = Semaphore(MAX_PARALLELISM)
for (source in sources) {
sources.mapNotNull { source ->
val repository = mangaRepositoryFactory.create(source)
if (!repository.isSearchSupported) {
continue
}
launch {
val item = runCatchingCancellable {
semaphore.withPermit {
mangaListMapper.toListModelList(
manga = repository.getList(offset = 0, filter = MangaListFilter.Search(q)),
mode = ListMode.GRID,
)
}
}.fold(
onSuccess = { list ->
if (list.isEmpty()) {
null
} else {
MultiSearchListModel(source, list.size > MIN_HAS_MORE_ITEMS, list, null)
null
} else {
launch {
val item = runCatchingCancellable {
semaphore.withPermit {
mangaListMapper.toListModelList(
manga = repository.getList(offset = 0, filter = MangaListFilter.Search(q)),
mode = ListMode.GRID,
)
}
},
onFailure = { error ->
error.printStackTraceDebug()
MultiSearchListModel(source, true, emptyList(), error)
},
)
if (item != null) {
send(item)
}.fold(
onSuccess = { list ->
if (list.isEmpty()) {
null
} else {
MultiSearchListModel(source, list.size > MIN_HAS_MORE_ITEMS, list, null)
}
},
onFailure = { error ->
error.printStackTraceDebug()
MultiSearchListModel(source, true, emptyList(), error)
},
)
if (item != null) {
send(item)
}
}
}
}
}.joinAll()
}.runningFold<MultiSearchListModel, List<MultiSearchListModel>?>(null) { list, item -> list.orEmpty() + item }
.filterNotNull()
.onEmpty { emit(emptyList()) }
}