Refactor some tracking-related logic
(cherry picked from commit dde2f42138082f2d71552d573adbe89015cc7ff4) # Conflicts: # app/src/main/java/eu/kanade/domain/track/interactor/TrackChapter.kt # app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
This commit is contained in:
parent
270ff9064a
commit
402014adb4
@ -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(), get()) }
|
addFactory { GetTracksPerManga(get(), get()) }
|
||||||
addFactory { GetTracks(get()) }
|
addFactory { GetTracks(get()) }
|
||||||
@ -125,7 +127,7 @@ class DomainModule : InjektModule {
|
|||||||
addFactory { SetReadStatus(get(), get(), get(), get(), get()) }
|
addFactory { SetReadStatus(get(), 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()) }
|
||||||
|
@ -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() }
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,14 +25,15 @@ 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 /* SY --> */ && ((service.id == TrackManager.MDLIST && track.status != FollowStatus.UNFOLLOWED.int.toLong()) || service.id != TrackManager.MDLIST)/* SY <-- */) {
|
if (service == null || !service.isLoggedIn || chapterNumber <= track.lastChapterRead /* SY --> */ || (service.id == TrackManager.MDLIST && track.status == FollowStatus.UNFOLLOWED.int.toLong())/* SY <-- */) {
|
||||||
val updatedTrack = track.copy(lastChapterRead = chapterNumber)
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
|
||||||
|
val updatedTrack = track.copy(lastChapterRead = chapterNumber)
|
||||||
async {
|
async {
|
||||||
runCatching {
|
runCatching {
|
||||||
try {
|
try {
|
||||||
@ -45,13 +46,10 @@ class TrackChapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.awaitAll()
|
.awaitAll()
|
||||||
.mapNotNull { it.exceptionOrNull() }
|
.mapNotNull { it.exceptionOrNull() }
|
||||||
.forEach { logcat(LogPriority.INFO, it) }
|
.forEach { logcat(LogPriority.WARN, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -15,19 +15,17 @@ 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.interactor.RefreshTracks
|
||||||
import eu.kanade.domain.track.model.toDbTrack
|
import eu.kanade.domain.track.model.toDbTrack
|
||||||
import eu.kanade.domain.track.model.toDomainTrack
|
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.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackStatus
|
import eu.kanade.tachiyomi.data.track.TrackStatus
|
||||||
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
|
||||||
@ -54,7 +52,6 @@ import kotlinx.coroutines.coroutineScope
|
|||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
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
|
||||||
@ -64,7 +61,6 @@ import tachiyomi.core.util.system.logcat
|
|||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
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
|
||||||
@ -109,17 +105,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()
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
@ -127,6 +119,9 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
private val insertFlatMetadata: InsertFlatMetadata = Injekt.get()
|
private val insertFlatMetadata: InsertFlatMetadata = Injekt.get()
|
||||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get()
|
private val networkToLocalManga: NetworkToLocalManga = Injekt.get()
|
||||||
private val getMergedMangaForDownloading: GetMergedMangaForDownloading = Injekt.get()
|
private val getMergedMangaForDownloading: GetMergedMangaForDownloading = Injekt.get()
|
||||||
|
private val getTracks: GetTracks = Injekt.get()
|
||||||
|
private val insertTrack: InsertTrack = Injekt.get()
|
||||||
|
private val mdList = Injekt.get<TrackManager>().mdList
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
private val notifier = LibraryUpdateNotifier(context)
|
private val notifier = LibraryUpdateNotifier(context)
|
||||||
@ -303,7 +298,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
val hasDownloads = AtomicBoolean(false)
|
val hasDownloads = AtomicBoolean(false)
|
||||||
val restrictions = libraryPreferences.autoUpdateMangaRestrictions().get()
|
val restrictions = libraryPreferences.autoUpdateMangaRestrictions().get()
|
||||||
// SY -->
|
// SY -->
|
||||||
val mdlistLogged = trackManager.services.any { it.isLogged && it.id == TrackManager.MDLIST }
|
val mdlistLogged = mdList.isLoggedIn
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
val fetchWindow = setFetchInterval.getWindow(ZonedDateTime.now())
|
val fetchWindow = setFetchInterval.getWindow(ZonedDateTime.now())
|
||||||
@ -323,8 +318,8 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
try {
|
try {
|
||||||
val tracks = getTracks.await(manga.id)
|
val tracks = getTracks.await(manga.id)
|
||||||
if (tracks.isEmpty() || tracks.none { it.syncId == TrackManager.MDLIST }) {
|
if (tracks.isEmpty() || tracks.none { it.syncId == TrackManager.MDLIST }) {
|
||||||
val track = trackManager.mdList.createInitialTracker(manga)
|
val track = mdList.createInitialTracker(manga)
|
||||||
insertTrack.await(trackManager.mdList.refresh(track).toDomainTrack(false)!!)
|
insertTrack.await(mdList.refresh(track).toDomainTrack(false)!!)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (e is CancellationException) throw e
|
if (e is CancellationException) throw e
|
||||||
@ -393,8 +388,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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,49 +528,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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
/**
|
/**
|
||||||
* filter all follows from Mangadex and only add reading or rereading manga to library
|
* filter all follows from Mangadex and only add reading or rereading manga to library
|
||||||
@ -631,7 +595,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
val listManga = getFavorites.await().filter { it.source in mangaDexSourceIds }
|
val listManga = getFavorites.await().filter { it.source in mangaDexSourceIds }
|
||||||
|
|
||||||
// filter all follows from Mangadex and only add reading or rereading manga to library
|
// filter all follows from Mangadex and only add reading or rereading manga to library
|
||||||
if (trackManager.mdList.isLogged) {
|
if (mdList.isLoggedIn) {
|
||||||
listManga.forEach { manga ->
|
listManga.forEach { manga ->
|
||||||
ensureActive()
|
ensureActive()
|
||||||
|
|
||||||
@ -643,13 +607,13 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
|
|
||||||
// find the mdlist entry if its unfollowed the follow it
|
// find the mdlist entry if its unfollowed the follow it
|
||||||
var tracker = dbTracks.firstOrNull { it.syncId == TrackManager.MDLIST }
|
var tracker = dbTracks.firstOrNull { it.syncId == TrackManager.MDLIST }
|
||||||
?: trackManager.mdList.createInitialTracker(manga).toDomainTrack(idRequired = false)
|
?: mdList.createInitialTracker(manga).toDomainTrack(idRequired = false)
|
||||||
|
|
||||||
if (tracker?.status == FollowStatus.UNFOLLOWED.int.toLong()) {
|
if (tracker?.status == FollowStatus.UNFOLLOWED.int.toLong()) {
|
||||||
tracker = tracker.copy(
|
tracker = tracker.copy(
|
||||||
status = FollowStatus.READING.int.toLong(),
|
status = FollowStatus.READING.int.toLong(),
|
||||||
)
|
)
|
||||||
val updatedTrack = trackManager.mdList.update(tracker.toDbTrack())
|
val updatedTrack = mdList.update(tracker.toDbTrack())
|
||||||
insertTrack.await(updatedTrack.toDomainTrack(false)!!)
|
insertTrack.await(updatedTrack.toDomainTrack(false)!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,5 +46,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 }
|
||||||
}
|
}
|
||||||
|
@ -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) }
|
||||||
|
@ -168,7 +168,7 @@ class MdList(id: Long) : TrackService(id) {
|
|||||||
trackPreferences.trackToken(this).delete()
|
trackPreferences.trackToken(this).delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isLogged: Boolean
|
override val isLoggedIn: Boolean
|
||||||
get() = trackPreferences.trackToken(this).get().isNotEmpty()
|
get() = trackPreferences.trackToken(this).get().isNotEmpty()
|
||||||
|
|
||||||
class MangaDexNotFoundException : Exception("Mangadex not enabled")
|
class MangaDexNotFoundException : Exception("Mangadex not enabled")
|
||||||
|
@ -229,7 +229,7 @@ class MangaDex(delegate: HttpSource, val context: Context) :
|
|||||||
override val twoFactorAuth = LoginSource.AuthSupport.NOT_SUPPORTED
|
override val twoFactorAuth = LoginSource.AuthSupport.NOT_SUPPORTED
|
||||||
|
|
||||||
override fun isLogged(): Boolean {
|
override fun isLogged(): Boolean {
|
||||||
return mdList.isLogged
|
return mdList.isLoggedIn
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUsername(): String {
|
override fun getUsername(): String {
|
||||||
|
@ -66,7 +66,6 @@ import tachiyomi.domain.UnsortedPreferences
|
|||||||
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
|
||||||
@ -104,7 +103,6 @@ open 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(),
|
||||||
@ -123,7 +121,7 @@ open class BrowseSourceScreenModel(
|
|||||||
// SY <--
|
// SY <--
|
||||||
) : 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)
|
||||||
|
|
||||||
@ -402,8 +400,7 @@ open 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" }
|
||||||
|
@ -556,7 +556,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() }
|
||||||
|
@ -28,7 +28,7 @@ class LibrarySettingsScreenModel(
|
|||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
|
|
||||||
val trackServices
|
val trackServices
|
||||||
get() = trackManager.services.filter { it.isLogged }
|
get() = trackManager.services.filter { it.isLoggedIn }
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
val grouping by libraryPreferences.groupLibraryBy().asState(coroutineScope)
|
val grouping by libraryPreferences.groupLibraryBy().asState(coroutineScope)
|
||||||
|
@ -169,7 +169,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
|
||||||
|
@ -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
|
||||||
|
@ -43,7 +43,7 @@ class StatsScreenModel(
|
|||||||
// SY <--
|
// SY <--
|
||||||
) : 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 } }
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
private val _allRead = MutableStateFlow(false)
|
private val _allRead = MutableStateFlow(false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user