فهرست منبع

Dedupe Global/MigrateSearchContent composables

arkon 1 سال پیش
والد
کامیت
8b46e8edad

+ 6 - 12
app/src/main/java/eu/kanade/presentation/browse/GlobalSearchScreen.kt

@@ -24,6 +24,7 @@ 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.GlobalSearchEmptyResultItem
 import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
 import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
 import eu.kanade.presentation.browse.components.GlobalSearchResultItem
@@ -43,7 +44,6 @@ import tachiyomi.presentation.core.components.material.padding
 @Composable
 fun GlobalSearchScreen(
     state: GlobalSearchScreenModel.State,
-    items: Map<CatalogueSource, SearchItemResult>,
     navigateUp: () -> Unit,
     onChangeSearchQuery: (String?) -> Unit,
     onSearch: (String) -> Unit,
@@ -129,7 +129,7 @@ fun GlobalSearchScreen(
         },
     ) { paddingValues ->
         GlobalSearchContent(
-            items = items,
+            items = state.filteredItems,
             contentPadding = paddingValues,
             getManga = getManga,
             onClickSource = onClickSource,
@@ -140,7 +140,8 @@ fun GlobalSearchScreen(
 }
 
 @Composable
-private fun GlobalSearchContent(
+internal fun GlobalSearchContent(
+    sourceId: Long? = null,
     items: Map<CatalogueSource, SearchItemResult>,
     contentPadding: PaddingValues,
     getManga: @Composable (Manga) -> State<Manga>,
@@ -154,7 +155,7 @@ private fun GlobalSearchContent(
         items.forEach { (source, result) ->
             item(key = source.id) {
                 GlobalSearchResultItem(
-                    title = source.name,
+                    title = sourceId?.let { "▶ ${source.name}".takeIf { source.id == sourceId } } ?: source.name,
                     subtitle = LocaleHelper.getDisplayName(source.lang),
                     onClick = { onClickSource(source) },
                 ) {
@@ -164,14 +165,7 @@ private fun GlobalSearchContent(
                         }
                         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,
-                                        ),
-                                )
+                                GlobalSearchEmptyResultItem()
                                 return@GlobalSearchResultItem
                             }
 

+ 4 - 60
app/src/main/java/eu/kanade/presentation/browse/MigrateSearchScreen.kt

@@ -1,26 +1,17 @@
 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 eu.kanade.presentation.browse.components.GlobalSearchCardRow
-import eu.kanade.presentation.browse.components.GlobalSearchEmptyResultItem
-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.source.CatalogueSource
-import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchState
-import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
-import eu.kanade.tachiyomi.util.system.LocaleHelper
+import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreenModel
 import tachiyomi.domain.manga.model.Manga
 import tachiyomi.presentation.core.components.material.Scaffold
 
 @Composable
 fun MigrateSearchScreen(
     navigateUp: () -> Unit,
-    state: MigrateSearchState,
+    state: MigrateSearchScreenModel.State,
     getManga: @Composable (Manga) -> State<Manga>,
     onChangeSearchQuery: (String?) -> Unit,
     onSearch: (String) -> Unit,
@@ -41,8 +32,8 @@ fun MigrateSearchScreen(
             )
         },
     ) { paddingValues ->
-        MigrateSearchContent(
-            sourceId = state.manga?.source ?: -1,
+        GlobalSearchContent(
+            sourceId = state.manga?.source,
             items = state.items,
             contentPadding = paddingValues,
             getManga = getManga,
@@ -52,50 +43,3 @@ fun MigrateSearchScreen(
         )
     }
 }
-
-@Composable
-private fun MigrateSearchContent(
-    sourceId: Long,
-    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 = if (source.id == sourceId) "▶ ${source.name}" else source.name,
-                    subtitle = LocaleHelper.getDisplayName(source.lang),
-                    onClick = { onClickSource(source) },
-                ) {
-                    when (result) {
-                        SearchItemResult.Loading -> {
-                            GlobalSearchLoadingResultItem()
-                        }
-                        is SearchItemResult.Success -> {
-                            if (result.isEmpty) {
-                                GlobalSearchEmptyResultItem()
-                                return@GlobalSearchResultItem
-                            }
-
-                            GlobalSearchCardRow(
-                                titles = result.result,
-                                getManga = getManga,
-                                onClick = onClickItem,
-                                onLongClick = onLongClickItem,
-                            )
-                        }
-                        is SearchItemResult.Error -> {
-                            GlobalSearchErrorResultItem(message = result.throwable.message)
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

+ 12 - 16
app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenModel.kt

@@ -17,15 +17,13 @@ import uy.kohesive.injekt.api.get
 
 class MigrateSearchScreenModel(
     val mangaId: Long,
-    initialExtensionFilter: String = "",
     preferences: BasePreferences = Injekt.get(),
     private val sourcePreferences: SourcePreferences = Injekt.get(),
     private val sourceManager: SourceManager = Injekt.get(),
     private val getManga: GetManga = Injekt.get(),
-) : SearchScreenModel<MigrateSearchState>(MigrateSearchState()) {
+) : SearchScreenModel<MigrateSearchScreenModel.State>(State()) {
 
     init {
-        extensionFilter = initialExtensionFilter
         coroutineScope.launch {
             val manga = getManga.await(mangaId)!!
 
@@ -73,21 +71,19 @@ class MigrateSearchScreenModel(
             it.copy(dialog = dialog)
         }
     }
+
+    @Immutable
+    data class State(
+        val manga: Manga? = null,
+        val searchQuery: String? = null,
+        val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
+        val dialog: MigrateSearchDialog? = null,
+    ) {
+        val progress: Int = items.count { it.value !is SearchItemResult.Loading }
+        val total: Int = items.size
+    }
 }
 
 sealed class MigrateSearchDialog {
     data class Migrate(val manga: Manga) : MigrateSearchDialog()
 }
-
-@Immutable
-data class MigrateSearchState(
-    val manga: Manga? = null,
-    val searchQuery: String? = null,
-    val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
-    val dialog: MigrateSearchDialog? = null,
-) {
-
-    val progress: Int = items.count { it.value !is SearchItemResult.Loading }
-
-    val total: Int = items.size
-}

+ 2 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreen.kt

@@ -18,7 +18,7 @@ import tachiyomi.presentation.core.screens.LoadingScreen
 
 class GlobalSearchScreen(
     val searchQuery: String = "",
-    private val extensionFilter: String = "",
+    private val extensionFilter: String? = null,
 ) : Screen() {
 
     @Composable
@@ -33,9 +33,8 @@ class GlobalSearchScreen(
         }
         val state by screenModel.state.collectAsState()
         var showSingleLoadingScreen by remember {
-            mutableStateOf(searchQuery.isNotEmpty() && extensionFilter.isNotEmpty() && state.total == 1)
+            mutableStateOf(searchQuery.isNotEmpty() && !extensionFilter.isNullOrEmpty() && state.total == 1)
         }
-        val filteredSources by screenModel.searchPagerFlow.collectAsState()
 
         if (showSingleLoadingScreen) {
             LoadingScreen()
@@ -58,7 +57,6 @@ class GlobalSearchScreen(
         } else {
             GlobalSearchScreen(
                 state = state,
-                items = filteredSources,
                 navigateUp = navigator::pop,
                 onChangeSearchQuery = screenModel::updateSearchQuery,
                 onSearch = screenModel::search,

+ 7 - 19
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreenModel.kt

@@ -3,12 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch
 import androidx.compose.runtime.Immutable
 import eu.kanade.domain.base.BasePreferences
 import eu.kanade.domain.source.service.SourcePreferences
-import eu.kanade.presentation.util.ioCoroutineScope
 import eu.kanade.tachiyomi.source.CatalogueSource
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.update
 import tachiyomi.domain.source.service.SourceManager
 import uy.kohesive.injekt.Injekt
@@ -16,7 +11,7 @@ import uy.kohesive.injekt.api.get
 
 class GlobalSearchScreenModel(
     initialQuery: String = "",
-    initialExtensionFilter: String = "",
+    initialExtensionFilter: String? = null,
     preferences: BasePreferences = Injekt.get(),
     private val sourcePreferences: SourcePreferences = Injekt.get(),
     private val sourceManager: SourceManager = Injekt.get(),
@@ -24,17 +19,9 @@ class GlobalSearchScreenModel(
 
     val incognitoMode = preferences.incognitoMode()
     val lastUsedSourceId = sourcePreferences.lastUsedSource()
-
-    val searchPagerFlow = state.map { Pair(it.onlyShowHasResults, it.items) }
-        .distinctUntilChanged()
-        .map { (onlyShowHasResults, items) ->
-            items.filter { (_, result) -> result.isVisible(onlyShowHasResults) }
-        }
-        .stateIn(ioCoroutineScope, SharingStarted.Lazily, state.value.items)
-
     init {
         extensionFilter = initialExtensionFilter
-        if (initialQuery.isNotBlank() || initialExtensionFilter.isNotBlank()) {
+        if (initialQuery.isNotBlank() || !initialExtensionFilter.isNullOrBlank()) {
             search(initialQuery)
         }
     }
@@ -77,10 +64,6 @@ class GlobalSearchScreenModel(
         }
     }
 
-    private fun SearchItemResult.isVisible(onlyShowHasResults: Boolean): Boolean {
-        return !onlyShowHasResults || (this is SearchItemResult.Success && !this.isEmpty)
-    }
-
     @Immutable
     data class State(
         val searchQuery: String? = null,
@@ -90,5 +73,10 @@ class GlobalSearchScreenModel(
     ) {
         val progress: Int = items.count { it.value !is SearchItemResult.Loading }
         val total: Int = items.size
+        val filteredItems = items.filter { (_, result) -> result.isVisible(onlyShowHasResults) }
     }
 }
+
+private fun SearchItemResult.isVisible(onlyShowHasResults: Boolean): Boolean {
+    return !onlyShowHasResults || (this is SearchItemResult.Success && !this.isEmpty)
+}

+ 3 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt

@@ -36,7 +36,7 @@ abstract class SearchScreenModel<T>(
     private val coroutineDispatcher = Executors.newFixedThreadPool(5).asCoroutineDispatcher()
 
     protected var query: String? = null
-    protected lateinit var extensionFilter: String
+    protected var extensionFilter: String? = null
 
     private val sources by lazy { getSelectedSources() }
     private val pinnedSources by lazy { sourcePreferences.pinnedSources().get() }
@@ -63,11 +63,10 @@ abstract class SearchScreenModel<T>(
     abstract fun getEnabledSources(): List<CatalogueSource>
 
     private fun getSelectedSources(): List<CatalogueSource> {
-        val filter = extensionFilter
-
         val enabledSources = getEnabledSources()
 
-        if (filter.isEmpty()) {
+        val filter = extensionFilter
+        if (filter.isNullOrEmpty()) {
             return enabledSources
         }
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -416,7 +416,7 @@ class MainActivity : BaseActivity() {
             INTENT_SEARCH -> {
                 val query = intent.getStringExtra(INTENT_SEARCH_QUERY)
                 if (!query.isNullOrEmpty()) {
-                    val filter = intent.getStringExtra(INTENT_SEARCH_FILTER) ?: ""
+                    val filter = intent.getStringExtra(INTENT_SEARCH_FILTER)
                     navigator.popUntilRoot()
                     navigator.push(GlobalSearchScreen(query, filter))
                 }