package eu.kanade.presentation.browse import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import eu.kanade.domain.source.model.installedExtension 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.presentation.components.BulkSelectionToolbar import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter import eu.kanade.tachiyomi.util.system.LocaleHelper import kotlinx.collections.immutable.ImmutableMap import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.domain.source.model.Source as DomainSource @Composable fun GlobalSearchScreen( state: SearchScreenModel.State, navigateUp: () -> Unit, onChangeSearchQuery: (String?) -> Unit, onSearch: (String) -> Unit, onChangeSearchFilter: (SourceFilter) -> Unit, onToggleResults: () -> Unit, getManga: @Composable (Manga) -> State, onClickSource: (CatalogueSource) -> Unit, onClickItem: (Manga) -> Unit, onLongClickItem: (Manga) -> Unit, // KMK --> bulkFavoriteScreenModel: BulkFavoriteScreenModel, hasPinnedSources: Boolean, // KMK <-- ) { // KMK --> val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() // KMK <-- Scaffold( topBar = { scrollBehavior -> // KMK --> if (bulkFavoriteState.selectionMode) { BulkSelectionToolbar( selectedCount = bulkFavoriteState.selection.size, isRunning = bulkFavoriteState.isRunning, onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { state.filteredItems.values .filterIsInstance() .flatMap { it.result } .let { scope.launchIO { bulkFavoriteScreenModel.networkToLocalManga.getLocal(it) .forEach { bulkFavoriteScreenModel.select(it) } } } }, onReverseSelection = { state.filteredItems.values .filterIsInstance() .flatMap { it.result } .let { scope.launchIO { bulkFavoriteScreenModel.reverseSelection( bulkFavoriteScreenModel.networkToLocalManga.getLocal(it), ) } } }, ) } else { // KMK <-- GlobalSearchToolbar( searchQuery = state.searchQuery, progress = state.progress, total = state.total, navigateUp = navigateUp, onChangeSearchQuery = onChangeSearchQuery, onSearch = onSearch, sourceFilter = state.sourceFilter, onChangeSearchFilter = onChangeSearchFilter, onlyShowHasResults = state.onlyShowHasResults, onToggleResults = onToggleResults, scrollBehavior = scrollBehavior, // KMK --> toggleSelectionMode = bulkFavoriteScreenModel::toggleSelectionMode, isRunning = bulkFavoriteState.isRunning, hasPinnedSources = hasPinnedSources, // KMK <-- ) } }, ) { paddingValues -> GlobalSearchContent( items = state.filteredItems, contentPadding = paddingValues, getManga = getManga, onClickSource = onClickSource, onClickItem = onClickItem, onLongClickItem = onLongClickItem, // KMK --> selection = bulkFavoriteState.selection, // KMK <-- ) } } @Composable internal fun GlobalSearchContent( items: ImmutableMap, contentPadding: PaddingValues, getManga: @Composable (Manga) -> State, onClickSource: (CatalogueSource) -> Unit, onClickItem: (Manga) -> Unit, onLongClickItem: (Manga) -> Unit, fromSourceId: Long? = null, // KMK --> selection: List, // KMK <-- ) { LazyColumn( contentPadding = contentPadding, ) { items.forEach { (source, result) -> item(key = "global-search-${source.id}") { // KMK --> val domainSource = DomainSource( source.id, "", "", supportsLatest = false, isStub = false, ) // KMK <-- GlobalSearchResultItem( title = ( fromSourceId?.let { "▶ ${source.name}".takeIf { source.id == fromSourceId } } ?: source.name ) + // KMK --> ( domainSource.installedExtension?.let { extension -> " (${extension.name})".takeIf { extension.name != source.name } } ?: "" ), // KMK <-- subtitle = LocaleHelper.getLocalizedDisplayName(source.lang), onClick = { onClickSource(source) }, modifier = Modifier.animateItem(), ) { when (result) { SearchItemResult.Loading -> { GlobalSearchLoadingResultItem() } is SearchItemResult.Success -> { GlobalSearchCardRow( titles = result.result, getManga = getManga, onClick = onClickItem, onLongClick = onLongClickItem, // KMK --> selection = selection, // KMK <-- ) } is SearchItemResult.Error -> { GlobalSearchErrorResultItem(message = result.throwable.message) } } } } } } }