Refactor some tracking-related logic

This commit is contained in:
arkon 2023-08-26 18:30:17 -04:00
parent 6922792ad1
commit dde2f42138
17 changed files with 96 additions and 96 deletions

View file

@ -16,6 +16,7 @@ import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.domain.source.interactor.ToggleLanguage import eu.kanade.domain.source.interactor.ToggleLanguage
import eu.kanade.domain.source.interactor.ToggleSource import eu.kanade.domain.source.interactor.ToggleSource
import eu.kanade.domain.source.interactor.ToggleSourcePin import eu.kanade.domain.source.interactor.ToggleSourcePin
import eu.kanade.domain.track.interactor.RefreshTracks
import eu.kanade.domain.track.interactor.TrackChapter import eu.kanade.domain.track.interactor.TrackChapter
import tachiyomi.data.category.CategoryRepositoryImpl import tachiyomi.data.category.CategoryRepositoryImpl
import tachiyomi.data.chapter.ChapterRepositoryImpl import tachiyomi.data.chapter.ChapterRepositoryImpl
@ -113,6 +114,7 @@ class DomainModule : InjektModule {
addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) } addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) }
addFactory { TrackChapter(get(), get(), get(), get()) } addFactory { TrackChapter(get(), get(), get(), get()) }
addFactory { RefreshTracks(get(), get(), get(), get()) }
addFactory { DeleteTrack(get()) } addFactory { DeleteTrack(get()) }
addFactory { GetTracksPerManga(get()) } addFactory { GetTracksPerManga(get()) }
addFactory { GetTracks(get()) } addFactory { GetTracks(get()) }
@ -125,7 +127,7 @@ class DomainModule : InjektModule {
addFactory { SetReadStatus(get(), get(), get(), get()) } addFactory { SetReadStatus(get(), get(), get(), get()) }
addFactory { ShouldUpdateDbChapter() } addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get()) } addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get()) }
addFactory { SyncChaptersWithTrackServiceTwoWay(get(), get()) } addFactory { SyncChaptersWithTrackServiceTwoWay(get(), get(), get()) }
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) } addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
addFactory { GetHistory(get()) } addFactory { GetHistory(get()) }

View file

