Observe tracker login state instead of fetching once (#987)

* Observe tracker login state instead of fetching once

* Review changes
This commit is contained in:
AntsyLich
2024-07-06 07:25:33 +06:00
committed by GitHub
parent 5a61ca5535
commit 2092c81bad
12 changed files with 96 additions and 53 deletions
@@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@@ -106,10 +107,10 @@ class LibraryScreenModel(
getTracksPerManga.subscribe(),
getTrackingFilterFlow(),
downloadCache.changes,
) { searchQuery, library, tracks, loggedInTrackers, _ ->
) { searchQuery, library, tracks, trackingFiler, _ ->
library
.applyFilters(tracks, loggedInTrackers)
.applySort(tracks)
.applyFilters(tracks, trackingFiler)
.applySort(tracks, trackingFiler.keys)
.mapValues { (_, value) ->
if (searchQuery != null) {
// Filter query
@@ -173,9 +174,10 @@ class LibraryScreenModel(
/**
* Applies library filters to the given map of manga.
*/
@Suppress("LongMethod", "CyclomaticComplexMethod")
private suspend fun LibraryMap.applyFilters(
trackMap: Map<Long, List<Track>>,
loggedInTrackers: Map<Long, TriState>,
trackingFiler: Map<Long, TriState>,
): LibraryMap {
val prefs = getLibraryItemPreferencesFlow().first()
val downloadedOnly = prefs.globalFilterDownloaded
@@ -187,10 +189,10 @@ class LibraryScreenModel(
val filterCompleted = prefs.filterCompleted
val filterIntervalCustom = prefs.filterIntervalCustom
val isNotLoggedInAnyTrack = loggedInTrackers.isEmpty()
val isNotLoggedInAnyTrack = trackingFiler.isEmpty()
val excludedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null }
val includedTracks = loggedInTrackers.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null }
val excludedTracks = trackingFiler.mapNotNull { if (it.value == TriState.ENABLED_NOT) it.key else null }
val includedTracks = trackingFiler.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null }
val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
val filterFnDownloaded: (LibraryItem) -> Boolean = {
@@ -254,9 +256,11 @@ class LibraryScreenModel(
/**
* Applies library sorting to the given map of manga.
*/
@Suppress("LongMethod", "CyclomaticComplexMethod")
private fun LibraryMap.applySort(
// Map<MangaId, List<Track>>
trackMap: Map<Long, List<Track>>,
loggedInTrackerIds: Set<Long>
): LibraryMap {
val sortAlphabetically: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
i1.libraryManga.manga.title.lowercase().compareToWithCollator(i2.libraryManga.manga.title.lowercase())
@@ -264,7 +268,7 @@ class LibraryScreenModel(
val defaultTrackerScoreSortValue = -1.0
val trackerScores by lazy {
val trackerMap = trackerManager.loggedInTrackers().associateBy { e -> e.id }
val trackerMap = trackerManager.getAll(loggedInTrackerIds).associateBy { e -> e.id }
trackMap.mapValues { entry ->
when {
entry.value.isEmpty() -> null
@@ -405,18 +409,17 @@ class LibraryScreenModel(
* @return map of track id with the filter value
*/
private fun getTrackingFilterFlow(): Flow<Map<Long, TriState>> {
val loggedInTrackers = trackerManager.loggedInTrackers()
return if (loggedInTrackers.isNotEmpty()) {
val prefFlows = loggedInTrackers
.map { libraryPreferences.filterTracking(it.id.toInt()).changes() }
.toTypedArray()
combine(*prefFlows) {
return trackerManager.loggedInTrackersFlow().flatMapLatest { loggedInTrackers ->
if (loggedInTrackers.isEmpty()) return@flatMapLatest flowOf(emptyMap())
val prefFlows = loggedInTrackers.map { tracker ->
libraryPreferences.filterTracking(tracker.id.toInt()).changes()
}
combine(prefFlows) {
loggedInTrackers
.mapIndexed { index, tracker -> tracker.id to it[index] }
.toMap()
}
} else {
flowOf(emptyMap())
}
}
@@ -4,6 +4,8 @@ import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.data.track.TrackerManager
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.TriState
import tachiyomi.core.common.preference.getAndSet
@@ -16,17 +18,22 @@ import tachiyomi.domain.library.model.LibrarySort
import tachiyomi.domain.library.service.LibraryPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.time.Duration.Companion.seconds
class LibrarySettingsScreenModel(
val preferences: BasePreferences = Injekt.get(),
val libraryPreferences: LibraryPreferences = Injekt.get(),
private val setDisplayMode: SetDisplayMode = Injekt.get(),
private val setSortModeForCategory: SetSortModeForCategory = Injekt.get(),
private val trackerManager: TrackerManager = Injekt.get(),
trackerManager: TrackerManager = Injekt.get(),
) : ScreenModel {
val trackers
get() = trackerManager.trackers.filter { it.isLoggedIn }
val trackersFlow = trackerManager.loggedInTrackersFlow()
.stateIn(
scope = screenModelScope,
started = SharingStarted.WhileSubscribed(5.seconds.inWholeMilliseconds),
initialValue = trackerManager.loggedInTrackers()
)
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
preference(libraryPreferences).getAndSet {