mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-21 20:47:03 -05:00
Observe tracker login state instead of fetching once (#987)
Some checks failed
CI / Build app (push) Has been cancelled
Some checks failed
CI / Build app (push) Has been cancelled
* Observe tracker login state instead of fetching once * Review changes
This commit is contained in:
parent
5a61ca5535
commit
2092c81bad
12 changed files with 96 additions and 53 deletions
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.FilterChip
|
import androidx.compose.material3.FilterChip
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -125,7 +126,7 @@ private fun ColumnScope.FilterPage(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val trackers = remember { screenModel.trackers }
|
val trackers by screenModel.trackersFlow.collectAsState()
|
||||||
when (trackers.size) {
|
when (trackers.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
// No trackers
|
// No trackers
|
||||||
|
@ -158,11 +159,11 @@ private fun ColumnScope.SortPage(
|
||||||
category: Category?,
|
category: Category?,
|
||||||
screenModel: LibrarySettingsScreenModel,
|
screenModel: LibrarySettingsScreenModel,
|
||||||
) {
|
) {
|
||||||
|
val trackers by screenModel.trackersFlow.collectAsState()
|
||||||
val sortingMode = category.sort.type
|
val sortingMode = category.sort.type
|
||||||
val sortDescending = !category.sort.isAscending
|
val sortDescending = !category.sort.isAscending
|
||||||
|
|
||||||
val trackerSortOption =
|
val trackerSortOption = if (trackers.isEmpty()) {
|
||||||
if (screenModel.trackers.isEmpty()) {
|
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
|
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
|
||||||
|
|
|
@ -7,12 +7,12 @@ import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.structuralEqualityPolicy
|
import androidx.compose.runtime.structuralEqualityPolicy
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.track.service.TrackPreferences
|
|
||||||
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.InfoWidget
|
import eu.kanade.presentation.more.settings.widget.InfoWidget
|
||||||
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
|
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
|
||||||
|
@ -23,8 +23,6 @@ import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.presentation.core.components.SliderItem
|
import tachiyomi.presentation.core.components.SliderItem
|
||||||
import tachiyomi.presentation.core.util.collectAsState
|
import tachiyomi.presentation.core.util.collectAsState
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
|
val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
|
||||||
val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp }
|
val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp }
|
||||||
|
@ -156,17 +154,15 @@ internal fun PreferenceItem(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is Preference.PreferenceItem.TrackerPreference -> {
|
is Preference.PreferenceItem.TrackerPreference -> {
|
||||||
val uName by Injekt.get<TrackPreferences>()
|
val isLoggedIn by item.tracker.let { tracker ->
|
||||||
.trackUsername(item.tracker)
|
tracker.isLoggedInFlow.collectAsState(tracker.isLoggedIn)
|
||||||
.collectAsState()
|
}
|
||||||
item.tracker.run {
|
|
||||||
TrackingPreferenceWidget(
|
TrackingPreferenceWidget(
|
||||||
tracker = this,
|
tracker = item.tracker,
|
||||||
checked = uName.isNotEmpty(),
|
checked = isLoggedIn,
|
||||||
onClick = { if (isLoggedIn) item.logout() else item.login() },
|
onClick = { if (isLoggedIn) item.logout() else item.login() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is Preference.PreferenceItem.InfoPreference -> {
|
is Preference.PreferenceItem.InfoPreference -> {
|
||||||
InfoWidget(text = item.title)
|
InfoWidget(text = item.title)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import eu.kanade.domain.track.service.TrackPreferences
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import tachiyomi.core.common.util.lang.withIOContext
|
import tachiyomi.core.common.util.lang.withIOContext
|
||||||
|
@ -53,6 +55,15 @@ abstract class BaseTracker(
|
||||||
get() = getUsername().isNotEmpty() &&
|
get() = getUsername().isNotEmpty() &&
|
||||||
getPassword().isNotEmpty()
|
getPassword().isNotEmpty()
|
||||||
|
|
||||||
|
override val isLoggedInFlow: Flow<Boolean> by lazy {
|
||||||
|
combine(
|
||||||
|
trackPreferences.trackUsername(this).changes(),
|
||||||
|
trackPreferences.trackPassword(this).changes(),
|
||||||
|
) { username, password ->
|
||||||
|
username.isNotEmpty() && password.isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getUsername() = trackPreferences.trackUsername(this).get()
|
override fun getUsername() = trackPreferences.trackUsername(this).get()
|
||||||
|
|
||||||
override fun getPassword() = trackPreferences.trackPassword(this).get()
|
override fun getPassword() = trackPreferences.trackPassword(this).get()
|
||||||
|
|
|
@ -7,6 +7,7 @@ import dev.icerock.moko.resources.StringResource
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
|
@ -61,6 +62,8 @@ interface Tracker {
|
||||||
|
|
||||||
val isLoggedIn: Boolean
|
val isLoggedIn: Boolean
|
||||||
|
|
||||||
|
val isLoggedInFlow: Flow<Boolean>
|
||||||
|
|
||||||
fun getUsername(): String
|
fun getUsername(): String
|
||||||
|
|
||||||
fun getPassword(): String
|
fun getPassword(): String
|
||||||
|
|
|
@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.data.track.mangaupdates.MangaUpdates
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList
|
import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.Shikimori
|
import eu.kanade.tachiyomi.data.track.shikimori.Shikimori
|
||||||
import eu.kanade.tachiyomi.data.track.suwayomi.Suwayomi
|
import eu.kanade.tachiyomi.data.track.suwayomi.Suwayomi
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
|
||||||
class TrackerManager {
|
class TrackerManager {
|
||||||
|
|
||||||
|
@ -32,5 +33,13 @@ class TrackerManager {
|
||||||
|
|
||||||
fun loggedInTrackers() = trackers.filter { it.isLoggedIn }
|
fun loggedInTrackers() = trackers.filter { it.isLoggedIn }
|
||||||
|
|
||||||
|
fun loggedInTrackersFlow() = combine(trackers.map { it.isLoggedInFlow }) {
|
||||||
|
it.mapIndexedNotNull { index, isLoggedIn ->
|
||||||
|
if (isLoggedIn) trackers[index] else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun get(id: Long) = trackers.find { it.id == id }
|
fun get(id: Long) = trackers.find { it.id == id }
|
||||||
|
|
||||||
|
fun getAll(ids: Set<Long>) = trackers.filter { it.id in ids }
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
@ -106,10 +107,10 @@ class LibraryScreenModel(
|
||||||
getTracksPerManga.subscribe(),
|
getTracksPerManga.subscribe(),
|
||||||
getTrackingFilterFlow(),
|
getTrackingFilterFlow(),
|
||||||
downloadCache.changes,
|
downloadCache.changes,
|
||||||
) { searchQuery, library, tracks, loggedInTrackers, _ ->
|
) { searchQuery, library, tracks, trackingFiler, _ ->
|
||||||
library
|
library
|
||||||
.applyFilters(tracks, loggedInTrackers)
|
.applyFilters(tracks, trackingFiler)
|
||||||
.applySort(tracks)
|
.applySort(tracks, trackingFiler.keys)
|
||||||
.mapValues { (_, value) ->
|
.mapValues { (_, value) ->
|
||||||
if (searchQuery != null) {
|
if (searchQuery != null) {
|
||||||
// Filter query
|
// Filter query
|
||||||
|
@ -173,9 +174,10 @@ class LibraryScreenModel(
|
||||||
/**
|
/**
|
||||||
* Applies library filters to the given map of manga.
|
* Applies library filters to the given map of manga.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||||
private suspend fun LibraryMap.applyFilters(
|
private suspend fun LibraryMap.applyFilters(
|
||||||
trackMap: Map<Long, List<Track>>,
|
trackMap: Map<Long, List<Track>>,
|
||||||
loggedInTrackers: Map<Long, TriState>,
|
trackingFiler: Map<Long, TriState>,
|
||||||
): LibraryMap {
|
): LibraryMap {
|
||||||
val prefs = getLibraryItemPreferencesFlow().first()
|
val prefs = getLibraryItemPreferencesFlow().first()
|
||||||
val downloadedOnly = prefs.globalFilterDownloaded
|
val downloadedOnly = prefs.globalFilterDownloaded
|
||||||
|
@ -187,10 +189,10 @@ class LibraryScreenModel(
|
||||||
val filterCompleted = prefs.filterCompleted
|
val filterCompleted = prefs.filterCompleted
|
||||||
val filterIntervalCustom = prefs.filterIntervalCustom
|
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 excludedTracks = trackingFiler.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 includedTracks = trackingFiler.mapNotNull { if (it.value == TriState.ENABLED_IS) it.key else null }
|
||||||
val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
|
val trackFiltersIsIgnored = includedTracks.isEmpty() && excludedTracks.isEmpty()
|
||||||
|
|
||||||
val filterFnDownloaded: (LibraryItem) -> Boolean = {
|
val filterFnDownloaded: (LibraryItem) -> Boolean = {
|
||||||
|
@ -254,9 +256,11 @@ class LibraryScreenModel(
|
||||||
/**
|
/**
|
||||||
* Applies library sorting to the given map of manga.
|
* Applies library sorting to the given map of manga.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||||
private fun LibraryMap.applySort(
|
private fun LibraryMap.applySort(
|
||||||
// Map<MangaId, List<Track>>
|
// Map<MangaId, List<Track>>
|
||||||
trackMap: Map<Long, List<Track>>,
|
trackMap: Map<Long, List<Track>>,
|
||||||
|
loggedInTrackerIds: Set<Long>
|
||||||
): LibraryMap {
|
): LibraryMap {
|
||||||
val sortAlphabetically: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
|
val sortAlphabetically: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
|
||||||
i1.libraryManga.manga.title.lowercase().compareToWithCollator(i2.libraryManga.manga.title.lowercase())
|
i1.libraryManga.manga.title.lowercase().compareToWithCollator(i2.libraryManga.manga.title.lowercase())
|
||||||
|
@ -264,7 +268,7 @@ class LibraryScreenModel(
|
||||||
|
|
||||||
val defaultTrackerScoreSortValue = -1.0
|
val defaultTrackerScoreSortValue = -1.0
|
||||||
val trackerScores by lazy {
|
val trackerScores by lazy {
|
||||||
val trackerMap = trackerManager.loggedInTrackers().associateBy { e -> e.id }
|
val trackerMap = trackerManager.getAll(loggedInTrackerIds).associateBy { e -> e.id }
|
||||||
trackMap.mapValues { entry ->
|
trackMap.mapValues { entry ->
|
||||||
when {
|
when {
|
||||||
entry.value.isEmpty() -> null
|
entry.value.isEmpty() -> null
|
||||||
|
@ -405,18 +409,17 @@ class LibraryScreenModel(
|
||||||
* @return map of track id with the filter value
|
* @return map of track id with the filter value
|
||||||
*/
|
*/
|
||||||
private fun getTrackingFilterFlow(): Flow<Map<Long, TriState>> {
|
private fun getTrackingFilterFlow(): Flow<Map<Long, TriState>> {
|
||||||
val loggedInTrackers = trackerManager.loggedInTrackers()
|
return trackerManager.loggedInTrackersFlow().flatMapLatest { loggedInTrackers ->
|
||||||
return if (loggedInTrackers.isNotEmpty()) {
|
if (loggedInTrackers.isEmpty()) return@flatMapLatest flowOf(emptyMap())
|
||||||
val prefFlows = loggedInTrackers
|
|
||||||
.map { libraryPreferences.filterTracking(it.id.toInt()).changes() }
|
val prefFlows = loggedInTrackers.map { tracker ->
|
||||||
.toTypedArray()
|
libraryPreferences.filterTracking(tracker.id.toInt()).changes()
|
||||||
combine(*prefFlows) {
|
}
|
||||||
|
combine(prefFlows) {
|
||||||
loggedInTrackers
|
loggedInTrackers
|
||||||
.mapIndexed { index, tracker -> tracker.id to it[index] }
|
.mapIndexed { index, tracker -> tracker.id to it[index] }
|
||||||
.toMap()
|
.toMap()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
flowOf(emptyMap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import eu.kanade.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.tachiyomi.data.track.TrackerManager
|
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.Preference
|
||||||
import tachiyomi.core.common.preference.TriState
|
import tachiyomi.core.common.preference.TriState
|
||||||
import tachiyomi.core.common.preference.getAndSet
|
import tachiyomi.core.common.preference.getAndSet
|
||||||
|
@ -16,17 +18,22 @@ import tachiyomi.domain.library.model.LibrarySort
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class LibrarySettingsScreenModel(
|
class LibrarySettingsScreenModel(
|
||||||
val preferences: BasePreferences = Injekt.get(),
|
val preferences: BasePreferences = Injekt.get(),
|
||||||
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
private val setDisplayMode: SetDisplayMode = Injekt.get(),
|
private val setDisplayMode: SetDisplayMode = Injekt.get(),
|
||||||
private val setSortModeForCategory: SetSortModeForCategory = Injekt.get(),
|
private val setSortModeForCategory: SetSortModeForCategory = Injekt.get(),
|
||||||
private val trackerManager: TrackerManager = Injekt.get(),
|
trackerManager: TrackerManager = Injekt.get(),
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
|
|
||||||
val trackers
|
val trackersFlow = trackerManager.loggedInTrackersFlow()
|
||||||
get() = trackerManager.trackers.filter { it.isLoggedIn }
|
.stateIn(
|
||||||
|
scope = screenModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(5.seconds.inWholeMilliseconds),
|
||||||
|
initialValue = trackerManager.loggedInTrackers()
|
||||||
|
)
|
||||||
|
|
||||||
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
|
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
|
||||||
preference(libraryPreferences).getAndSet {
|
preference(libraryPreferences).getAndSet {
|
||||||
|
|
|
@ -138,7 +138,7 @@ class MangaScreen(
|
||||||
)
|
)
|
||||||
}.takeIf { isHttpSource },
|
}.takeIf { isHttpSource },
|
||||||
onTrackingClicked = {
|
onTrackingClicked = {
|
||||||
if (screenModel.loggedInTrackers.isEmpty()) {
|
if (successState.loggedInTracker.isEmpty()) {
|
||||||
navigator.push(SettingsScreen(SettingsScreen.Destination.Tracking))
|
navigator.push(SettingsScreen(SettingsScreen.Destination.Tracking))
|
||||||
} else {
|
} else {
|
||||||
screenModel.showTrackDialog()
|
screenModel.showTrackDialog()
|
||||||
|
|
|
@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.data.download.DownloadCache
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.Tracker
|
||||||
import eu.kanade.tachiyomi.data.track.TrackerManager
|
import eu.kanade.tachiyomi.data.track.TrackerManager
|
||||||
import eu.kanade.tachiyomi.network.HttpException
|
import eu.kanade.tachiyomi.network.HttpException
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
@ -45,7 +46,6 @@ import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -117,8 +117,6 @@ class MangaScreenModel(
|
||||||
private val successState: State.Success?
|
private val successState: State.Success?
|
||||||
get() = state.value as? State.Success
|
get() = state.value as? State.Success
|
||||||
|
|
||||||
val loggedInTrackers by lazy { trackerManager.trackers.filter { it.isLoggedIn } }
|
|
||||||
|
|
||||||
val manga: Manga?
|
val manga: Manga?
|
||||||
get() = successState?.manga
|
get() = successState?.manga
|
||||||
|
|
||||||
|
@ -194,6 +192,16 @@ class MangaScreenModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screenModelScope.launchIO {
|
||||||
|
trackerManager.loggedInTrackersFlow()
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.collectLatest { trackers ->
|
||||||
|
updateSuccessState {
|
||||||
|
it.copy(loggedInTracker = trackers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
observeDownloads()
|
observeDownloads()
|
||||||
|
|
||||||
screenModelScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
|
@ -978,12 +986,13 @@ class MangaScreenModel(
|
||||||
val manga = successState?.manga ?: return
|
val manga = successState?.manga ?: return
|
||||||
|
|
||||||
screenModelScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
getTracks.subscribe(manga.id)
|
combine(
|
||||||
.catch { logcat(LogPriority.ERROR, it) }
|
getTracks.subscribe(manga.id).catch { logcat(LogPriority.ERROR, it) },
|
||||||
.map { tracks ->
|
trackerManager.loggedInTrackersFlow(),
|
||||||
|
) { mangaTracks, loggedInTrackers ->
|
||||||
loggedInTrackers
|
loggedInTrackers
|
||||||
// Map to TrackItem
|
// Map to TrackItem
|
||||||
.map { service -> TrackItem(tracks.find { it.trackerId == service.id }, service) }
|
.map { service -> TrackItem(mangaTracks.find { it.trackerId == service.id }, service) }
|
||||||
// Show only if the service supports this manga's source
|
// Show only if the service supports this manga's source
|
||||||
.filter { (it.tracker as? EnhancedTracker)?.accept(source!!) ?: true }
|
.filter { (it.tracker as? EnhancedTracker)?.accept(source!!) ?: true }
|
||||||
}
|
}
|
||||||
|
@ -1057,6 +1066,7 @@ class MangaScreenModel(
|
||||||
val isRefreshingData: Boolean = false,
|
val isRefreshingData: Boolean = false,
|
||||||
val dialog: Dialog? = null,
|
val dialog: Dialog? = null,
|
||||||
val hasPromptedToAddBefore: Boolean = false,
|
val hasPromptedToAddBefore: Boolean = false,
|
||||||
|
val loggedInTracker: List<Tracker> = emptyList(),
|
||||||
) : State {
|
) : State {
|
||||||
val processedChapters by lazy {
|
val processedChapters by lazy {
|
||||||
chapters.applyFilters(manga).toList()
|
chapters.applyFilters(manga).toList()
|
||||||
|
|
|
@ -239,7 +239,7 @@ data class TrackInfoDialogHomeScreen(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Track>.mapToTrackItem(): List<TrackItem> {
|
private fun List<Track>.mapToTrackItem(): List<TrackItem> {
|
||||||
val loggedInTrackers = Injekt.get<TrackerManager>().trackers.filter { it.isLoggedIn }
|
val loggedInTrackers = Injekt.get<TrackerManager>().loggedInTrackers()
|
||||||
val source = Injekt.get<SourceManager>().getOrStub(sourceId)
|
val source = Injekt.get<SourceManager>().getOrStub(sourceId)
|
||||||
return loggedInTrackers
|
return loggedInTrackers
|
||||||
// Map to TrackItem
|
// Map to TrackItem
|
||||||
|
|
|
@ -36,7 +36,7 @@ class StatsScreenModel(
|
||||||
private val trackerManager: TrackerManager = Injekt.get(),
|
private val trackerManager: TrackerManager = Injekt.get(),
|
||||||
) : StateScreenModel<StatsScreenState>(StatsScreenState.Loading) {
|
) : StateScreenModel<StatsScreenState>(StatsScreenState.Loading) {
|
||||||
|
|
||||||
private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn } }
|
private val loggedInTrackers by lazy { trackerManager.loggedInTrackers() }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
screenModelScope.launchIO {
|
screenModelScope.launchIO {
|
||||||
|
|
|
@ -7,6 +7,8 @@ import eu.kanade.tachiyomi.data.track.Tracker
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import tachiyomi.domain.track.model.Track
|
import tachiyomi.domain.track.model.Track
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
|
@ -16,6 +18,7 @@ data class DummyTracker(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val supportsReadingDates: Boolean = false,
|
override val supportsReadingDates: Boolean = false,
|
||||||
override val isLoggedIn: Boolean = false,
|
override val isLoggedIn: Boolean = false,
|
||||||
|
override val isLoggedInFlow: Flow<Boolean> = flowOf(false),
|
||||||
val valLogoColor: Int = Color.rgb(18, 25, 35),
|
val valLogoColor: Int = Color.rgb(18, 25, 35),
|
||||||
val valLogo: Int = R.drawable.ic_tracker_anilist,
|
val valLogo: Int = R.drawable.ic_tracker_anilist,
|
||||||
val valStatuses: List<Long> = (1L..6L).toList(),
|
val valStatuses: List<Long> = (1L..6L).toList(),
|
||||||
|
|
Loading…
Reference in a new issue