@ -1,11 +1,12 @@
package eu.kanade.domain.chapter.interactor package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.chapter.interactor.GetChapterByMangaId
import tachiyomi.domain.chapter.interactor.UpdateChapter import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.toChapterUpdate import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.track.interactor.InsertTrack import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.domain.track.model.Track import tachiyomi.domain.track.model.Track
@ -13,14 +14,22 @@ import tachiyomi.domain.track.model.Track
class SyncChaptersWithTrackServiceTwoWay( class SyncChaptersWithTrackServiceTwoWay(
private val updateChapter: UpdateChapter, private val updateChapter: UpdateChapter,
private val insertTrack: InsertTrack, private val insertTrack: InsertTrack,
private val getChapterByMangaId: GetChapterByMangaId,
) { ) {
suspend fun await( suspend fun await(
chapters: List<Chapter>, mangaId: Long,
remoteTrack: Track, remoteTrack: Track,
service: TrackService, service: TrackService,
) { ) {
val sortedChapters = chapters.sortedBy { it.chapterNumber } if (service !is EnhancedTrackService) {
return
}
val sortedChapters = getChapterByMangaId.await(mangaId)
.sortedBy { it.chapterNumber }
.filter { it.isRecognizedNumber }
val chapterUpdates = sortedChapters val chapterUpdates = sortedChapters
.filter { chapter -> chapter.chapterNumber <= remoteTrack.lastChapterRead && !chapter.read } .filter { chapter -> chapter.chapterNumber <= remoteTrack.lastChapterRead && !chapter.read }
.map { it.copy(read = true).toChapterUpdate() } .map { it.copy(read = true).toChapterUpdate() }

View file

@ -0,0 +1,43 @@
package eu.kanade.domain.track.interactor
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.track.TrackManager
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.supervisorScope
import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
class RefreshTracks(
private val getTracks: GetTracks,
private val trackManager: TrackManager,
private val insertTrack: InsertTrack,
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay,
) {
suspend fun await(mangaId: Long) {
supervisorScope {
getTracks.await(mangaId)
.map { track ->
async {
val service = trackManager.getService(track.syncId)
if (service != null && service.isLoggedIn) {
try {
val updatedTrack = service.refresh(track.toDbTrack())
insertTrack.await(updatedTrack.toDomainTrack()!!)
syncChaptersWithTrackServiceTwoWay.await(mangaId, track, service)
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
}
}
}
}
.awaitAll()
}
}
}

View file

@ -24,33 +24,31 @@ class TrackChapter(
suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) = coroutineScope { suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) = coroutineScope {
launchNonCancellable { launchNonCancellable {
val tracks = getTracks.await(mangaId) val tracks = getTracks.await(mangaId)
if (tracks.isEmpty()) return@launchNonCancellable if (tracks.isEmpty()) return@launchNonCancellable
tracks.mapNotNull { track -> tracks.mapNotNull { track ->
val service = trackManager.getService(track.syncId) val service = trackManager.getService(track.syncId)
if (service != null && service.isLogged && chapterNumber > track.lastChapterRead) { if (service == null || !service.isLoggedIn || chapterNumber <= track.lastChapterRead) {
val updatedTrack = track.copy(lastChapterRead = chapterNumber) return@mapNotNull null
}
async { val updatedTrack = track.copy(lastChapterRead = chapterNumber)
runCatching { async {
try { runCatching {
service.update(updatedTrack.toDbTrack(), true) try {
insertTrack.await(updatedTrack) service.update(updatedTrack.toDbTrack(), true)
} catch (e: Exception) { insertTrack.await(updatedTrack)
delayedTrackingStore.addItem(updatedTrack) } catch (e: Exception) {
DelayedTrackingUpdateJob.setupTask(context) delayedTrackingStore.addItem(updatedTrack)
throw e DelayedTrackingUpdateJob.setupTask(context)
} throw e
} }
} }
} else {
null
} }
} }
.awaitAll() .awaitAll()
.mapNotNull { it.exceptionOrNull() } .mapNotNull { it.exceptionOrNull() }
.forEach { logcat(LogPriority.INFO, it) } .forEach { logcat(LogPriority.WARN, it) }
} }
} }
} }

View file

@ -48,7 +48,7 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
.forEach { track -> .forEach { track ->
try { try {
val service = trackManager.getService(track.syncId) val service = trackManager.getService(track.syncId)
if (service != null && service.isLogged) { if (service != null && service.isLoggedIn) {
logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" } logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" }
service.update(track.toDbTrack(), true) service.update(track.toDbTrack(), true)
insertTrack.await(track) insertTrack.await(track)

View file

@ -164,7 +164,7 @@ internal fun PreferenceItem(
TrackingPreferenceWidget( TrackingPreferenceWidget(
service = this, service = this,
checked = uName.isNotEmpty(), checked = uName.isNotEmpty(),
onClick = { if (isLogged) item.logout() else item.login() }, onClick = { if (isLoggedIn) item.logout() else item.login() },
) )
} }
} }

View file

@ -135,7 +135,7 @@ object Migrations {
// Force MAL log out due to login flow change // Force MAL log out due to login flow change
// v52: switched from scraping to WebView // v52: switched from scraping to WebView
// v53: switched from WebView to OAuth // v53: switched from WebView to OAuth
if (trackManager.myAnimeList.isLogged) { if (trackManager.myAnimeList.isLoggedIn) {
trackManager.myAnimeList.logout() trackManager.myAnimeList.logout()
context.toast(R.string.myanimelist_relogin) context.toast(R.string.myanimelist_relogin)
} }

View file

@ -51,7 +51,7 @@ class BackupFileValidator(
.distinct() .distinct()
val missingTrackers = trackers val missingTrackers = trackers
.mapNotNull { trackManager.getService(it.toLong()) } .mapNotNull { trackManager.getService(it.toLong()) }
.filter { !it.isLogged } .filter { !it.isLoggedIn }
.map { context.getString(it.nameRes()) } .map { context.getString(it.nameRes()) }
.sorted() .sorted()

View file

@ -15,19 +15,14 @@ import androidx.work.WorkQuery
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
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.copyFrom import eu.kanade.domain.manga.model.copyFrom
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.interactor.RefreshTracks
import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.source.UnmeteredSource import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy import eu.kanade.tachiyomi.source.model.UpdateStrategy
@ -44,7 +39,6 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.sync.withPermit
import logcat.LogPriority import logcat.LogPriority
@ -53,7 +47,6 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.chapter.interactor.GetChapterByMangaId
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.NoChaptersException import tachiyomi.domain.chapter.model.NoChaptersException
import tachiyomi.domain.download.service.DownloadPreferences import tachiyomi.domain.download.service.DownloadPreferences
@ -73,8 +66,6 @@ import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.toMangaUpdate import tachiyomi.domain.manga.model.toMangaUpdate
import tachiyomi.domain.source.model.SourceNotInstalledException import tachiyomi.domain.source.model.SourceNotInstalledException
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -92,17 +83,13 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
private val downloadPreferences: DownloadPreferences = Injekt.get() private val downloadPreferences: DownloadPreferences = Injekt.get()
private val libraryPreferences: LibraryPreferences = Injekt.get() private val libraryPreferences: LibraryPreferences = Injekt.get()
private val downloadManager: DownloadManager = Injekt.get() private val downloadManager: DownloadManager = Injekt.get()
private val trackManager: TrackManager = Injekt.get()
private val coverCache: CoverCache = Injekt.get() private val coverCache: CoverCache = Injekt.get()
private val getLibraryManga: GetLibraryManga = Injekt.get() private val getLibraryManga: GetLibraryManga = Injekt.get()
private val getManga: GetManga = Injekt.get() private val getManga: GetManga = Injekt.get()
private val updateManga: UpdateManga = Injekt.get() private val updateManga: UpdateManga = Injekt.get()
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get()
private val getCategories: GetCategories = Injekt.get() private val getCategories: GetCategories = Injekt.get()
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get() private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get()
private val getTracks: GetTracks = Injekt.get() private val refreshTracks: RefreshTracks = Injekt.get()
private val insertTrack: InsertTrack = Injekt.get()
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get()
private val setFetchInterval: SetFetchInterval = Injekt.get() private val setFetchInterval: SetFetchInterval = Injekt.get()
private val notifier = LibraryUpdateNotifier(context) private val notifier = LibraryUpdateNotifier(context)
@ -296,8 +283,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
} }
if (libraryPreferences.autoUpdateTrackers().get()) { if (libraryPreferences.autoUpdateTrackers().get()) {
val loggedServices = trackManager.services.filter { it.isLogged } refreshTracks.await(manga.id)
updateTrackings(manga, loggedServices)
} }
} }
} }
@ -417,49 +403,19 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
private suspend fun updateTrackings() { private suspend fun updateTrackings() {
coroutineScope { coroutineScope {
var progressCount = 0 var progressCount = 0
val loggedServices = trackManager.services.filter { it.isLogged }
mangaToUpdate.forEach { libraryManga -> mangaToUpdate.forEach { libraryManga ->
val manga = libraryManga.manga
ensureActive() ensureActive()
val manga = libraryManga.manga
notifier.showProgressNotification(listOf(manga), progressCount++, mangaToUpdate.size) notifier.showProgressNotification(listOf(manga), progressCount++, mangaToUpdate.size)
refreshTracks.await(manga.id)
// Update the tracking details.
updateTrackings(manga, loggedServices)
} }
notifier.cancelProgressNotification() notifier.cancelProgressNotification()
} }
} }
private suspend fun updateTrackings(manga: Manga, loggedServices: List<TrackService>) {
getTracks.await(manga.id)
.map { track ->
supervisorScope {
async {
val service = trackManager.getService(track.syncId)
if (service != null && service in loggedServices) {
try {
val updatedTrack = service.refresh(track.toDbTrack())
insertTrack.await(updatedTrack.toDomainTrack()!!)
if (service is EnhancedTrackService) {
val chapters = getChapterByMangaId.await(manga.id)
syncChaptersWithTrackServiceTwoWay.await(chapters, track, service)
}
} catch (e: Throwable) {
// Ignore errors and continue
logcat(LogPriority.ERROR, e)
}
}
}
}
}
.awaitAll()
}
private suspend fun withUpdateNotification( private suspend fun withUpdateNotification(
updatingManga: CopyOnWriteArrayList<Manga>, updatingManga: CopyOnWriteArrayList<Manga>,
completed: AtomicInteger, completed: AtomicInteger,

View file

@ -39,5 +39,5 @@ class TrackManager(context: Context) {
fun getService(id: Long) = services.find { it.id == id } fun getService(id: Long) = services.find { it.id == id }
fun hasLoggedServices() = services.any { it.isLogged } fun hasLoggedServices() = services.any { it.isLoggedIn }
} }

View file

@ -33,6 +33,7 @@ abstract class TrackService(val id: Long) {
val trackPreferences: TrackPreferences by injectLazy() val trackPreferences: TrackPreferences by injectLazy()
val networkService: NetworkHelper by injectLazy() val networkService: NetworkHelper by injectLazy()
private val insertTrack: InsertTrack by injectLazy() private val insertTrack: InsertTrack by injectLazy()
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay by injectLazy()
open val client: OkHttpClient open val client: OkHttpClient
get() = networkService.client get() = networkService.client
@ -89,7 +90,7 @@ abstract class TrackService(val id: Long) {
trackPreferences.setTrackCredentials(this, "", "") trackPreferences.setTrackCredentials(this, "", "")
} }
open val isLogged: Boolean open val isLoggedIn: Boolean
get() = getUsername().isNotEmpty() && get() = getUsername().isNotEmpty() &&
getPassword().isNotEmpty() getPassword().isNotEmpty()
@ -101,6 +102,7 @@ abstract class TrackService(val id: Long) {
trackPreferences.setTrackCredentials(this, username, password) trackPreferences.setTrackCredentials(this, username, password)
} }
// TODO: move this to an interactor, and update all trackers based on common data
suspend fun registerTracking(item: Track, mangaId: Long) { suspend fun registerTracking(item: Track, mangaId: Long) {
item.manga_id = mangaId item.manga_id = mangaId
try { try {
@ -113,6 +115,7 @@ abstract class TrackService(val id: Long) {
insertTrack.await(track) insertTrack.await(track)
// TODO: merge into SyncChaptersWithTrackServiceTwoWay?
// Update chapter progress if newer chapters marked read locally // Update chapter progress if newer chapters marked read locally
if (hasReadChapters) { if (hasReadChapters) {
val latestLocalReadChapterNumber = allChapters val latestLocalReadChapterNumber = allChapters
@ -144,9 +147,7 @@ abstract class TrackService(val id: Long) {
} }
} }
if (this is EnhancedTrackService) { syncChaptersWithTrackServiceTwoWay.await(mangaId, track, this@TrackService)
Injekt.get<SyncChaptersWithTrackServiceTwoWay>().await(allChapters, track, this@TrackService)
}
} }
} catch (e: Throwable) { } catch (e: Throwable) {
withUIContext { Injekt.get<Application>().toast(e.message) } withUIContext { Injekt.get<Application>().toast(e.message) }

View file

@ -45,7 +45,6 @@ import tachiyomi.core.util.system.logcat
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.chapter.interactor.GetChapterByMangaId
import tachiyomi.domain.chapter.interactor.SetMangaDefaultChapterFlags import tachiyomi.domain.chapter.interactor.SetMangaDefaultChapterFlags
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
@ -72,7 +71,6 @@ class BrowseSourceScreenModel(
private val getRemoteManga: GetRemoteManga = Injekt.get(), private val getRemoteManga: GetRemoteManga = Injekt.get(),
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(), private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
private val getCategories: GetCategories = Injekt.get(), private val getCategories: GetCategories = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
private val setMangaCategories: SetMangaCategories = Injekt.get(), private val setMangaCategories: SetMangaCategories = Injekt.get(),
private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(), private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(),
private val getManga: GetManga = Injekt.get(), private val getManga: GetManga = Injekt.get(),
@ -82,7 +80,7 @@ class BrowseSourceScreenModel(
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get(), private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get(),
) : StateScreenModel<BrowseSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) { ) : StateScreenModel<BrowseSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) {
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } } private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLoggedIn } }
var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope) var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope)
@ -299,8 +297,7 @@ class BrowseSourceScreenModel(
(service as TrackService).bind(track) (service as TrackService).bind(track)
insertTrack.await(track.toDomainTrack()!!) insertTrack.await(track.toDomainTrack()!!)
val chapters = getChapterByMangaId.await(manga.id) syncChaptersWithTrackServiceTwoWay.await(manga.id, track.toDomainTrack()!!, service)
syncChaptersWithTrackServiceTwoWay.await(chapters, track.toDomainTrack()!!, service)
} }
} catch (e: Exception) { } catch (e: Exception) {
logcat(LogPriority.WARN, e) { "Could not match manga: ${manga.title} with service $service" } logcat(LogPriority.WARN, e) { "Could not match manga: ${manga.title} with service $service" }

View file

@ -366,7 +366,7 @@ 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 loggedServices = trackManager.services.filter { it.isLogged } val loggedServices = trackManager.services.filter { it.isLoggedIn }
return if (loggedServices.isNotEmpty()) { return if (loggedServices.isNotEmpty()) {
val prefFlows = loggedServices val prefFlows = loggedServices
.map { libraryPreferences.filterTracking(it.id.toInt()).changes() } .map { libraryPreferences.filterTracking(it.id.toInt()).changes() }

View file

@ -26,7 +26,7 @@ class LibrarySettingsScreenModel(
) : ScreenModel { ) : ScreenModel {
val trackServices val trackServices
get() = trackManager.services.filter { it.isLogged } get() = trackManager.services.filter { it.isLoggedIn }
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) { fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
preference(libraryPreferences).getAndSet { preference(libraryPreferences).getAndSet {

View file

@ -105,7 +105,7 @@ class MangaScreenModel(
private val successState: State.Success? private val successState: State.Success?
get() = state.value as? State.Success get() = state.value as? State.Success
private val loggedServices by lazy { trackManager.services.filter { it.isLogged } } private val loggedServices by lazy { trackManager.services.filter { it.isLoggedIn } }
val manga: Manga? val manga: Manga?
get() = successState?.manga get() = successState?.manga

View file

@ -71,7 +71,6 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.lang.withUIContext import tachiyomi.core.util.lang.withUIContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.util.system.logcat
import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.interactor.GetMangaWithChapters
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.track.interactor.DeleteTrack import tachiyomi.domain.track.interactor.DeleteTrack
import tachiyomi.domain.track.interactor.GetTracks import tachiyomi.domain.track.interactor.GetTracks
@ -218,8 +217,7 @@ data class TrackInfoDialogHomeScreen(
private suspend fun refreshTrackers() { private suspend fun refreshTrackers() {
val insertTrack = Injekt.get<InsertTrack>() val insertTrack = Injekt.get<InsertTrack>()
val getMangaWithChapters = Injekt.get<GetMangaWithChapters>() val syncChaptersWithTrackServiceTwoWay = Injekt.get<SyncChaptersWithTrackServiceTwoWay>()
val syncTwoWayService = Injekt.get<SyncChaptersWithTrackServiceTwoWay>()
val context = Injekt.get<Application>() val context = Injekt.get<Application>()
try { try {
@ -229,11 +227,7 @@ data class TrackInfoDialogHomeScreen(
val track = trackItem.track ?: continue val track = trackItem.track ?: continue
val domainTrack = trackItem.service.refresh(track.toDbTrack()).toDomainTrack() ?: continue val domainTrack = trackItem.service.refresh(track.toDbTrack()).toDomainTrack() ?: continue
insertTrack.await(domainTrack) insertTrack.await(domainTrack)
syncChaptersWithTrackServiceTwoWay.await(mangaId, domainTrack, trackItem.service)
if (trackItem.service is EnhancedTrackService) {
val allChapters = getMangaWithChapters.awaitChapters(mangaId)
syncTwoWayService.await(allChapters, domainTrack, trackItem.service)
}
} catch (e: Exception) { } catch (e: Exception) {
logcat( logcat(
LogPriority.ERROR, LogPriority.ERROR,
@ -257,7 +251,7 @@ data class TrackInfoDialogHomeScreen(
} }
private fun List<Track>.mapToTrackItem(): List<TrackItem> { private fun List<Track>.mapToTrackItem(): List<TrackItem> {
val loggedServices = Injekt.get<TrackManager>().services.filter { it.isLogged } val loggedServices = Injekt.get<TrackManager>().services.filter { it.isLoggedIn }
val source = Injekt.get<SourceManager>().getOrStub(sourceId) val source = Injekt.get<SourceManager>().getOrStub(sourceId)
return loggedServices return loggedServices
// Map to TrackItem // Map to TrackItem

View file

@ -36,7 +36,7 @@ class StatsScreenModel(
private val trackManager: TrackManager = Injekt.get(), private val trackManager: TrackManager = Injekt.get(),
) : StateScreenModel<StatsScreenState>(StatsScreenState.Loading) { ) : StateScreenModel<StatsScreenState>(StatsScreenState.Loading) {
private val loggedServices by lazy { trackManager.services.fastFilter { it.isLogged } } private val loggedServices by lazy { trackManager.services.fastFilter { it.isLoggedIn } }
init { init {
coroutineScope.launchIO { coroutineScope.launchIO {