1a61130f0b
This was effectively DDoSing sources as it does a request for every entry to get the details (primarily a cover image). The expectation now is that users have to open individual entries to load the details/cover if needed. This isn't necessary for most sources, which are able to provide covers as part of the listing normally.
113 lines
4.4 KiB
Kotlin
113 lines
4.4 KiB
Kotlin
package eu.kanade.presentation.browse
|
|
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.State
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.res.stringResource
|
|
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
|
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
|
|
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
|
|
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
|
|
import eu.kanade.presentation.browse.components.GlobalSearchToolbar
|
|
import eu.kanade.tachiyomi.R
|
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchState
|
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
|
import tachiyomi.domain.manga.model.Manga
|
|
import tachiyomi.presentation.core.components.LazyColumn
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
import tachiyomi.presentation.core.components.material.padding
|
|
|
|
@Composable
|
|
fun GlobalSearchScreen(
|
|
state: GlobalSearchState,
|
|
navigateUp: () -> Unit,
|
|
onChangeSearchQuery: (String?) -> Unit,
|
|
onSearch: (String) -> Unit,
|
|
getManga: @Composable (Manga) -> State<Manga>,
|
|
onClickSource: (CatalogueSource) -> Unit,
|
|
onClickItem: (Manga) -> Unit,
|
|
onLongClickItem: (Manga) -> Unit,
|
|
) {
|
|
Scaffold(
|
|
topBar = { scrollBehavior ->
|
|
GlobalSearchToolbar(
|
|
searchQuery = state.searchQuery,
|
|
progress = state.progress,
|
|
total = state.total,
|
|
navigateUp = navigateUp,
|
|
onChangeSearchQuery = onChangeSearchQuery,
|
|
onSearch = onSearch,
|
|
scrollBehavior = scrollBehavior,
|
|
)
|
|
},
|
|
) { paddingValues ->
|
|
GlobalSearchContent(
|
|
items = state.items,
|
|
contentPadding = paddingValues,
|
|
getManga = getManga,
|
|
onClickSource = onClickSource,
|
|
onClickItem = onClickItem,
|
|
onLongClickItem = onLongClickItem,
|
|
)
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun GlobalSearchContent(
|
|
items: Map<CatalogueSource, SearchItemResult>,
|
|
contentPadding: PaddingValues,
|
|
getManga: @Composable (Manga) -> State<Manga>,
|
|
onClickSource: (CatalogueSource) -> Unit,
|
|
onClickItem: (Manga) -> Unit,
|
|
onLongClickItem: (Manga) -> Unit,
|
|
) {
|
|
LazyColumn(
|
|
contentPadding = contentPadding,
|
|
) {
|
|
items.forEach { (source, result) ->
|
|
item(key = source.id) {
|
|
GlobalSearchResultItem(
|
|
title = source.name,
|
|
subtitle = LocaleHelper.getDisplayName(source.lang),
|
|
onClick = { onClickSource(source) },
|
|
) {
|
|
when (result) {
|
|
SearchItemResult.Loading -> {
|
|
GlobalSearchLoadingResultItem()
|
|
}
|
|
is SearchItemResult.Success -> {
|
|
if (result.isEmpty) {
|
|
Text(
|
|
text = stringResource(R.string.no_results_found),
|
|
modifier = Modifier
|
|
.padding(
|
|
horizontal = MaterialTheme.padding.medium,
|
|
vertical = MaterialTheme.padding.small,
|
|
),
|
|
)
|
|
return@GlobalSearchResultItem
|
|
}
|
|
|
|
GlobalSearchCardRow(
|
|
titles = result.result,
|
|
getManga = { getManga(it) },
|
|
onClick = onClickItem,
|
|
onLongClick = onLongClickItem,
|
|
)
|
|
}
|
|
is SearchItemResult.Error -> {
|
|
GlobalSearchErrorResultItem(message = result.throwable.message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|