diff --git a/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt index 0da255514..24e68ea82 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt @@ -28,7 +28,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import eu.kanade.domain.source.interactor.GetRemoteManga import eu.kanade.domain.source.model.Pin import eu.kanade.domain.source.model.Source import eu.kanade.presentation.browse.components.BaseSourceItem @@ -42,13 +41,14 @@ import eu.kanade.presentation.util.topSmallPaddingValues import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.ui.browse.source.SourcesState +import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing import eu.kanade.tachiyomi.util.system.LocaleHelper @Composable fun SourcesScreen( state: SourcesState, contentPadding: PaddingValues, - onClickItem: (Source, String) -> Unit, + onClickItem: (Source, Listing) -> Unit, onClickPin: (Source) -> Unit, onLongClickItem: (Source) -> Unit, ) { @@ -136,18 +136,18 @@ private fun SourceItem( showLatest: Boolean, showPin: Boolean, // SY <-- - onClickItem: (Source, String) -> Unit, + onClickItem: (Source, Listing) -> Unit, onLongClickItem: (Source) -> Unit, onClickPin: (Source) -> Unit, ) { BaseSourceItem( modifier = modifier, source = source, - onClickItem = { onClickItem(source, GetRemoteManga.QUERY_POPULAR) }, + onClickItem = { onClickItem(source, Listing.Popular) }, onLongClickItem = { onLongClickItem(source) }, action = { if (source.supportsLatest /* SY --> */ && showLatest /* SY <-- */) { - TextButton(onClick = { onClickItem(source, GetRemoteManga.QUERY_LATEST) }) { + TextButton(onClick = { onClickItem(source, Listing.Latest) }) { Text( text = stringResource(R.string.latest), style = LocalTextStyle.current.copy( diff --git a/app/src/main/java/eu/kanade/presentation/components/AppBar.kt b/app/src/main/java/eu/kanade/presentation/components/AppBar.kt index f94513bb7..db26ca0a4 100644 --- a/app/src/main/java/eu/kanade/presentation/components/AppBar.kt +++ b/app/src/main/java/eu/kanade/presentation/components/AppBar.kt @@ -240,7 +240,8 @@ fun SearchToolbar( val keyboardController = LocalSoftwareKeyboardController.current val focusManager = LocalFocusManager.current - val searchAndClearFocus: () -> Unit = { + val searchAndClearFocus: () -> Unit = f@{ + if (searchQuery.isBlank()) return@f onSearch(searchQuery) focusManager.clearFocus() keyboardController?.hide() diff --git a/app/src/main/java/eu/kanade/presentation/more/NewUpdateScreen.kt b/app/src/main/java/eu/kanade/presentation/more/NewUpdateScreen.kt index 0e881a161..0d6909461 100644 --- a/app/src/main/java/eu/kanade/presentation/more/NewUpdateScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/NewUpdateScreen.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.OpenInNew import androidx.compose.material.icons.outlined.NewReleases -import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBarDefaults @@ -68,7 +67,7 @@ fun NewUpdateScreen( vertical = MaterialTheme.padding.small, ), ) { - Button( + TextButton( modifier = Modifier.fillMaxWidth(), onClick = onAcceptUpdate, ) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt index 79dd386e3..2506f44e5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt @@ -50,6 +50,7 @@ fun Screen.feedTab(): TabContent { navigator.push( BrowseSourceScreen( source.id, + listingQuery = null, savedSearch = savedSearch.id, ), ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt index 4785bbfc0..f756ff656 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt @@ -30,7 +30,7 @@ import eu.kanade.tachiyomi.util.Constants data class SourceSearchScreen( private val oldManga: Manga, private val sourceId: Long, - private val query: String? = null, + private val query: String?, ) : Screen { @Composable @@ -39,7 +39,7 @@ data class SourceSearchScreen( val uriHandler = LocalUriHandler.current val navigator = LocalNavigator.currentOrThrow - val screenModel = rememberScreenModel { BrowseSourceScreenModel(sourceId = sourceId, searchQuery = query) } + val screenModel = rememberScreenModel { BrowseSourceScreenModel(sourceId, query) } val state by screenModel.state.collectAsState() val snackbarHostState = remember { SnackbarHostState() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesTab.kt index 10fdadbea..2acfc7275 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesTab.kt @@ -12,7 +12,6 @@ import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow -import eu.kanade.domain.source.interactor.GetRemoteManga.Companion.QUERY_POPULAR import eu.kanade.presentation.browse.SourceCategoriesDialog import eu.kanade.presentation.browse.SourceOptionsDialog import eu.kanade.presentation.browse.SourcesScreen @@ -21,6 +20,7 @@ import eu.kanade.presentation.components.TabContent import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen.SmartSearchConfig import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen +import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing import eu.kanade.tachiyomi.ui.browse.source.feed.SourceFeedScreen import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchScreen import exh.ui.smartsearch.SmartSearchScreen @@ -62,12 +62,12 @@ fun Screen.sourcesTab( SourcesScreen( state = state, contentPadding = contentPadding, - onClickItem = { source, query -> + onClickItem = { source, listing -> // SY --> val screen = when { smartSearchConfig != null -> SmartSearchScreen(source.id, smartSearchConfig) - (query.isBlank() || query == QUERY_POPULAR) && screenModel.useNewSourceNavigation -> SourceFeedScreen(source.id) - else -> BrowseSourceScreen(source.id, query) + listing == Listing.Popular && screenModel.useNewSourceNavigation -> SourceFeedScreen(source.id) + else -> BrowseSourceScreen(source.id, listing.query) } screenModel.onOpenSource(source) navigator.push(screen) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt index dcad0a8fa..3caf23139 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt @@ -39,7 +39,6 @@ import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.uniqueScreenKey import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow -import eu.kanade.domain.source.interactor.GetRemoteManga import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.components.BrowseSourceToolbar import eu.kanade.presentation.browse.components.FailedToLoadSavedSearchDialog @@ -56,6 +55,7 @@ import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen +import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing import eu.kanade.tachiyomi.ui.category.CategoryScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.webview.WebViewActivity @@ -67,7 +67,7 @@ import kotlinx.coroutines.flow.receiveAsFlow data class BrowseSourceScreen( private val sourceId: Long, - private val query: String? = null, + private val listingQuery: String?, // SY --> private val filtersJson: String? = null, private val savedSearch: Long? = null, @@ -92,7 +92,7 @@ data class BrowseSourceScreen( val screenModel = rememberScreenModel { BrowseSourceScreenModel( sourceId = sourceId, - searchQuery = query, + listingQuery = listingQuery, // SY --> filtersJson = filtersJson, savedSearch = savedSearch, @@ -147,10 +147,10 @@ data class BrowseSourceScreen( horizontalArrangement = Arrangement.spacedBy(8.dp), ) { FilterChip( - selected = state.currentFilter == BrowseSourceScreenModel.Filter.Popular, + selected = state.listing == Listing.Popular, onClick = { - screenModel.reset() - screenModel.search(GetRemoteManga.QUERY_POPULAR) + screenModel.resetFilters() + screenModel.setListing(Listing.Popular) }, leadingIcon = { Icon( @@ -166,10 +166,10 @@ data class BrowseSourceScreen( ) if (screenModel.source.supportsLatest) { FilterChip( - selected = state.currentFilter == BrowseSourceScreenModel.Filter.Latest, + selected = state.listing == Listing.Latest, onClick = { - screenModel.reset() - screenModel.search(GetRemoteManga.QUERY_LATEST) + screenModel.resetFilters() + screenModel.setListing(Listing.Latest) }, leadingIcon = { Icon( @@ -186,7 +186,7 @@ data class BrowseSourceScreen( } /* SY --> if (state.filters.isNotEmpty())*/ run /* SY <-- */ { FilterChip( - selected = state.currentFilter is BrowseSourceScreenModel.Filter.UserInput, + selected = state.listing is Listing.Search, onClick = screenModel::openFilterSheet, leadingIcon = { Icon( diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt index a620969ca..7db775c27 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt @@ -107,7 +107,7 @@ import eu.kanade.tachiyomi.source.model.Filter as SourceModelFilter open class BrowseSourceScreenModel( private val sourceId: Long, - searchQuery: String?, + listingQuery: String?, // SY --> private val filtersJson: String? = null, private val savedSearch: Long? = null, @@ -135,7 +135,7 @@ open class BrowseSourceScreenModel( private val insertSavedSearch: InsertSavedSearch = Injekt.get(), private val getExhSavedSearch: GetExhSavedSearch = Injekt.get(), // SY <-- -) : StateScreenModel(State(Filter.valueOf(searchQuery))) { +) : StateScreenModel(State(Listing.valueOf(listingQuery))) { private val loggedServices by lazy { Injekt.get().services.filter { it.isLogged } } @@ -149,16 +149,16 @@ open class BrowseSourceScreenModel( private var filterSheet: SourceFilterSheet? = null /** - * Flow of Pager flow tied to [State.currentFilter] + * Flow of Pager flow tied to [State.listing] */ - val mangaPagerFlowFlow = state.map { it.currentFilter } + val mangaPagerFlowFlow = state.map { it.listing } .distinctUntilChanged() - .map { currentFilter -> + .map { listing -> Pager( PagingConfig(pageSize = 25), ) { // SY --> - createSourcePagingSource(currentFilter.query ?: "", currentFilter.filters) + createSourcePagingSource(listing.query ?: "", listing.filters) // SY <-- }.flow .map { pagingData -> @@ -184,7 +184,19 @@ open class BrowseSourceScreenModel( // SY <-- init { - mutableState.update { it.copy(filters = source.getFilterList()) } + mutableState.update { + val initialListing = it.listing + val listing = if (initialListing is Listing.Search) { + initialListing.copy(filters = source.getFilterList()) + } else { + initialListing + } + + it.copy( + listing = listing, + filters = source.getFilterList(), + ) + } // SY --> val savedSearchFilters = savedSearch @@ -234,31 +246,26 @@ open class BrowseSourceScreenModel( } // SY <-- - fun reset() { + fun resetFilters() { mutableState.update { it.copy(filters = source.getFilterList()) } } + fun setListing(listing: Listing) { + mutableState.update { it.copy(listing = listing) } + } + fun search(query: String? = null, filters: FilterList? = null) { // SY --> if (filters != null && filters !== state.value.filters) { mutableState.update { state -> state.copy(filters = filters) } } // SY <-- - Filter.valueOf(query).let { - if (it !is Filter.UserInput) { - mutableState.update { state -> state.copy(currentFilter = it) } - return - } - } + val input = state.value.listing as? Listing.Search + ?: Listing.Search(query = null, filters = source.getFilterList()) - val input = if (state.value.currentFilter is Filter.UserInput) { - state.value.currentFilter as Filter.UserInput - } else { - Filter.UserInput() - } mutableState.update { it.copy( - currentFilter = input.copy( + listing = input.copy( query = query ?: input.query, filters = filters ?: input.filters, ), @@ -297,14 +304,14 @@ open class BrowseSourceScreenModel( } mutableState.update { - val filter = if (genreExists) { - Filter.UserInput(filters = defaultFilters) + val listing = if (genreExists) { + Listing.Search(query = null, filters = defaultFilters) } else { - Filter.UserInput(query = genreName) + Listing.Search(query = genreName, filters = defaultFilters) } it.copy( filters = defaultFilters, - currentFilter = filter, + listing = listing, ) } } @@ -472,8 +479,8 @@ open class BrowseSourceScreenModel( // SY <-- onFilterClicked = { search(filters = state.filters) }, onResetClicked = { - reset() - filterSheet?.setFilters(state.value.filterItems) + resetFilters() + filterSheet?.setFilters(state.filterItems) }, // EXH --> onSaveClicked = { @@ -511,20 +518,20 @@ open class BrowseSourceScreenModel( // EXH <-- ) - filterSheet?.setFilters(state.value.filterItems) + filterSheet?.setFilters(state.filterItems) } - sealed class Filter(open val query: String?, open val filters: FilterList) { - object Popular : Filter(query = GetRemoteManga.QUERY_POPULAR, filters = FilterList()) - object Latest : Filter(query = GetRemoteManga.QUERY_LATEST, filters = FilterList()) - data class UserInput(override val query: String? = null, override val filters: FilterList = FilterList()) : Filter(query = query, filters = filters) + sealed class Listing(open val query: String?, open val filters: FilterList) { + object Popular : Listing(query = GetRemoteManga.QUERY_POPULAR, filters = FilterList()) + object Latest : Listing(query = GetRemoteManga.QUERY_LATEST, filters = FilterList()) + data class Search(override val query: String?, override val filters: FilterList) : Listing(query = query, filters = filters) companion object { - fun valueOf(query: String?): Filter { + fun valueOf(query: String?): Listing { return when (query) { GetRemoteManga.QUERY_POPULAR -> Popular GetRemoteManga.QUERY_LATEST -> Latest - else -> UserInput(query = query) + else -> Search(query = query, filters = FilterList()) // filters are filled in later } } } @@ -548,7 +555,7 @@ open class BrowseSourceScreenModel( @Immutable data class State( - val currentFilter: Filter, + val listing: Listing, val filters: FilterList = FilterList(), val toolbarQuery: String? = null, val dialog: Dialog? = null, @@ -557,7 +564,7 @@ open class BrowseSourceScreenModel( // SY <-- ) { val filterItems get() = filters.toItems() - val isUserQuery get() = currentFilter is Filter.UserInput && !currentFilter.query.isNullOrEmpty() + val isUserQuery get() = listing is Listing.Search && !listing.query.isNullOrEmpty() } // EXH --> @@ -565,8 +572,8 @@ open class BrowseSourceScreenModel( name: String, ) { coroutineScope.launchNonCancellable { - val query = state.value.currentFilter.query - val filterList = state.value.currentFilter.filters.ifEmpty { source.getFilterList() } + val query = state.value.listing.query + val filterList = state.value.listing.filters.ifEmpty { source.getFilterList() } insertSavedSearch.await( SavedSearch( id = -1, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt index 3a2c7b1ec..51ea45997 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt @@ -199,7 +199,7 @@ class SourceFeedScreen(val sourceId: Long) : Screen { } private fun onSavedSearchClick(navigator: Navigator, source: CatalogueSource, savedSearch: SavedSearch) { - navigator.replace(BrowseSourceScreen(source.id, savedSearch = savedSearch.id)) + navigator.replace(BrowseSourceScreen(source.id, listingQuery = null, savedSearch = savedSearch.id)) } private fun onSearchClick(navigator: Navigator, source: CatalogueSource, query: String) { diff --git a/app/src/main/java/exh/ui/smartsearch/SmartSearchScreen.kt b/app/src/main/java/exh/ui/smartsearch/SmartSearchScreen.kt index 7188b8c6e..92bbdc309 100644 --- a/app/src/main/java/exh/ui/smartsearch/SmartSearchScreen.kt +++ b/app/src/main/java/exh/ui/smartsearch/SmartSearchScreen.kt @@ -52,7 +52,7 @@ class SmartSearchScreen(private val sourceId: Long, private val smartSearchConfi navigator.push( BrowseSourceScreen( sourceId = screenModel.source.id, - query = smartSearchConfig.origTitle, + listingQuery = smartSearchConfig.origTitle, smartSearchConfig = smartSearchConfig, ), )