Minor refactoring

(cherry picked from commit ef7b285151f83b8ef679786417b82ca3227dab35)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupConst.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt
This commit is contained in:
arkon 2023-07-16 18:43:37 -04:00 committed by Jobobby04
parent 996d47e094
commit 2a5c869b1a
22 changed files with 72 additions and 101 deletions

View File

@ -30,7 +30,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.browse.source.SourcesState import eu.kanade.tachiyomi.ui.browse.source.SourcesScreenModel
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Pin import tachiyomi.domain.source.model.Pin
@ -47,7 +47,7 @@ import tachiyomi.source.local.isLocal
@Composable @Composable
fun SourcesScreen( fun SourcesScreen(
state: SourcesState, state: SourcesScreenModel.State,
contentPadding: PaddingValues, contentPadding: PaddingValues,
onClickItem: (Source, Listing) -> Unit, onClickItem: (Source, Listing) -> Unit,
onClickPin: (Source) -> Unit, onClickPin: (Source) -> Unit,

View File

@ -1,27 +1,21 @@
package eu.kanade.tachiyomi.data.backup package eu.kanade.tachiyomi.data.backup
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID // Filter options
internal object BackupConst {
object BackupConst { const val BACKUP_CATEGORY = 0x1
const val BACKUP_CATEGORY_MASK = 0x1
private const val NAME = "BackupRestoreServices" const val BACKUP_CHAPTER = 0x2
const val EXTRA_URI = "$ID.$NAME.EXTRA_URI" const val BACKUP_CHAPTER_MASK = 0x2
const val BACKUP_HISTORY = 0x4
// Filter options const val BACKUP_HISTORY_MASK = 0x4
internal const val BACKUP_CATEGORY = 0x1 const val BACKUP_TRACK = 0x8
internal const val BACKUP_CATEGORY_MASK = 0x1 const val BACKUP_TRACK_MASK = 0x8
internal const val BACKUP_CHAPTER = 0x2
internal const val BACKUP_CHAPTER_MASK = 0x2
internal const val BACKUP_HISTORY = 0x4
internal const val BACKUP_HISTORY_MASK = 0x4
internal const val BACKUP_TRACK = 0x8
internal const val BACKUP_TRACK_MASK = 0x8
// SY --> // SY -->
internal const val BACKUP_CUSTOM_INFO = 0x10 const val BACKUP_CUSTOM_INFO = 0x10
internal const val BACKUP_CUSTOM_INFO_MASK = 0x10 const val BACKUP_CUSTOM_INFO_MASK = 0x10
internal const val BACKUP_READ_MANGA = 0x20 const val BACKUP_READ_MANGA = 0x20
internal const val BACKUP_READ_MANGA_MASK = 0x20 const val BACKUP_READ_MANGA_MASK = 0x20
internal const val BACKUP_ALL = 0x3F const val BACKUP_ALL = 0x3F
// SY <-- // SY <--
} }

View File

@ -13,7 +13,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.Response import okhttp3.Response

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter

View File

@ -6,7 +6,6 @@ import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import tachiyomi.domain.chapter.interactor.GetChapter import tachiyomi.domain.chapter.interactor.GetChapter

View File

@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.DeletableTrackService import eu.kanade.tachiyomi.data.track.DeletableTrackService
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View File

@ -6,7 +6,6 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View File

@ -9,7 +9,6 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.awaitSuccess import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.track.bangumi package eu.kanade.tachiyomi.data.track.bangumi
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Interceptor import okhttp3.Interceptor

View File

@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.DeletableTrackService import eu.kanade.tachiyomi.data.track.DeletableTrackService
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.track.kitsu package eu.kanade.tachiyomi.data.track.kitsu
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response

View File

@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.DeletableTrackService import eu.kanade.tachiyomi.data.track.DeletableTrackService
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View File

@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.DeletableTrackService import eu.kanade.tachiyomi.data.track.DeletableTrackService
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.data.track.shikimori package eu.kanade.tachiyomi.data.track.shikimori
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response

View File

@ -29,9 +29,6 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L
onChangeSearchFilter = screenModel::setSourceFilter, onChangeSearchFilter = screenModel::setSourceFilter,
onToggleResults = screenModel::toggleFilterResults, onToggleResults = screenModel::toggleFilterResults,
onClickSource = { onClickSource = {
if (!screenModel.incognitoMode.get()) {
screenModel.lastUsedSourceId.set(it.id)
}
// SY --> // SY -->
navigator.push(SourceSearchScreen(state.manga!!, it.id, state.searchQuery)) navigator.push(SourceSearchScreen(state.manga!!, it.id, state.searchQuery))
// SY <-- // SY <--

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import cafe.adriel.voyager.core.model.coroutineScope import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
@ -21,16 +20,11 @@ class MigrateSearchScreenModel(
// SY --> // SY -->
val validSources: List<Long>, val validSources: List<Long>,
// SY <-- // SY <--
initialExtensionFilter: String = "",
preferences: BasePreferences = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(), private val sourcePreferences: SourcePreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
private val getManga: GetManga = Injekt.get(), private val getManga: GetManga = Injekt.get(),
) : SearchScreenModel<MigrateSearchScreenModel.State>(State()) { ) : SearchScreenModel<MigrateSearchScreenModel.State>(State()) {
val incognitoMode = preferences.incognitoMode()
val lastUsedSourceId = sourcePreferences.lastUsedSource()
init { init {
coroutineScope.launch { coroutineScope.launch {
val manga = getManga.await(mangaId)!! val manga = getManga.await(mangaId)!!
@ -68,11 +62,11 @@ class MigrateSearchScreenModel(
return mutableState.value.items return mutableState.value.items
} }
fun setSourceFilter(filter: SourceFilter) { override fun setSourceFilter(filter: SourceFilter) {
mutableState.update { it.copy(sourceFilter = filter) } mutableState.update { it.copy(sourceFilter = filter) }
} }
fun toggleFilterResults() { override fun toggleFilterResults() {
mutableState.update { mutableState.update {
it.copy(onlyShowHasResults = !it.onlyShowHasResults) it.copy(onlyShowHasResults = !it.onlyShowHasResults)
} }

View File

@ -5,7 +5,6 @@ import androidx.compose.runtime.getValue
import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.core.preference.asState import eu.kanade.core.preference.asState
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.interactor.GetEnabledSources import eu.kanade.domain.source.interactor.GetEnabledSources
import eu.kanade.domain.source.interactor.GetShowLatest import eu.kanade.domain.source.interactor.GetShowLatest
import eu.kanade.domain.source.interactor.GetSourceCategories import eu.kanade.domain.source.interactor.GetSourceCategories
@ -36,8 +35,6 @@ import uy.kohesive.injekt.api.get
import java.util.TreeMap import java.util.TreeMap
class SourcesScreenModel( class SourcesScreenModel(
private val preferences: BasePreferences = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(),
private val getEnabledSources: GetEnabledSources = Injekt.get(), private val getEnabledSources: GetEnabledSources = Injekt.get(),
private val toggleSource: ToggleSource = Injekt.get(), private val toggleSource: ToggleSource = Injekt.get(),
private val toggleSourcePin: ToggleSourcePin = Injekt.get(), private val toggleSourcePin: ToggleSourcePin = Injekt.get(),
@ -47,9 +44,10 @@ class SourcesScreenModel(
private val getShowLatest: GetShowLatest = Injekt.get(), private val getShowLatest: GetShowLatest = Injekt.get(),
private val toggleExcludeFromDataSaver: ToggleExcludeFromDataSaver = Injekt.get(), private val toggleExcludeFromDataSaver: ToggleExcludeFromDataSaver = Injekt.get(),
private val setSourceCategories: SetSourceCategories = Injekt.get(), private val setSourceCategories: SetSourceCategories = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(),
val smartSearchConfig: SourcesScreen.SmartSearchConfig?, val smartSearchConfig: SourcesScreen.SmartSearchConfig?,
// SY <-- // SY <--
) : StateScreenModel<SourcesState>(SourcesState()) { ) : StateScreenModel<SourcesScreenModel.State>(State()) {
private val _events = Channel<Event>(Int.MAX_VALUE) private val _events = Channel<Event>(Int.MAX_VALUE)
val events = _events.receiveAsFlow() val events = _events.receiveAsFlow()
@ -132,12 +130,6 @@ class SourcesScreenModel(
} }
} }
fun onOpenSource(source: Source) {
if (!preferences.incognitoMode().get()) {
sourcePreferences.lastUsedSource().set(source.id)
}
}
fun toggleSource(source: Source) { fun toggleSource(source: Source) {
toggleSource.await(source) toggleSource.await(source)
} }
@ -177,6 +169,21 @@ class SourcesScreenModel(
data class SourceCategories(val source: Source) : Dialog() data class SourceCategories(val source: Source) : Dialog()
} }
@Immutable
data class State(
val dialog: Dialog? = null,
val isLoading: Boolean = true,
val items: List<SourceUiModel> = emptyList(),
// SY -->
val categories: List<String> = emptyList(),
val showPin: Boolean = true,
val showLatest: Boolean = false,
val dataSaverEnabled: Boolean = false,
// SY <--
) {
val isEmpty = items.isEmpty()
}
companion object { companion object {
const val PINNED_KEY = "pinned" const val PINNED_KEY = "pinned"
const val LAST_USED_KEY = "last_used" const val LAST_USED_KEY = "last_used"
@ -186,18 +193,3 @@ class SourcesScreenModel(
// SY <-- // SY <--
} }
} }
@Immutable
data class SourcesState(
val dialog: SourcesScreenModel.Dialog? = null,
val isLoading: Boolean = true,
val items: List<SourceUiModel> = emptyList(),
// SY -->
val categories: List<String> = emptyList(),
val showPin: Boolean = true,
val showLatest: Boolean = false,
val dataSaverEnabled: Boolean = false,
// SY <--
) {
val isEmpty = items.isEmpty()
}

View File

@ -69,7 +69,6 @@ fun Screen.sourcesTab(
listing == Listing.Popular && screenModel.useNewSourceNavigation -> SourceFeedScreen(source.id) listing == Listing.Popular && screenModel.useNewSourceNavigation -> SourceFeedScreen(source.id)
else -> BrowseSourceScreen(source.id, listing.query) else -> BrowseSourceScreen(source.id, listing.query)
} }
screenModel.onOpenSource(source)
navigator.push(screen) navigator.push(screen)
// SY <-- // SY <--
}, },

View File

@ -13,6 +13,7 @@ import androidx.paging.map
import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.core.preference.asState import eu.kanade.core.preference.asState
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.manga.model.toDomainManga
@ -97,6 +98,7 @@ open class BrowseSourceScreenModel(
// SY <-- // SY <--
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
sourcePreferences: SourcePreferences = Injekt.get(), sourcePreferences: SourcePreferences = Injekt.get(),
basePreferences: BasePreferences = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(), private val libraryPreferences: LibraryPreferences = Injekt.get(),
private val coverCache: CoverCache = Injekt.get(), private val coverCache: CoverCache = Injekt.get(),
private val getRemoteManga: GetRemoteManga = Injekt.get(), private val getRemoteManga: GetRemoteManga = Injekt.get(),
@ -156,6 +158,10 @@ open class BrowseSourceScreenModel(
} }
} }
if (!basePreferences.incognitoMode().get()) {
sourcePreferences.lastUsedSource().set(source.id)
}
// SY --> // SY -->
val savedSearchFilters = savedSearch val savedSearchFilters = savedSearch
val jsonFilters = filtersJson val jsonFilters = filtersJson

View File

@ -64,9 +64,6 @@ class GlobalSearchScreen(
onChangeSearchFilter = screenModel::setSourceFilter, onChangeSearchFilter = screenModel::setSourceFilter,
onToggleResults = screenModel::toggleFilterResults, onToggleResults = screenModel::toggleFilterResults,
onClickSource = { onClickSource = {
if (!screenModel.incognitoMode.get()) {
screenModel.lastUsedSourceId.set(it.id)
}
navigator.push(BrowseSourceScreen(it.id, state.searchQuery)) navigator.push(BrowseSourceScreen(it.id, state.searchQuery))
}, },
onClickItem = { navigator.push(MangaScreen(it.id, true)) }, onClickItem = { navigator.push(MangaScreen(it.id, true)) },

View File

@ -1,25 +1,14 @@
package eu.kanade.tachiyomi.ui.browse.source.globalsearch package eu.kanade.tachiyomi.ui.browse.source.globalsearch
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class GlobalSearchScreenModel( class GlobalSearchScreenModel(
initialQuery: String = "", initialQuery: String = "",
initialExtensionFilter: String? = null, initialExtensionFilter: String? = null,
preferences: BasePreferences = Injekt.get(),
private val sourcePreferences: SourcePreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
) : SearchScreenModel<GlobalSearchScreenModel.State>(State(searchQuery = initialQuery)) { ) : SearchScreenModel<GlobalSearchScreenModel.State>(State(searchQuery = initialQuery)) {
val incognitoMode = preferences.incognitoMode()
val lastUsedSourceId = sourcePreferences.lastUsedSource()
init { init {
extensionFilter = initialExtensionFilter extensionFilter = initialExtensionFilter
if (initialQuery.isNotBlank() || !initialExtensionFilter.isNullOrBlank()) { if (initialQuery.isNotBlank() || !initialExtensionFilter.isNullOrBlank()) {
@ -28,15 +17,8 @@ class GlobalSearchScreenModel(
} }
override fun getEnabledSources(): List<CatalogueSource> { override fun getEnabledSources(): List<CatalogueSource> {
val enabledLanguages = sourcePreferences.enabledLanguages().get() return super.getEnabledSources()
val disabledSources = sourcePreferences.disabledSources().get()
val pinnedSources = sourcePreferences.pinnedSources().get()
return sourceManager.getVisibleCatalogueSources()
.filter { mutableState.value.sourceFilter != SourceFilter.PinnedOnly || "${it.id}" in pinnedSources } .filter { mutableState.value.sourceFilter != SourceFilter.PinnedOnly || "${it.id}" in pinnedSources }
.filter { it.lang in enabledLanguages }
.filterNot { "${it.id}" in disabledSources }
.sortedWith(compareBy({ "${it.id}" !in pinnedSources }, { "${it.name.lowercase()} (${it.lang})" }))
} }
override fun updateSearchQuery(query: String?) { override fun updateSearchQuery(query: String?) {
@ -55,11 +37,11 @@ class GlobalSearchScreenModel(
return mutableState.value.items return mutableState.value.items
} }
fun setSourceFilter(filter: SourceFilter) { override fun setSourceFilter(filter: SourceFilter) {
mutableState.update { it.copy(sourceFilter = filter) } mutableState.update { it.copy(sourceFilter = filter) }
} }
fun toggleFilterResults() { override fun toggleFilterResults() {
mutableState.update { mutableState.update {
it.copy(onlyShowHasResults = !it.onlyShowHasResults) it.copy(onlyShowHasResults = !it.onlyShowHasResults)
} }

View File

@ -10,16 +10,19 @@ import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import tachiyomi.core.util.lang.awaitSingle import tachiyomi.core.util.lang.awaitSingle
import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.concurrent.Executors import java.util.concurrent.Executors
@ -27,6 +30,7 @@ import java.util.concurrent.Executors
abstract class SearchScreenModel<T>( abstract class SearchScreenModel<T>(
initialState: T, initialState: T,
private val sourcePreferences: SourcePreferences = Injekt.get(), private val sourcePreferences: SourcePreferences = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
private val extensionManager: ExtensionManager = Injekt.get(), private val extensionManager: ExtensionManager = Injekt.get(),
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
private val getManga: GetManga = Injekt.get(), private val getManga: GetManga = Injekt.get(),
@ -34,12 +38,13 @@ abstract class SearchScreenModel<T>(
) : StateScreenModel<T>(initialState) { ) : StateScreenModel<T>(initialState) {
private val coroutineDispatcher = Executors.newFixedThreadPool(5).asCoroutineDispatcher() private val coroutineDispatcher = Executors.newFixedThreadPool(5).asCoroutineDispatcher()
private var searchJob: Job? = null
protected var query: String? = null protected var query: String? = null
protected var extensionFilter: String? = null protected var extensionFilter: String? = null
private val sources by lazy { getSelectedSources() } private val sources by lazy { getSelectedSources() }
private val pinnedSources by lazy { sourcePreferences.pinnedSources().get() } protected val pinnedSources = sourcePreferences.pinnedSources().get()
private val sortComparator = { map: Map<CatalogueSource, SearchItemResult> -> private val sortComparator = { map: Map<CatalogueSource, SearchItemResult> ->
compareBy<CatalogueSource>( compareBy<CatalogueSource>(
@ -53,14 +58,27 @@ abstract class SearchScreenModel<T>(
fun getManga(initialManga: Manga): State<Manga> { fun getManga(initialManga: Manga): State<Manga> {
return produceState(initialValue = initialManga) { return produceState(initialValue = initialManga) {
getManga.subscribe(initialManga.url, initialManga.source) getManga.subscribe(initialManga.url, initialManga.source)
.filterNotNull()
.collectLatest { manga -> .collectLatest { manga ->
if (manga == null) return@collectLatest
value = manga value = manga
} }
} }
} }
abstract fun getEnabledSources(): List<CatalogueSource> open fun getEnabledSources(): List<CatalogueSource> {
val enabledLanguages = sourcePreferences.enabledLanguages().get()
val disabledSources = sourcePreferences.disabledSources().get()
val pinnedSources = sourcePreferences.pinnedSources().get()
return sourceManager.getVisibleCatalogueSources()
.filter { it.lang in enabledLanguages && "${it.id}" !in disabledSources }
.sortedWith(
compareBy(
{ "${it.id}" !in pinnedSources },
{ "${it.name.lowercase()} (${it.lang})" },
),
)
}
private fun getSelectedSources(): List<CatalogueSource> { private fun getSelectedSources(): List<CatalogueSource> {
val enabledSources = getEnabledSources() val enabledSources = getEnabledSources()
@ -90,15 +108,19 @@ abstract class SearchScreenModel<T>(
updateItems(function(getItems())) updateItems(function(getItems()))
} }
abstract fun setSourceFilter(filter: SourceFilter)
abstract fun toggleFilterResults()
fun search(query: String) { fun search(query: String) {
if (this.query == query) return if (this.query == query) return
this.query = query this.query = query
searchJob?.cancel()
val initialItems = getSelectedSources().associateWith { SearchItemResult.Loading } val initialItems = getSelectedSources().associateWith { SearchItemResult.Loading }
updateItems(initialItems) updateItems(initialItems)
searchJob = ioCoroutineScope.launch {
ioCoroutineScope.launch {
sources sources
.map { source -> .map { source ->
async { async {