mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 15:32:01 +00:00
ref: publish search catalogs as they arrive
This commit is contained in:
parent
5cdda57913
commit
95708b9b79
2 changed files with 64 additions and 9 deletions
|
|
@ -20,11 +20,11 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.awaitAll
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.joinAll
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import nuvio.composeapp.generated.resources.*
|
import nuvio.composeapp.generated.resources.*
|
||||||
import org.jetbrains.compose.resources.getString
|
import org.jetbrains.compose.resources.getString
|
||||||
|
|
@ -91,16 +91,57 @@ object SearchRepository {
|
||||||
_uiState.value = SearchUiState(isLoading = true)
|
_uiState.value = SearchUiState(isLoading = true)
|
||||||
|
|
||||||
activeJob = scope.launch {
|
activeJob = scope.launch {
|
||||||
val results = requests.map { request ->
|
val resultChannel = Channel<IndexedSearchResult>(Channel.UNLIMITED)
|
||||||
async {
|
val jobs = requests.mapIndexed { index, request ->
|
||||||
|
launch {
|
||||||
runCatching { request.toSection() }
|
runCatching { request.toSection() }
|
||||||
|
.fold(
|
||||||
|
onSuccess = { section ->
|
||||||
|
resultChannel.send(
|
||||||
|
IndexedSearchResult(
|
||||||
|
index = index,
|
||||||
|
section = section,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onFailure = { error ->
|
||||||
|
if (error is CancellationException) throw error
|
||||||
|
resultChannel.send(
|
||||||
|
IndexedSearchResult(
|
||||||
|
index = index,
|
||||||
|
error = error,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.awaitAll()
|
}
|
||||||
|
val closeChannelJob = launch {
|
||||||
|
jobs.joinAll()
|
||||||
|
resultChannel.close()
|
||||||
|
}
|
||||||
|
val results = arrayOfNulls<IndexedSearchResult>(requests.size)
|
||||||
|
|
||||||
val sections = results
|
try {
|
||||||
.mapNotNull { it.getOrNull() }
|
for (result in resultChannel) {
|
||||||
val firstFailure = results.firstNotNullOfOrNull { it.exceptionOrNull()?.message }
|
results[result.index] = result
|
||||||
val allFailed = results.isNotEmpty() && results.all { it.isFailure }
|
val sections = results.orderedSections()
|
||||||
|
if (sections.isNotEmpty()) {
|
||||||
|
_uiState.value = SearchUiState(
|
||||||
|
isLoading = true,
|
||||||
|
sections = sections,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
closeChannelJob.cancel()
|
||||||
|
resultChannel.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
val completedResults = results.filterNotNull()
|
||||||
|
val sections = results.orderedSections()
|
||||||
|
val firstFailure = completedResults.firstNotNullOfOrNull { it.error?.message }
|
||||||
|
val allFailed = completedResults.isNotEmpty() && completedResults.all { it.error != null }
|
||||||
|
|
||||||
_uiState.value = SearchUiState(
|
_uiState.value = SearchUiState(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
|
|
@ -436,6 +477,15 @@ object SearchRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private data class IndexedSearchResult(
|
||||||
|
val index: Int,
|
||||||
|
val section: HomeCatalogSection? = null,
|
||||||
|
val error: Throwable? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun Array<IndexedSearchResult?>.orderedSections(): List<HomeCatalogSection> =
|
||||||
|
mapNotNull { result -> result?.section }
|
||||||
|
|
||||||
private fun CatalogPage.withUnreleasedFilter(): CatalogPage {
|
private fun CatalogPage.withUnreleasedFilter(): CatalogPage {
|
||||||
if (!HomeCatalogSettingsRepository.snapshot().hideUnreleasedContent) return this
|
if (!HomeCatalogSettingsRepository.snapshot().hideUnreleasedContent) return this
|
||||||
val filteredItems = items.filterReleasedItems(CurrentDateProvider.todayIsoDate())
|
val filteredItems = items.filterReleasedItems(CurrentDateProvider.todayIsoDate())
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,11 @@ fun SearchScreen(
|
||||||
onPosterLongClick = onPosterLongClick,
|
onPosterLongClick = onPosterLongClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (uiState.isLoading) {
|
||||||
|
item(key = "search_loading_more") {
|
||||||
|
HomeSkeletonRow(modifier = Modifier.padding(horizontal = homeSectionPadding))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue