mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	@@ -19,8 +19,8 @@ import eu.kanade.presentation.components.Scaffold
 | 
			
		||||
import eu.kanade.presentation.util.padding
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItemResult
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@@ -60,7 +60,7 @@ fun GlobalSearchScreen(
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun GlobalSearchContent(
 | 
			
		||||
    items: Map<CatalogueSource, GlobalSearchItemResult>,
 | 
			
		||||
    items: Map<CatalogueSource, SearchItemResult>,
 | 
			
		||||
    contentPadding: PaddingValues,
 | 
			
		||||
    getManga: @Composable (CatalogueSource, Manga) -> State<Manga>,
 | 
			
		||||
    onClickSource: (CatalogueSource) -> Unit,
 | 
			
		||||
@@ -78,13 +78,13 @@ fun GlobalSearchContent(
 | 
			
		||||
                    onClick = { onClickSource(source) },
 | 
			
		||||
                ) {
 | 
			
		||||
                    when (result) {
 | 
			
		||||
                        is GlobalSearchItemResult.Error -> {
 | 
			
		||||
                        is SearchItemResult.Error -> {
 | 
			
		||||
                            GlobalSearchErrorResultItem(message = result.throwable.message)
 | 
			
		||||
                        }
 | 
			
		||||
                        GlobalSearchItemResult.Loading -> {
 | 
			
		||||
                        SearchItemResult.Loading -> {
 | 
			
		||||
                            GlobalSearchLoadingResultItem()
 | 
			
		||||
                        }
 | 
			
		||||
                        is GlobalSearchItemResult.Success -> {
 | 
			
		||||
                        is SearchItemResult.Success -> {
 | 
			
		||||
                            if (result.isEmpty) {
 | 
			
		||||
                                Text(
 | 
			
		||||
                                    text = stringResource(R.string.no_results_found),
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ import eu.kanade.presentation.components.LazyColumn
 | 
			
		||||
import eu.kanade.presentation.components.Scaffold
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchState
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItemResult
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
@@ -56,7 +56,7 @@ fun MigrateSearchScreen(
 | 
			
		||||
@Composable
 | 
			
		||||
fun MigrateSearchContent(
 | 
			
		||||
    sourceId: Long,
 | 
			
		||||
    items: Map<CatalogueSource, GlobalSearchItemResult>,
 | 
			
		||||
    items: Map<CatalogueSource, SearchItemResult>,
 | 
			
		||||
    contentPadding: PaddingValues,
 | 
			
		||||
    getManga: @Composable (CatalogueSource, Manga) -> State<Manga>,
 | 
			
		||||
    onClickSource: (CatalogueSource) -> Unit,
 | 
			
		||||
@@ -74,13 +74,13 @@ fun MigrateSearchContent(
 | 
			
		||||
                    onClick = { onClickSource(source) },
 | 
			
		||||
                ) {
 | 
			
		||||
                    when (result) {
 | 
			
		||||
                        is GlobalSearchItemResult.Error -> {
 | 
			
		||||
                        is SearchItemResult.Error -> {
 | 
			
		||||
                            GlobalSearchErrorResultItem(message = result.throwable.message)
 | 
			
		||||
                        }
 | 
			
		||||
                        GlobalSearchItemResult.Loading -> {
 | 
			
		||||
                        SearchItemResult.Loading -> {
 | 
			
		||||
                            GlobalSearchLoadingResultItem()
 | 
			
		||||
                        }
 | 
			
		||||
                        is GlobalSearchItemResult.Success -> {
 | 
			
		||||
                        is SearchItemResult.Success -> {
 | 
			
		||||
                            if (result.isEmpty) {
 | 
			
		||||
                                GlobalSearchEmptyResultItem()
 | 
			
		||||
                                return@GlobalSearchResultItem
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import eu.kanade.domain.manga.model.Manga
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItemResult
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
 | 
			
		||||
import kotlinx.coroutines.flow.update
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
@@ -58,13 +58,13 @@ class MigrateSearchScreenModel(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun updateItems(items: Map<CatalogueSource, GlobalSearchItemResult>) {
 | 
			
		||||
    override fun updateItems(items: Map<CatalogueSource, SearchItemResult>) {
 | 
			
		||||
        mutableState.update {
 | 
			
		||||
            it.copy(items = items)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getItems(): Map<CatalogueSource, GlobalSearchItemResult> {
 | 
			
		||||
    override fun getItems(): Map<CatalogueSource, SearchItemResult> {
 | 
			
		||||
        return mutableState.value.items
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -83,11 +83,11 @@ sealed class MigrateSearchDialog {
 | 
			
		||||
data class MigrateSearchState(
 | 
			
		||||
    val manga: Manga? = null,
 | 
			
		||||
    val searchQuery: String? = null,
 | 
			
		||||
    val items: Map<CatalogueSource, GlobalSearchItemResult> = emptyMap(),
 | 
			
		||||
    val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
 | 
			
		||||
    val dialog: MigrateSearchDialog? = null,
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    val progress: Int = items.count { it.value !is GlobalSearchItemResult.Loading }
 | 
			
		||||
    val progress: Int = items.count { it.value !is SearchItemResult.Loading }
 | 
			
		||||
 | 
			
		||||
    val total: Int = items.size
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
import eu.kanade.domain.manga.model.Manga
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
@@ -45,39 +44,24 @@ class GlobalSearchScreenModel(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun updateItems(items: Map<CatalogueSource, GlobalSearchItemResult>) {
 | 
			
		||||
    override fun updateItems(items: Map<CatalogueSource, SearchItemResult>) {
 | 
			
		||||
        mutableState.update {
 | 
			
		||||
            it.copy(items = items)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getItems(): Map<CatalogueSource, GlobalSearchItemResult> {
 | 
			
		||||
    override fun getItems(): Map<CatalogueSource, SearchItemResult> {
 | 
			
		||||
        return mutableState.value.items
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sealed class GlobalSearchItemResult {
 | 
			
		||||
    object Loading : GlobalSearchItemResult()
 | 
			
		||||
 | 
			
		||||
    data class Error(
 | 
			
		||||
        val throwable: Throwable,
 | 
			
		||||
    ) : GlobalSearchItemResult()
 | 
			
		||||
 | 
			
		||||
    data class Success(
 | 
			
		||||
        val result: List<Manga>,
 | 
			
		||||
    ) : GlobalSearchItemResult() {
 | 
			
		||||
        val isEmpty: Boolean
 | 
			
		||||
            get() = result.isEmpty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Immutable
 | 
			
		||||
data class GlobalSearchState(
 | 
			
		||||
    val searchQuery: String? = null,
 | 
			
		||||
    val items: Map<CatalogueSource, GlobalSearchItemResult> = emptyMap(),
 | 
			
		||||
    val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    val progress: Int = items.count { it.value !is GlobalSearchItemResult.Loading }
 | 
			
		||||
    val progress: Int = items.count { it.value !is SearchItemResult.Loading }
 | 
			
		||||
 | 
			
		||||
    val total: Int = items.size
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,15 @@ abstract class SearchScreenModel<T>(
 | 
			
		||||
    protected lateinit var extensionFilter: String
 | 
			
		||||
 | 
			
		||||
    private val sources by lazy { getSelectedSources() }
 | 
			
		||||
    private val pinnedSources by lazy { sourcePreferences.pinnedSources().get() }
 | 
			
		||||
 | 
			
		||||
    private val sortComparator = { map: Map<CatalogueSource, SearchItemResult> ->
 | 
			
		||||
        compareBy<CatalogueSource>(
 | 
			
		||||
            { (map[it] as? SearchItemResult.Success)?.isEmpty ?: true },
 | 
			
		||||
            { "${it.id}" !in pinnedSources },
 | 
			
		||||
            { "${it.name.lowercase()} (${it.lang})" },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Composable
 | 
			
		||||
    fun getManga(source: CatalogueSource, initialManga: Manga): State<Manga> {
 | 
			
		||||
@@ -107,11 +116,11 @@ abstract class SearchScreenModel<T>(
 | 
			
		||||
 | 
			
		||||
    abstract fun updateSearchQuery(query: String?)
 | 
			
		||||
 | 
			
		||||
    abstract fun updateItems(items: Map<CatalogueSource, GlobalSearchItemResult>)
 | 
			
		||||
    abstract fun updateItems(items: Map<CatalogueSource, SearchItemResult>)
 | 
			
		||||
 | 
			
		||||
    abstract fun getItems(): Map<CatalogueSource, GlobalSearchItemResult>
 | 
			
		||||
    abstract fun getItems(): Map<CatalogueSource, SearchItemResult>
 | 
			
		||||
 | 
			
		||||
    fun getAndUpdateItems(function: (Map<CatalogueSource, GlobalSearchItemResult>) -> Map<CatalogueSource, GlobalSearchItemResult>) {
 | 
			
		||||
    fun getAndUpdateItems(function: (Map<CatalogueSource, SearchItemResult>) -> Map<CatalogueSource, SearchItemResult>) {
 | 
			
		||||
        updateItems(function(getItems()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -120,19 +129,9 @@ abstract class SearchScreenModel<T>(
 | 
			
		||||
 | 
			
		||||
        this.query = query
 | 
			
		||||
 | 
			
		||||
        val initialItems = getSelectedSources().associateWith { GlobalSearchItemResult.Loading }
 | 
			
		||||
        val initialItems = getSelectedSources().associateWith { SearchItemResult.Loading }
 | 
			
		||||
        updateItems(initialItems)
 | 
			
		||||
 | 
			
		||||
        val pinnedSources = sourcePreferences.pinnedSources().get()
 | 
			
		||||
 | 
			
		||||
        val comparator = { mutableMap: MutableMap<CatalogueSource, GlobalSearchItemResult> ->
 | 
			
		||||
            compareBy<CatalogueSource>(
 | 
			
		||||
                { mutableMap[it] is GlobalSearchItemResult.Success },
 | 
			
		||||
                { "${it.id}" in pinnedSources },
 | 
			
		||||
                { "${it.name.lowercase()} (${it.lang})" },
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
            sources.forEach { source ->
 | 
			
		||||
                val page = try {
 | 
			
		||||
@@ -142,9 +141,8 @@ abstract class SearchScreenModel<T>(
 | 
			
		||||
                } catch (e: Exception) {
 | 
			
		||||
                    getAndUpdateItems { items ->
 | 
			
		||||
                        val mutableMap = items.toMutableMap()
 | 
			
		||||
                        mutableMap[source] = GlobalSearchItemResult.Error(throwable = e)
 | 
			
		||||
                        mutableMap.toSortedMap(comparator(mutableMap))
 | 
			
		||||
                        mutableMap.toMap()
 | 
			
		||||
                        mutableMap[source] = SearchItemResult.Error(throwable = e)
 | 
			
		||||
                        mutableMap.toSortedMap(sortComparator(mutableMap))
 | 
			
		||||
                    }
 | 
			
		||||
                    return@forEach
 | 
			
		||||
                }
 | 
			
		||||
@@ -157,11 +155,25 @@ abstract class SearchScreenModel<T>(
 | 
			
		||||
 | 
			
		||||
                getAndUpdateItems { items ->
 | 
			
		||||
                    val mutableMap = items.toMutableMap()
 | 
			
		||||
                    mutableMap[source] = GlobalSearchItemResult.Success(titles)
 | 
			
		||||
                    mutableMap.toSortedMap(comparator(mutableMap))
 | 
			
		||||
                    mutableMap.toMap()
 | 
			
		||||
                    mutableMap[source] = SearchItemResult.Success(titles)
 | 
			
		||||
                    mutableMap.toSortedMap(sortComparator(mutableMap))
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sealed class SearchItemResult {
 | 
			
		||||
    object Loading : SearchItemResult()
 | 
			
		||||
 | 
			
		||||
    data class Error(
 | 
			
		||||
        val throwable: Throwable,
 | 
			
		||||
    ) : SearchItemResult()
 | 
			
		||||
 | 
			
		||||
    data class Success(
 | 
			
		||||
        val result: List<Manga>,
 | 
			
		||||
    ) : SearchItemResult() {
 | 
			
		||||
        val isEmpty: Boolean
 | 
			
		||||
            get() = result.isEmpty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user