190 lines
7.9 KiB
Kotlin
Raw Normal View History

package eu.kanade.presentation.browse
import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material.icons.outlined.PushPin
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
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.GlobalSearchFilter
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
2023-01-22 10:54:28 -05:00
import tachiyomi.domain.manga.model.Manga
import tachiyomi.presentation.core.components.material.Divider
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.padding
@Composable
fun GlobalSearchScreen(
state: GlobalSearchState,
items: Map<CatalogueSource, SearchItemResult>,
navigateUp: () -> Unit,
onChangeSearchQuery: (String?) -> Unit,
onSearch: (String) -> Unit,
onChangeFilter: (GlobalSearchFilter) -> Unit,
getManga: @Composable (Manga) -> State<Manga>,
onClickSource: (CatalogueSource) -> Unit,
onClickItem: (Manga) -> Unit,
onLongClickItem: (Manga) -> Unit,
) {
Scaffold(
2022-11-27 15:16:08 -05:00
topBar = { scrollBehavior ->
Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
GlobalSearchToolbar(
searchQuery = state.searchQuery,
progress = state.progress,
total = state.total,
navigateUp = navigateUp,
onChangeSearchQuery = onChangeSearchQuery,
onSearch = onSearch,
scrollBehavior = scrollBehavior,
)
Row(
modifier = Modifier
.horizontalScroll(rememberScrollState())
.padding(horizontal = MaterialTheme.padding.small),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
FilterChip(
selected = state.searchFilter == GlobalSearchFilter.All,
onClick = { onChangeFilter(GlobalSearchFilter.All) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.DoneAll,
contentDescription = "",
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(id = R.string.all))
},
)
FilterChip(
selected = state.searchFilter == GlobalSearchFilter.PinnedOnly,
onClick = { onChangeFilter(GlobalSearchFilter.PinnedOnly) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.PushPin,
contentDescription = "",
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(id = R.string.pinned_sources))
},
)
FilterChip(
selected = state.searchFilter == GlobalSearchFilter.AvailableOnly,
onClick = { onChangeFilter(GlobalSearchFilter.AvailableOnly) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.FilterList,
contentDescription = "",
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(id = R.string.has_results))
},
)
}
Divider()
}
},
) { paddingValues ->
GlobalSearchContent(
items = 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(
2022-11-27 15:16:08 -05:00
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,
onClick = onClickItem,
onLongClick = onLongClickItem,
)
}
is SearchItemResult.Error -> {
GlobalSearchErrorResultItem(message = result.throwable.message)
}
}
}
}
}
}
}